企业库的依赖注入模块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方法的时候,容器都会创建一个新的对象实例。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
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,这个方法在容器中注册一个已经存在实例的类型,生命周期可以指定。在生命周期里面,容器返回这个已经存在的实例。如果没有指定生命周期,实例的生命周期由容器控制。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
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 CustomService (LoggingService logger)
{
logger .WriteToLog( " Some Value " );
}
}
在运行的时候,开发者使用容器的Resolve方法创建一个CustomService的实例,容器也会在CustomService类型范围内创建一个LoggingService对象实例。
CustomService myInstance = myContainer .Resolve < CustomService > ();
属性注入
除了构造函数注入,Unity还支持属性注入和方法调用注入。下面将讲述属性注入。一个ProductService类有一个属性,是一个叫做SupplierData的类,通过在属性上添加Denpendency特性实现属性注入。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
{
}
public class ProductData
{
private SupplierData _supplier;
[Dependency ]
public SupplierData Supplier
{
get { return _supplier ;}
set { this ._supplier = var;}
}
}
现在,使用Unity创建一个ProductData对象实例,会自动创建一个SupplierData类的实例作为ProductData对象的属性值。
未完待续。。。。。。。。。。。。。。。。。。。。。。。。。。。。。