通过使用依赖注入框架和反转控制,你可以生成和装配自定义类实例和能包含依赖对象的实例和配置。在接下来的段落中说明了使用Unity的方法。
The Types of Objects Unity Can Create —Unity可以创建对象
你可以使用Unity容器来创建任何拥有公共构造函数(public constructor)对象的实例(当然,你也可以通过new操作来创建)而不必通过容器注册映射(mapping)。当你调用Resolve方法创建一个默认未注册的实例类型,Unity 容器会简单的调用这个类型的构造函数并返回结果。
Unity暴露一个名为RegisterType的方法用来通过容器注册映射类型。这个方法也支持通过容器调用Resolve方法来构造一个你指定的类型实例。所创建的对象的生命周期相当于你指定方法参数的生命周期。如果你没有为生命周期指定一个值,则容器在每次调用Resolve方法都会创建一个新的实例,更多信息请参看:Registering Types and Type Mappings——类型注册及映射。
Registering Existing Types and Object Instances—注册已存在的类型和对象实例
Unity暴露一个名为RegisterInstance的方法用于通过容器注册已存在的的实例。当你调用Resolve方法时,容器会返回一个已经存在的在生命周期内的实例。如果你没有为生命周期指定一个值,则实例的生命周期被容器控制,这意味着它实际上是一个单例实例。更多信息可以查看 Create Instance Registrations——创建注册实例。
Managing the Lifetime of Objects—管理对象的生命周期
Unity允许你在创建对象的时候选择一个生命周期。默认情况下,每次你通过调用Resolve方法并指定一个类型时Unity都会创建一个全新的实例。然而,你可以使用生命周期管理器来为创建的实例指定不同的生命周期。例如,你可以指定Unity保持一个单独实例(或者,单例对象)——如果不存在的实例则会创建一个全新实例,而如果已经存在则直接返回一个引用对象。当然还有其他的生命周期可以使用。例如,你可以使用生命周期管理器来保持一个对象的弱引用以便创建进程来销毁它们,或者通过一个生命周期管理器来为每个线程保持一个单独的实例。
你可以在注册类型、类型映射或者通过配置设计器管理已存在的对象等时候指定一个生命周期管理器,具体可查看Specifying Types in the Configuration File——在配置文件中配置指定类型。另外,你可以使用运行时代码来添加向容器中添加你想使用的生命周期管理注册,具体可以查看Registering Types and Type Mappings——类型注册及映射和Creating Instance Registrations——创建注册实例。
Configuring Types for Injection into Constructors, Methods, and Properties —配置构造注入、方法注入和属性注入
Unity使你可以使用例如:构造函数注入、属性输入和方法调用注入等技术来生成和聚集已完成依赖对象和配置的对象实例。更多信息可以查看Specifying Values for Injection——特殊值注入和Registering Injected Parameter and Property Values——注册注入参数及属性值。
Example Application Code for Constructor Injection—构造注入实例代码
下面是一个构造函数注入的例子,如果你通过Unity容器中的Resolve 方法来实例化一个拥有依赖一个或多个其他类的构造函数时,Unity容器会自动创建构造函数中指定参数的依赖对象实例。例如,在下面的代码中有一个名为CustomerService的类依赖于一个名为LoggingService的类。
C#:
//http://www.cnblos.com/kyo-yo/
public class CustomerService
{
public CustomerService(LoggingService myServiceInstance)
{
// work with the dependent instance
myServiceInstance.WriteToLog("SomeValue");
}
}
Visual Basic:
'http://www.cnblogs.com/kyo-yo/
Public Class CustomerService
Public Sub New(ByVal myServiceInstance As LoggingService)
' work with the dependent instance
myServiceInstance.WriteToLog("SomeValue")
End Sub
End Class
在运行时,开发者可以通过容器的Resolve 方法来创建CustomerService类实例,这会导致它在CustomerService类范围内会注入一个LoggingService类的实例。
C#:
//http://www.cnblos.com/kyo-yo/
IUnityContainer uContainer = new UnityContainer();
CustomerService myInstance = uContainer.Resolve();
Visual Basic:
'http://www.cnblogs.com/kyo-yo/
Dim uContainer As IUnityContainer = New UnityContainer()
Dim myInstance As CustomerService = uContainer.Resolve(Of CustomerService)()
Example Application Code for Property (Setter) Injection—属性(Setter)注入实例代码
除了构造函数注入,在前面描述过,Unity还支持属性和方法调用注入。在下面的代码演示了属性注入。一个名为ProductService的类有一个属性依赖于另外一个名为SupplierData 的类(没有定义在下面的代码中)。Unity不会自动将属性作为一部分创建实例;你必须明确配置容器如何去做。一个方法是为属性添加一个Dependency特性(Attribute)声明,具体的请看下面的代码:
C#:
//http://www.cnblogs.com/kyo-yo/
public class ProductService
{
private SupplierData supplier;
[Dependency]
public SupplierData SupplierDetails
{
get { return supplier; }
set { supplier = value; }
}
}
Visual Basic:
'http://www.cnblogs.com/kyo-yo/
Public Class ProductService
Private supplier As SupplierData
_
Public Property SupplierDetails() As SupplierData
Get
Return supplier
End Get
Set(ByVal value As SupplierData)
supplier = value
End Set
End Property
End Class
现在,创建一个ProductService类的实例,Unity会自动为ProductService类中的SupplierDetails属性生成SupplierData类的实例并设置其值。
Populating and Injecting Arrays, Including Generic Arrays—填充和注入数组,包括泛型数组
你可以定义数组,包括数组和泛型类型,并且Unity会在运行时将数组注入到你的类中。你可以指定数组的成员,或者使用Unity将配置中所定义的匹配类型自动填充到数组中。你然后可以直接使用数组作为类型填充,或者设置成构造函数的值、方法的参数成员和属性。数组可以被定义在配置文件中或通过代码在运行时定义。
更多信息和示例,可以查看一下有关数组的章节:
- Configuring Injected Parameter and Property Values ——配置注入参数和属性值
- Registering Injected Parameter and Property Values ——注册注入参数和属性值
- Registering Generic Parameters and Types ——注册泛型参数和类型
Intercepting Calls to Objects——拦截对象调用
最好类型在面向对象系统中是具体单一职责性。但是随着系统的运行,其他问题被添加进来。系统检测,例如:日志、事件计数器、参数验证和异常处理都是许多常见通用的例子。这些横切问题(AOP)通常需要在程序中添加大量重复代码除非你的设计发生改变,例如你更改你的日志框架,然后日志调用在代码中许多地方必须被改变。
拦截技术使你能够在调用目标对象之前或之后增加代码。这种调用就是拦截可能发生的额外处理。当你手动执行此编码过程,接下来你会知道什么被称之为装饰模式。编写装饰模式需求需要在设计开始知道类型的问题,同時要求每一个不同的装饰类型配合你所写的类型。
Unity拦截系统自动创建装饰模式。其允许你最小化的简单的重用代码来解决这些横切问题(AOP),如果有的话,注意什么类型的将被应用到横切问题(AOP)。
Example Application Code—实例程序代码
下面的例子在运行时配置容器,通过使用一个拦截器VirtualMethodInterceptor 、一个拦截行为ABehavior和一个额外的接口实现来拦截类型TypeToIntercept。
C#:
//http://www.cnblogs.com/kyo-yo/
IUnityContainer container = new UnityContainer();
container.AddNewExtension();
container.RegisterType(
new Interceptor(),
new InterceptionBehavior(),
new AdditionalInterface());
Visual Basic:
'http://www.cnblogs.com/kyo-yo/
Dim container As IUnityContainer = New UnityContainer()
container.AddNewExtension(Of DataException)()
container.RegisterType(Of TypeToIntercept)(
New Interceptor(Of VirtualMethodInterceptor)(),
New InterceptionBehavior(Of ABehavior)(),
New AdditionalInterface(Of IOtherInterface)())
你然后可以通过使用下面的示例中的调用来创建实例:
C#:
//http://www.cnblogs.com/kyo-yo/
TypeToIntercept instance = container.Resolve();
Visual Basic:
'http://www.cnblogs.com/kyo-yo/
Dim instance As TypeToIntercept = container.Resolve(Of TypeToIntercept)()
现在当实例调用方法时,在ABehavior类中的代码将在任何调用实例对象之前和之后被执行。
本文翻译自:What Does Untiy Do?
PS:本文翻译自Unity2.0官方文档,主要是为了学习Unity2.0相关的知识,同时锻炼自己的英语能力,不过由于自己的英语实在不好,所以文章肯定有许多问题,所以欢迎指出。