Enterprise Library深入解析与灵活应用(1):通过Unity Extension实现和Policy Injection Application Block的集成
Enterprise Library是微软P&P部门开发的众多Open source框架中的一个,最新的版本已经出到了4.0。由于接触Enterprise Library 已经有很长的一段时间,在实际的项目中使用的频率也很高。对此有了一些积累,希望通过这个新的系列和广大网友一起分享和交流。本系列 假设读者已经对Enterprise Library有一定的了解,故而不会对各个Application Block的基本原理和编程模型进行介绍,而把侧重点放在 Enterprise Library深层次的实现原理、设计模式的应用、有效扩展和最佳实践上。
今天我们讨论的内容是如何通过自定义 UnityContainerExtension实现Unity和PIAB的集成,我们假设读者已经对Unity Application Block和Policy Injection Application Block已 经有了一定的了解。
1、创建PolicyInjectionStrategy
我们知道Policy Injection Application Block是基于Remoting的原理 通过Method Interception的方式实现了AOP(而另一种常见的方式是基于IL Injection)。要使应用在目标对象的CallHandler发挥作用,需用 通过PolicyInjecctor(默认为Remoting PolicyInjection)进行对象的创建。而实现Unity和PIAB集成的途径就是让Unity Container使用进行 对象的创建。
Unity是建立在ObjectBuilder之上的,而ObjectBuilder是整个Enterprise Library以及P&P其他开源框架(比如 Smart Client Software Factory)的基石。ObjectBuilder,顾名思义,就是进行对象创建的组件。而ObjectBuilder进行对象创建的方式是基 于策略的(Strategy based object creation),他通过将不同的策略运用到对象创建(或释放回收)的不同的阶段,而从提供了一个功能强 大的、极具扩展的对象创建的框架。而要实现我们的目标,首先需要创建自定义的BuilderStrategy:PolicyInjectionStrategy 。
namespace Artech.PolicyInjectionIntegratedInUnity
{
public class PolicyInjectionStrategy : EnterpriseLibraryBuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
base.PreBuildUp(context);
if (context.Policies.Get<IPolicyInjectionPolicy> (context.BuildKey) == null)
{
context.Policies.Set<IPolicyInjectionPolicy>(new PolicyInjectionPolicy(true), context.BuildKey);
}
}
public override void PostBuildUp(IBuilderContext context)
{
base.PostBuildUp(context);
IPolicyInjectionPolicy policy = context.Policies.Get<IPolicyInjectionPolicy>(context.BuildKey);
if ((policy != null) && policy.ApplyPolicies)
{
policy.SetPolicyConfigurationSource(EnterpriseLibraryBuilderStrategy.GetConfigurationSource(context));
context.Existing = policy.ApplyProxy(context.Existing, BuildKey.GetType(context.OriginalBuildKey));
}
}
}
}
上面就是整个PolicyInjectionStrategy 的定义。通过PreBuildUp在对象创建之前将 PolicyInjectionPolicy添加到BuilderContext 的Policy列表中(BuilderContext 为整个对象的创建和生命周期的管理提供context信息)。 在PostBuildUp中,将PolicyInjectionPolicy从BuilderContext 中取出,调用ApplyProxy方法将创建的对象通过PolicyInjecctor进行封装, 那么调用被封装过的对象,我们的Policy Injection CallHandler就可以发挥其作用了。
注:PolicyInjectionPolicy定了在 Microsoft.Practices.EnterpriseLibrary.PolicyInjection dll中,实现了 Microsoft.Practices.EnterpriseLibrary.PolicyInjection.ObjectBuilder.IPolicyInjectionPolicy和 Microsoft.Practices.ObjectBuilder2.IBuilderPolicy。其ApplyProxy方法实际上就是调用了PolicyInjecctor的Wrap方法。