首页 > 代码库 > 依赖注入

依赖注入

问题:

  Open-Closed Principle原则讲的是:一个软件实体应当对扩展开放,对修改关闭。将变化隔离,使得变化部分发生变化时,不变部分不受影响。

为了做到这一点,要利用面向对象中的多态性,使用多态性后,客户类不再直接依赖服务类,而是依赖一个抽象的接口。这样,客户类就不能在类的内部直接实例化具体的服务类。但是客户类在运作中又客观需要具体的服务类提供服务,因为接口并不能提供实质性的服务。这样一来就产生了“客户类依赖接口,接口不能提供实质的服务” 和“客户类需要具体实质的服务类”的矛盾。

 

解决:

  依赖注入Dependency Injection。实现过程:由于客户类只能依赖服务的一个接口,而不是依赖具体服务类,所以客户类提供一个注入点。在程序运行过程中,客户类直接实例化具体的服务类实例,而是客户类的运行上下文环境或者专门组件 负责实例化服务类,然后通过客户类提供的注入点 将 实例化的服务类注入,从而确保客户类能正常运行。

 

                                         

 

Unity应用程序块是一个轻量级、可扩展的依赖注入容器,支持构造函数,属性和方法调用注入。

 

Unity应用程序块使用容器注册类型和映射的两种方法如下:

1、RegisterType  此方法用容器注册一个类型。在适当的时候,容器将构建一个指定的类型的实例。这可以通过类的特性或者调用Resolve方法时初始化依赖注入。

 构建的对象的生命周期与在方法参数中指定的生命周期一致。如果没有指定生命周期的值,将为类型注册一个暂时的生命周期,这意味着容器将为每一个对Resolve的调用创建一个新的实例。

2、RegisterInstance  此方法将一个指定的类型的已存在的实例 注册到 容器,并带有指定的生命周期。容器将在生命周期内返回已有的实例。 如果没有指定生命周期,实例将拥有容器控制的生命周期。

 

四种注册的实例介绍:

1、类型的配置容器注册

  作为RegisterType和Resolve方法的重载的一个示例,下面代码注册了一个用于接口ICustomerService的映射,指定容器将放回CustomerService类的实例。CustomerService实现了ICustomerService接口。

IUnityContainer myContainer =  new UnityContainer();myContainer.RegisterType<ICustomerService, CustomerService>();ICustomerService customerServiceInstance = myContainer.Resolve<ICustomerService>();

 

2、已有对象实例的配置容器注册
  作为RegisterType和Resolve方法的重载的一个示例,下面代码注册了实现了ICustomerService接口的CustomerService类的一个已有实例,然后获取次实例。

IUnityContainer myContainer =  new UnityContainer();CustomerService customer = new CustomerService();myContainer.RegisterType<ICustomerService>(customer);ICustomerService customerServiceInstance = myContainer.Resolve<ICustomerService>();

 

3、构造函数注入

  作为构造函数注入的一个示例,如果开发人员用Unity容器的Resolve方法实例化的类(该类有一个构造函数定义了一个或者多个对其他类的依赖),Unity容器将自动创建指定在构造函数参数中的依赖对象的实例。

例如,下列代码展示了依赖于 LoggingService 对象的 CustomerService 类。

public class CustomerService{ public CustomerService(LoggingService myServiceInstance) {  // work with the dependent instance  myServiceInstance.WriteToLog("SomeValue"); }}

在运行时,开发人员使用容器的 Resolve 方法创建了 CustomerService 类的一个实例,这导致了实例生成框架将具体类 LoggingService 的一个实例注入到 CustomerService 类中。

IUnityContainer uContainer = new UnityContainer();CustomerService myInstance = uContainer.Resolve<CustomerService>();

 

4、属性注入

  除了前面描述的构造函数注入以外,Unity应用程序块还支持属性和方法调用注入。下面代码示例了属性注入。ProductService类暴露了一个引用另一个名为SupplierData类的实例属性。要强制依赖对象的注入,开发人员必须下列代码一样使用Dependency特性装饰属性的声明。

public class ProductService{ private SupplierData supplier; [Dependency] public SupplierData SupplierDetails {  get { return supplier; }  set { supplier = value; } }}

 

依赖注入