IOC控制反转–.net framework
分层架构:
一、传统依赖倒置实现
- 传统工艺:会有依赖,上端全部展示细节
BaseBll baseBll = new BaseBll();
baseBll.DoSomething();
- 依赖于抽象:左边依赖倒置,面向抽象
实现类继承接口,实现类实现接口的方法
左边抽象,右边实现类
BaseBll.cs (ZhaoxiFramework.BLL)
public class BaseBll: IBaseBll
{
public void DoSomething()
{
Console.WriteLine("{0} Do Something", this.GetType().Name);
}
}
调用
IBaseBll baseBll = new BaseBll();
baseBll.DoSomething();
- 第三方工厂
IPhone.cs(ZhaoxiFramework.Interface)
public interface IPhone
{
void Call();
IMicrophone iMicrophone { get; set; }
IHeadphone iHeadphone { get; set; }
IPower iPower { get; set; }
}
ObjectFactory.cs(ZhaoxiFramework.IOC.Project)
public static IPhone CreatePhone(IBaseBll iBLL)
{
string classModule = ConfigurationManager.AppSettings["iPhoneType"];
Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
Type type = assemly.GetType(classModule.Split(',')[0]);
return (IPhone)Activator.CreateInstance(type, new object[] { iBLL });
}
AndroidPhone.cs(ZhaoxiFramework.Service)
public class AndroidPhone : IPhone
{
public IMicrophone iMicrophone { get; set; }
public IHeadphone iHeadphone { get; set; }
public IPower iPower { get; set; }
public AndroidPhone(IBaseBll baseBll)
{
Console.WriteLine("{0}构造函数", this.GetType().Name);
}
}
App.config 文件(ZhaoxiFramework.IOC.Project)
<appSettings>
<add key="iPhoneType" value="ZhaoxiFramework.Service.AndroidPhone,ZhaoxiFramework.Service" />
</appSettings>
调用(ZhaoxiFramework.IOC.Project)
IBaseBll baseBll = new BaseBll();
IPhone phone = ObjectFactory.CreatePhone(baseBll);
=> 那什么是IOC?
传统工艺是使用new关键词进行对象的创建,依赖于细节;
但是IOC是把对象交个一个第三方的容器来创建,其实本质就是一个工厂 + 配置文件;
上述所讲解到的 第三种方式:第三方工厂,通过工厂来创建对象的时候,如果有参数的情况下,需要把参数的实例事先创建好 new BaseBll()
,然后再传递过来 ObjectFactory.CreatePhone(baseBll)
;
**问题:**那么在创建对象的时候,如果依赖的太多呢?难道每一个以来我们都写一个工厂来创建吗?(以下--->
代表依赖关系,前面一项依赖于后一项)
比如,ApplePhone类 —> Headphone —> Microphone —> Power …
期望: 如果说,对象A —> 对象B —> 对象C;在创建对象A的时候,能够自动的把依赖的对象创建好,传递过来,直接得到想要的对象,那岂不是很舒服。那什么方式能帮助完成这种理想情况呢?
答案: DI(依赖注入),经常和IOC放在一起使用;因为在使用IOC容器的时候,会很容易踩到坑(出现上述所说的多个依赖的关系),DI 这时候就能帮助弥补它。
=> IOC 和 DI 是什么关系?
IOC是一种对象的创建的实现(目标),而DI 是IOC 的一种实现方式
二、Unity 使用
第一步:Nuget 引入三个包,
Unity
、Unity.Abstractions
、Unity.Container
第二步:注册抽象和实现
2.1 通过IOC创建实例
有三种关系可以进行实现:1. 接口–实现类、2. 抽象类–子类、3. 普通类–子类
接口–实现类
//创建一个容器
IUnityContainer container = new UnityContainer();
//告诉容器---抽象和细节的关系
container.RegisterType<IBaseBll, BaseBll>();
//获取对象的实例
IBaseBll baseBll = container.Resolve<IBaseBll>(); //ZhaoxiFramework.BLL.BaseBll
抽象类–子类
ApplePad.cs(ZhaoxiFramework.Service)
public class ApplePad : AbstractPad
{
public override void Show()
{
Console.WriteLine($"This is {nameof(ApplePad)}");
}
}
AbstractPad.cs(ZhaoxiFramework.Interface)
public abstract class AbstractPad
{
public abstract void Show();
}
创建实例:
//创建一个容器
IUnityContainer container = new UnityContainer();
//告诉容器---抽象和细节的关系
container.RegisterType<AbstractPad, ApplePad>();
//获取对象的实例
AbstractPad abstractPad = container.Resolve<AbstractPad>(); //输出结果为:ZhaoxiFramework.Service.ApplePad
普通类–子类
IUnityContainer container = new UnityContainer();
container.RegisterType<ApplePad, ApplePadChild>();
AbstractPad applePadChild = container.Resolve<ApplePad>(); //输出结果为:ZhaoxiFramework.Service.ApplePadChild
2.2 有趣的继承关系
ApplePadChild.cs(ZhaoxiFramework.Service)
public class ApplePadChild : ApplePad
{
public override void Show()
{
base.Show();
Console.WriteLine($"This is {nameof(ApplePadChild)}");
}
}
创建实例1:
//创建一个容器
IUnityContainer container = new UnityContainer();
container.RegisterType<AbstractPad, ApplePad>();
AbstractPad abstractPad = container.Resolve<AbstractPad>(); //1.输出结果为:ZhaoxiFramework.Service.ApplePad
container.RegisterType<ApplePad, ApplePadChild>();
AbstractPad applePadChild = container.Resolve<ApplePad>(); //2.输出结果为:ZhaoxiFramework.Service.ApplePadChild
AbstractPad applePadChild1 = container.Resolve<AbstractPad>(); //3.输出结果为:ZhaoxiFramework.Service.ApplePadChild
注册完成之后,形成的链式如下:
AbstractPad
->ApplePad
->ApplePadChild
1.输出结果为 ApplePad,是因为
ApplePad
->ApplePadChild
的关系还未注册进行就开始被调用来创建实例了1.输出结果为 ApplePadChild,是因为 链式关系已经完整了,就返回的最底层的(最后的)类型
创建实例2:
//创建一个容器
IUnityContainer container = new UnityContainer();
container.RegisterType<ApplePad, ApplePadChild>();
AbstractPad applePadChild = container.Resolve<ApplePad>(); //输出结果为:ZhaoxiFramework.Service.ApplePadChild
container.RegisterType<AbstractPad, ApplePad>();
AbstractPad abstractPad = container.Resolve<AbstractPad>(); //输出结果为:ZhaoxiFramework.Service.ApplePadChild
因为
ApplePad, ApplePadChild
已经先注册了,所以在注册AbstractPad, ApplePad
之后再实例化的时候,期间就会有下面一个链式指向的过程:
AbstractPad
->ApplePad
->ApplePadChild