代码改变世界

微软企业库4.1学习笔记(二十四)Unity依赖注入模块 简介

2010-05-01 10:04  Virus-BeautyCode  阅读(2935)  评论(3编辑  收藏  举报

  企业库的依赖注入模块Unity是一个轻量的、可扩展的依赖注入容器,支持构造函数注入、属性注入、方法调用注入。你可以用它创建企业库的对象,或者是自定义的对象。但是,Unity模块和企业库中的其他模块有很多的不同点:

  •   你可以在不安装企业库的情况下,直接使用Unity模块的依赖注入功能。
  •   Unity模块可以通过配置信息来准备容器,也可以在运行的时候在代码中动态创建依赖关系。
  •   Unity模块不依赖于企业库的核心库和企业库的配置系统,它用自己内置的方法读取配置信息,如果需要的话,也可以从企业库的配置文件中读取Unity的配置信息。

  

  Unity模块具有下面的优点:

  •   提供了简单的对象创建,尤其是对于有继承关系的对象和有依赖关系的对象,提供了简单的代码实现。
  •   支持抽象需求,允许开发者在运行的时候确定依赖关系,或者是在配置的时候指明依赖关系。
  •   增加了灵活性,通过在容器中延迟组件之间的配置。
  •   具有服务定位的能力,允许客户端存储和缓存容器。这在ASP.NET中相当有用,开发者可以将容器持久在ASP.NET的session或者是application中。

  下面将包括一些列的主题,你可以看看Unity是否适合你的应用需求。

  •  常用的解决方案。
  •   示例代码
  •   Unity的亮点
  •   什么时候使用Unity模块

  一、常用的解决方案

  Unity模块可以解决开发者面对的以组件为基础的开发中遇到的一些问题。现代的商业应用中,有许多用来实现特殊功能的业务对象和组件,还有一些组件可以独立实现一些功能,例如,日志、验证、授权、缓存和异常处理。

  成功建立这种类型应用的关键,就是完成一个解耦的、松散耦合的设计。松散耦合的应用更灵活,并且更容易维护。同样,在开发的过程中,他们也很容易测试。你可以伪造那些有强依赖的对象,例如,数据库连接、网络连接、ERP连接和富客户端接口组件,来进行单元测试。

  依赖注入是建立松散耦合应用的主要技术。它提供了一些处理对象之间依赖的方法。例如,一个处理客户信息的对象,可能会依赖于访问存储的对象,验证信息的对象,和检查用户是否具有更新权限的对象。依赖注入技术可以确保客户类被正确的初始化,加载上面用到的对象,特别在当依赖是抽象的时候。

  下面的模式定义了处理这个过程的架构和开发方法:

  •   Inversion of Control(IOC)pattern。这种模式支持插件式的架构,使得对象可以查询其他需要的对象。
  •   Dependency Injection(DI)pattern。是一种特殊的IOC模式,是一种以面向接口为基础的编程技术,可以修改类的行为,但是不是通过修改类的内部实现。开发者使用接口编程,用一个容器在类中注入依赖的对象实例,注入对象实例的方法包括:接口注入,构造函数注入属性(setter)注入,方法调用注入。
  •   Interception pattern。这种模式引入另一种层次的间接性。在客户端和真实对象之间放一个对象。在客户端和真实对象之间有一个代理。客户端的行为通过代理和真实对象进行交互,以及其他需要交互的对象。

  下面将向大家演示下列功能:

  •   建立Unity容器
  •   获取指定类型的对象
  •   获取指定类型和注册名的对象
  •   获取一个特殊类型的全部对象
  •   使用BuildUp创建对象,而不是通过容器
  •   为构造函数注入注释对象
  •   为属性(setter)注入注释对象
  •   为方法调用注入注释对象

  另外,Unity的示例代码中还包含其他的技术,一个简单的MVP模式实现,和一个Event Broker服务作为自定义的容器扩展。

  示例代码

  使用依赖注入框架和反转控制技术,开发者可以生成自定义类的实例,和依赖其他对象的对象实例。Unity模块支持这些功能,开发者可以使用容器配置注入、构造函数注入、属性注入、方法调用注入,创建所有有依赖的对象实例。

  Unity提供了两个方法,可以在容器中注册类型和映射关系。

  •   RegisterType,这个方法在容器中注册一个类型,在适当的时候,容器会创建一个指定类型的实例。可以通过类的attribute或者是调用Resolve方法来实现。创建的对象的生命周期,就是在参数中指定的生命周期。如果你没有提供生命周期参数,注册类型的生命周期是短暂的,意味着每次调用Resolve方法的时候,容器都会创建一个新的对象实例。

 

 

代码
using System;
using Microsoft.Practices .EnterpriseLibrary.Logging;
using Microsoft.Practices.Unity;

namespace BeautyCode.ConApp
{
    
public     interface IMyService
    {}
    
public class CustomService:IMyService 
    {}
    
/// <summary>
    
/// Description of Class4.
    
/// </summary>
    public class Class4
    {
        
public Class4()
        {
            IUnityContainer myContainer
=new UnityContainer ();
            myContainer.RegisterType 
<IMyService,CustomService>();
            IMyService myServiceInstance
=myContainer.Resolve <IMyService >();
        }
    }
}

 

 

  •   RegisterInstance,这个方法在容器中注册一个已经存在实例的类型,生命周期可以指定。在生命周期里面,容器返回这个已经存在的实例。如果没有指定生命周期,实例的生命周期由容器控制。

  

 

 

代码
using System;
using Microsoft.Practices .EnterpriseLibrary.Logging;
using Microsoft.Practices.Unity;

namespace BeautyCode.ConApp
{
    
public     interface IMyService
    {}
    
public class CustomService:IMyService 
    {}
    
/// <summary>
    
/// Description of Class4.
    
/// </summary>
    public class Class4
    {
        
public Class4()
        {
            IUnityContainer myContainer
=new UnityContainer ();
            CustomService customerServ
=new CustomService ();
            myContainer .RegisterInstance 
<IMyService >(customerServ );
            
            IMyService myServiceInstance
=myContainer.Resolve <IMyService >();
        }
    }
}

 

 

  构造函数注入

  如果开发者使用Unity的Resolve方法初始化的一个类有一个构造函数,构造函数有一个以上的参数,参数的类型是其他的自定义类,Unity容器会自动创建参数中描述的依赖对象。例如下面的CustomService类,依赖于一个LoggingService类。

  

 

 public class CustomService:IMyService 
    {
        
public CustomService (LoggingService logger)
        {
            logger .WriteToLog(
"Some Value");
        }
    }

 

 

  在运行的时候,开发者使用容器的Resolve方法创建一个CustomService的实例,容器也会在CustomService类型范围内创建一个LoggingService对象实例。

  

  

 

 

IUnityContainer myContainer=new UnityContainer ();
            CustomService myInstance
=myContainer .Resolve <CustomService  >();

 

 

  属性注入

  除了构造函数注入,Unity还支持属性注入和方法调用注入。下面将讲述属性注入。一个ProductService类有一个属性,是一个叫做SupplierData的类,通过在属性上添加Denpendency特性实现属性注入。

  

 

代码
public class SupplierData
    {
    }
    
public class ProductData
    {
        
private SupplierData _supplier;
        
        [Dependency ]
        
public SupplierData Supplier
        {
            
get{return _supplier ;}
            
set{this._supplier=var;}
        }
    }
    

 

 

  现在,使用Unity创建一个ProductData对象实例,会自动创建一个SupplierData类的实例作为ProductData对象的属性值。

  

   未完待续。。。。。。。。。。。。。。。。。。。。。。。。。。。。。