.NET 依赖注入
依赖注入 -> 1 : Setter注入
Setter 注入 是指在Client 类中,设置一个服务类接口类型的数据成员,并设置一个Set方法做为注入点,这个Set方法接收一个具体的服务类实例为参数,并将它赋给服务类接口类型的数据成员.
Code :
1 internal interface IServiceClass 2 { 3 string ServerInfo(); 4 } 5 6 internal class ServiceClassA : IServiceClass 7 { 8 public string ServerInfo() 9 { 10 return "My Is ServerClassA"; 11 } 12 } 13 14 internal class ServiceClassB : IServiceClass 15 { 16 public string ServerInfo() 17 { 18 return "My Is ServerClassB"; 19 } 20 } 21 // 1:Setter注入 22 internal class ClientClass 23 { 24 private IServiceClass _service; 25 public void Set_Service(IServiceClass service) 26 { 27 this._service = service; 28 } 29 public void ShowInfo() 30 { 31 Console.WriteLine(_service.ServerInfo()); 32 } 33 }
依赖注入 -> 2 : 构造注入
构造注入 : 在Client类中设置一个服务类接口类型的数据成员,并以构造函数为函数的注入点,这个构造函数接收一个具体的服务类实例为参数,并将它赋给服务类接口类型的数据成员
1 internal class ClientClass1 2 { 3 private IServiceClass _service; 4 public ClientClass1(IServiceClass service) 5 { 6 this._service = service; 7 } 8 public void ShowInfo() 9 { 10 Console.WriteLine(_service.ServerInfo()); 11 } 12 }
依赖注入 -> 3 : 依赖获取
在以上两个注入中,都是客户类被动接收所依赖的服务类,
那么依赖获取 : 是指在系统中提供一个获取点,客户类仍然依赖服务类的接口,当客户端类需要服务类时,从获取点主动取得指定的服务类,具体的服务类型由获取点的配置决定.
1 internal interface IButton 2 { 3 string ShowInfo(); 4 } 5 6 internal sealed class WindowButton : IButton 7 { 8 public string Description {get; private set;} 9 public WindowButton() 10 { 11 this.Description = "Window 风格"; 12 } 13 public string ShowInfo() 14 { 15 return this.Description; 16 } 17 } 18 19 internal sealed class MacButton : IButton 20 { 21 public string Description {get;private set;} 22 public MacButton() 23 { 24 this.Description = "Mac 风格"; 25 } 26 public string ShowInfo() 27 { 28 return this.Description; 29 } 30 } 31 32 internal interface IFactory 33 { 34 IButton MakeButton(); 35 } 36 37 internal sealed class WindowFactory : IFactory 38 { 39 public IButton MakeButton() 40 { 41 return new WindowButton(); 42 } 43 } 44 45 internal sealed class MacFactory : IFactory 46 { 47 public IButton MakeButton() 48 { 49 return new MacButton(); 50 } 51 } 52 53 internal static class FactoryContainer 54 { 55 public static IFactory factory {get; private set;} 56 static FactoryContainer() 57 { 58 if("Window") 59 { 60 factory = new WindowFactory(); 61 } 62 else if("Mac") 63 { 64 factory = new MacFactory(); 65 } 66 else 67 { 68 throw new Exception("Factory Init Error"); 69 } 70 } 71 }
扩展 1 --> 反射与依赖注入
反射与依赖注入
如果未来有新类添加进来则必须要修改代码,那么我们可以利用反射通过类的名字来实例化对象,可以将类的名字作为配置项,就可以实现不修改代码的情况下,加载未来才出现的类.
扩展 2 -- IOC Container 控制反转
IOC Container 控制反转
专门用于实现依赖注入功能的组件或框架,就是 IOC Container
IOC Container 分类 :
1、重量级IOC Container :是指一般用外部配置文件(XML),作为依赖源,并托管整个系统各个类的实例化的IOC Container。
这种 IOC Container 一般是承接了整个系统几乎所有多态性的依赖注入工作,并承接了所有服务类的实例化工作,而且这个实例化依赖于一个外部配置文件,这种 IOC Container 很像通过一个文件,定义整个系统多态结构,视野宏大。
2、轻量级IOC Container :是指一般不依赖于配置文件,而主要使用传参的 Setter 或 Construtor注入 这种 IOC Container叫做轻量级IOC Container, 这种框架很灵活,使用方便,但往往不稳定,而且依赖点都是程序中的字符串参数,所以不适合需要大规模替换和相对稳定的低活多态性,而对于高活多态性,比较好。
Unity 是一个典型的轻量级 IOC Container。