3.5 [ Enterprise Library ]注入模型设计
转载请注明出处:http://www.cnblogs.com/doriandeng/archive/2007/10/07/916431.html
Enterprise Library 使用一个定制的底层的名为
ObjectBuilder的系统在运行时注入适当类型的对象的实例(实例有预设的属性)到应用程序中。ObjectBuilder 的设计
对象实例的构造和释放在绝大多数应用程序是一个通用的过程,尤其是在像使用 Enterprise Library
构建的商业应用程序中。基于这个原因,Enterprise Library
应用程序块利用了一个名为ObjectBuiler的底层子系统,它执行所有重复、必要的创建对象实例的任务,并提供了高度的灵活性。
ObjectBuilder
封装了对象实例的创建。它可以做下列事情:
创建特定的具体类实例,甚至要求为抽象类型。
如果可以,返回已存在的对象实例;或者总是生成新的实例。
从工厂类中基于配置数据创建合适的对象。
当一个类暴露出多个构造函数时,智能的选择适当的构造函数。
自动应用值到公共属性,并在响应到预定义策略中执行对象的方法。
响应( respond )定义在属性和方法上的属性(Attribute ) ,它影响着新对象的创建和命名。
自动与支持
IBuilderAware接口的对象通信以指出对象已创建完毕。提供销毁功能,它能由逆向的操作链从已存在的对象中移除设置。
ObjectBuilder
是一个底层次的工具,在绝大多数情况下,不会与其直接在应用程序中交互。在应用程序块中的类使用它在创建声明在应用程序块中的类时生成对象实例。然而,如果你愿意,可以直接在应用程序和框架中使用ObjectBuilder
的特性。也可以创建自己的策略或修改已存在的策略以影响ObjectBuilder
的行为。
关于 ObjectBuilder 的更多信息,包括文档和更新释放,请参见
ObjectBuilder 依赖注入框架。
ObjectBuilder 架构
ObjectBuilder
使用了一个策略管道。利用这个管道,多个操作可以替换为对象被说明和为使用而准备。这儿的意思是可以控制在替换过程中的顺序。它也支持由运行适当的管道进程以相反的顺序的受控的对象释放。
ObjectBuilder
策略在构造和销毁期间管理对象执行的过程。ObjectBuilder
管道被组织成多个阶段,管道的每个阶段包含多个策略。可以实现自己的策略为一个 .NET
框架类,并带有指定的接口。
ObjectBuilder 方法
ObjectBuilder 存在于命名空间
Microsoft.Practices.ObjectBuilder中,其基类
BuilderBase暴露了二个方法。BuildUp方法有二个重载。
例 3.9. C#
BuildUp(locator, type, id, instance, policies[] ); BuildUp<type>(locator, id, instance, policies[] );
例 3.10. Visual Basic .NET
BuildUp(locator, type, id, instance, policies() ) BuildUp(Of type)(locator, id, instance, policies() )
前面的代码包含下列元素:
- locator
这是一个实现了
IReadWriteLocator接口的类的引用,它为对象或类的放置提供了线索。更多信息请参见此主题后面部分的“使用 ReadWriteLocator ”。- type
要创建的对象的类型。
- id
分配给新的对象实例的标识。
- instance
可选的到在将起作用管道进程中的已存在的对象实例的引用。这允许使用已存在的对象并确认它们通过管道传送它们以适当的为使用做准备。
ObjectBuilder仅应用合适的进程到这样的对象实例。- policies[]
PolicyList实例的数组,它实现了瞬时的方针( policy ),覆盖了内建的方针。更多信息,请参见本节后面的“使用PolicyList”。
TearDown方法利用已存在的对象实例,并在通过策略链后运行它。这个过程可以移除在BuildUp进程期间添加到对象中的特性,如果打算重新使用对象的话。
TearDown 方法的签名如下。
例 3.12. Visual Basic .NET
Public Function TearDown(Of T)(ByVal locator As IReadWriteLocator, ByVal item As T) As T _ Implements IBuilder(Of TStageEnum).TearDown
使用 ReadWriteLocator
ObjectBuilder使用生命时间包装器的概念保存对象的引用,这确保正确的对象管理以及在正确的时间销毁它们。定位器引用了生命时间包装器中独立的对象。在定位器中的多个条目可以指向同样的对象实例。例如,在定位器中的条目可能
通过类类型名、它实现的接口和对象名来引用。
定位器可以是只读的或者可读写的,ObjectBuilder 的
BuildUp
方法利用了一个实现了IReadWriteLocator
接口的对象的实例。
使用 PolicyList
PolicyList 是一个政策( Policy
)的集合,其中每一个都由实现了IBuilderPolicy接口的类所描绘,它们一起影响
ObjectBuilder创建对象的方法。政策可以是临时的也可以是永久的。
临时政策是那些由在ObjectBuilder
中的策略自动生成的或者是通过反射声明在类文件中的方法和属性 ( Property )上的属性 ( Attribute )
而来的政策。
持久政策是那些由实现了 IBuilderPolicy
接口创建的。可以传递这些类实例的数组到ObjectBuilder的BuildUp方法中去。
管道阶段
在 ObjectBuilder 中的管道由下列四个阶段组成:
- 预创建
发生在
ObjectBuilder创建一个对象的新实例前。- 创建
在此阶段,
ObjectBuilder创建新的对象实例。- 初始化
在此阶段,
ObjectBuilder为使用而准备对象。它设置新对象实例的属性并调用方法。- 初始化后
此阶段发生在
ObjectBuilder返回新建的对象前。
表3.1 列出了ObjectBuilder 在管道的每个过程中所完成的默认处理。
表 3.1. 启动一个复合 UI 程序块应用程序的步骤
| 管道步骤 | ObjetBuilder 策略 |
|---|---|
| 预创建( ProCreation ) | TypeMappingStrategy; SingletonStrategy; ConstructorReflectionStrategy |
| 创建 ( Creation ) | CreationStrategy |
| 初始化 ( Initialization ) | PropertySetterStrategy; PropertyReflectionStrategy; MethodReflectionStrategy; MethodExecutionStrategy |
| 初始化后 ( PostInitialization ) | BuilderAwareStrategy |
应用程序块使用 ObjectBuilder
添加指定的策略到管道中,如果需要,可以添加自己的策略。
策略类型
列出在表3.2 中的用于 ObjectBuilder
的默认策略如下:
- TypeMappingStrategy
此策略可以设计对象实质的返回类型。例如,一个抽象或接口类型
IMyObject的要求是能自动强制转换为具体的类型MyObject。- SingletonStrategy
此策略指出
ObjectBuilder是返回一个新的对象实例还是一个可用的已存在的实例。- ConstructorReflectionStrategy
此策略检查声明在构造函数中的属性的类,特别是 [InjectionConstructor] 属性,并选择哪一个用于对象的创建。关于在构造函数中用[Dependency] 和 [CreateNew] 属性修饰的参数如何影响行为的更多信息将在本节的后面部分描绘。
- CreationStrategy
此策略实例化新的对象,使用构造函数或者
Activator类方法。- PropertySetterStrategy
此策略可以基于政策设置新对象实例的公共属性的值。
- PropertyReflectionStrategy
此策略查检在属性( Property )上的属性( Attribute ) 的类,并应用它们到新的对象实例。拥有[Dependency] 和 [CreateNew] 属性 ( Attribute ) 的属性 ( Property ) 的应用致使这些值注入到了新的对象实例中。
- MethodReflectionStrategy
此策略检查方法上的属性的类,方法必须运行在初始化阶段期间。
- MethodExecutionStrategy
此策略运行新对象实例中的方法,这依赖于政策( Policy )。
- BuilderAwareStrategy
此策略检查类以查看它是否实现了
IBuilderAware接口。如果实现了,ObjectBuilder在创建完成时通知对象,然后对象触发 OnBuiltUp 以示准备完毕可以使用了。如果ObjectBuilder运行了TearDown方法,它将触发 OnTearingDown 事件。
如果要创建更多的步骤、修改或移除现在的步骤,可以从 BuilderBase
类派生自己的类,而使用自己的步骤,或者预初始化一个构造器以满足自己的需要。查看构造器的源文件(
Builder.cs ) 可以看到一个如何做的例子。
基于属性的依赖注入
ObjectBuilder
支持一个能用目的的基于属性的依赖注入。二个内建的策略,ConstructorInjectionStrategy
和 PropertyInjectionStrategy
,提供了依赖注入。二个策略都支持一个通用的属性集,可以应用到变量。这些属性如下:
- [CreateNew]
此属性告诉依赖注入系统总是创建新的需要的。这对像模型-视图-控制器(MVC)或模型-视图-展示器(MVP)这样的设计模式非常有用,这些地方创建一个视图就自动生成一个新的控制器/展示器。
- [Dependency]
这是一个通用目的的属性,带有四个可选参数:
- Name
指定命名的对象替换未命名的对象。默认值,如果省略的话,是 null ( 未命名的)。
- NotPresentBehavior
指定如果想要的对象不存在的话会发生什么。默认值是 NotPresentBehavior.CreateNew。
- CreateType
指定将要创建的类型。
- SearchMode
指定定位器是否将为对象搜索树,或者消除依赖。如果省略,默认值是Up。
前面在 [Dependency] 属性中的这些属性意味着它可以满足下列所有需求:
查找未命名的 X ( X 是一种类型)。如果不存在,将抛出异常。
查找未命名的 X 。如果它不存在,将创建一个新的。
查找未命名的 X 。如果它不存在,提供一个 null 值代替。
查找命名为 Y 的 X ( Y 是一个字符串) 。如果不存在,抛出一个异常。
查找命名为 Y 的 X 。如果不存在,创建一个新的。
查找命名为 Y 的 X 。如果不存在,提供一个 null 值代替。
例如,以下代码总是生成一个类型为 MyCustomObject 的。
例 3.13. C#
using Microsoft.Practices.ObjectBuilder;
[Dependency(CreateType=typeof(MyCustomObject),
NotPresentBehavior=NotPresentBehavior.CreateNew)]
public ICustomObject MyCustomObject { set { ... } }例 3.14. Visual Basic .NET
Imports Microsoft.Practices.ObjectBuilder <Dependency(CreateType:=typeof(MyCustomObject), NotPresentBehavior:=NotPresentBehavior.CreateNew)> _ Public WriteOnly Property MyCustomObject() As ICustomObject Set ... End Set End Property
如果系统没有找到一个 ICustomObject 它将创建一个新的
MyCustomObject ,并为下一个需要
ICustomObject
的人用ICustomObject
类型注册它。
构造函数、属性和方法注入
三个内建的策略,ConstructorReflectionStrategy
、PropertyReflectionStrategy 和
MethodReflectionStrategy ,使用 [Dependency]
和 [CreateNew] 属性来控制它们的行为。
ConstructorReflectionStrategy
有二个方面。首先,它刻画出所使用的构造函数;第二,它刻画出如何满足那些构造函数的参数。
ConstructorReflectionStrategy 首先查找应用了
[InjectionConstructor]
属性的任何构造函数(在这仅可以是其中之一),如果找到,就使用此构造函数。如果没有应用了[InjectionConstructor]
的构造函数,但仅有一个构造函数,则使用那个构造函数。如果有多个构造函数,但没有任何一个应用了
[InjectionConstructor] 属性,策略将抛出一个异常。
在选择构造函数后,策略将决定如何需要的参数到构造函数,这可能由 [ Dependency ] 或者/ 和 [CreateNew] 属性标记。任何没有应用属性的参数都处理为应用了默认 [ Dependency] 属性(未命名的,NotPresentBehavior= NotPresentBehavior.CreateNew, SearchMode = Up ) 。
PropertyReflectionStrategy 查找带有
[Dependency] 和 [CreateNew] 属性(
Attribute )的属性 ( Property )并适当的满足它们(它们必须是公共的并拥有设置器)。在一个类中,它不用没有应用属性(
Attribute ) 的属性( Property ) 做任何事件。
MethodReflectionStrategy 查找应用了
[MethodInjection]
的方法,并在初始化阶段执行。这些方法的参数可能包括[CreateNew]和
[Dependency] 属性。任何没有应用属性的参数都将被
为应用了默认的[Dependency]
属性(未命名的,NotPresentBehavior=
NotPresentBehavior.CreateNew, SearchMode = Up ) 。
Enterprise Library 属性( Attribute )
Enterprise Library 提供自己的策略到 ObjectBuilder
。这些策略如下:
- ConfigurationNameMappingStrategy
此策略读取配置源并转换为
ObjectBuilder可以使用的格式。- SingletonStrategy
此策略限制
ObjectBuilder可以创建的对象实例的数量。- ConfiguredObjectStrategy
此策略指挥
ObjectBuilder如何使用配置数据和元数据配置对象。- InstrumentationStrategy
此策略指定度量仪,如性能计数器,一旦对象创建,
ObjectBuidler将附加度量到对象上。
这些 ObjectBuidler
策略使用属性正确的创建对象。表1列出了一些最重要的属性。
表 3.2. Enterprise Library 属性 ( Attribute )
| 属性(Attribute) | 描述 |
|---|---|
| ConfigurationElementType | 指定 ObjectBuilder
将用于创建对象的配置对象类型。类型必须派生自
NameTypeConfigurationElement
,它与属性类关联。 |
| CustomFactoryAttribute | 指定
ObjectBuilder将用于构建对象的定制工厂类型。 |
| ConfigurationNameMapper | 指定用于映射 XML 元素名到提供程序层次中的类型的类型。指定的类型必须实现
IConfigurationNameMapper
接口,ConfigurationNameMappingStrategy
在映射名称时使用此属性来发现要使用的类型。 |
| Assembler | 定义构建对象的工厂。 |
浙公网安备 33010602011771号