当前位置:编程学习 > 网站相关 >>

WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Pol

在上一篇文章中,我们通过自定义InstanceProvider实现了WCF和微软Enterprise Library Unity Application Block的集成, 今天我们已相同的方式实现WCF与Enterprise Library的另一个Application Block的集成:Policy Injection Application Block (PIAB)。

PIAB,通过Method Interception的机制实现了AOP(Aspect Oriented Programing)。按照PIAB的编程方式,我们将非业务逻辑,比如Caching、Authorization、Transaction Enlist、Auditing、ExceptionHandling扽等等, 定义在一个个的CallHandler,这些CallHandler通过Attribute或者Configuration的方式应用到目标方法上。关于PIAB的详细介绍,我们参考我的PIAB系列

由于PIAB特殊的实现机制,我们需要通过PIAB的PolicyInjector来创建新的对象或者包装现有的目标对象。只有调用这种能够方式的对象,应用在上面的CallHandler才能被执行。所以WCF和PIAB的核心问题就是如何通过PIAB PolicyInjector来创建新的Service Instance,或者包装已经生成的service instance。在上面一篇文章中,我们通过Unity Container重新定义了InstanceProvider,我们今天的实现方案也是通过自定义InstanceProvider的方式来实现,不是我们需需要通过PolicyInjector来进行对象的创建。

一、创建基于PolicyInjection的InstanceProvider

下面是我们新的InstanceProvider(PolicyInjectionInstanceProvider )的定义

   1: namespace Artech.WCFExtensions
   2: {
   3:     public class PolicyInjectionInstanceProvider : IInstanceProvider
   4:     {
   5:         private Type _serviceContractType;
   6:         private string _policyInjectorName;
   7: 
   8:         public PolicyInjectionInstanceProvider(Type serviceContractType, string policyInjectorName)
   9:         {
  10:             this._serviceContractType = serviceContractType;
  11:             this._policyInjectorName = policyInjectorName;
  12:         }
  13:         public object GetInstance(InstanceContext instanceContext, Message message)
  14:         {
  15:             PolicyInjector policyInjector = null;
  16:             if (string.IsNullOrEmpty(this._policyInjectorName))
  17:             {
  18:                 policyInjector = new PolicyInjectorFactory().Create();
  19:             }
  20:             else
  21:             {
  22:                 policyInjector = new PolicyInjectorFactory().Create(this._policyInjectorName);
  23:             }
  24: 
  25:             Type serviceType = instanceContext.Host.Description.ServiceType;
  26:             object serviceInstance = Activator.CreateInstance(serviceType);
  27:             if (!this._serviceContractType.IsInterface && !serviceType.IsMarshalByRef && policyInjector is RemotingPolicyInjector)
  28:             {
  29:                 return serviceInstance;
  30:             }
  31: 
  32:             return policyInjector.Wrap(serviceInstance, this._serviceContractType);
  33:         }
  34: 
  35:         public object GetInstance(InstanceContext instanceContext)
  36:         {
  37:             return this.GetInstance(instanceContext, null);
  38:         }
  39: 
  40:         public void ReleaseInstance(InstanceContext instanceContext, object instance)
  41:         {
  42:             IDisposable disposable = instance as IDisposable;
  43:             if (disposable != null)
  44:             {
  45:                 disposable.Dispose();
  46:             }
  47:         }
  48:     }
  49: }

我们对PolicyInjectionInstanceProvider 的实现进行简单的说明:在PIAB中真正用于创建对象的是PolicyInjector,虽然PIAB中仅仅定义了一种基于Remoting的RemotingPolicyInjector,但是我们可以根据我们的需要实现一些不同Injection方式,比如IL Injection。所以我们定义了一个字段_policyInjectorName在配置中定位我们需要的PolicyInjector。该字段如果为null或者empty,将使用默认的PolicyInjector。PolicyInjection的获取通过下面的代码实现:

   1: PolicyInjector policyInjector = null;
   2: if (string.IsNullOrEmpty(this._policyInjectorName))
   3: {
   4:     policyInjector = new PolicyInjectorFactory().Create();
   5: }
   6: else
   7: {
   8:     policyInjector = new PolicyInjectorFactory().Create(this._policyInjectorName);
   9: }

能够被RemotingPolicyInjector创建的对象不是满足下面两个条件中的一个:

Target type实现一个Interface。
Target Type直接或者间接集成System.MarshalByRefObject.
所以如果不能满足这个条件,我们直接通过反射创建service instance:

   1: Type serviceType = instanceContext.Host.Description.ServiceType;
   2: object serviceInstance = Activator.CreateInstance(serviceType);
   3: if (!this._serviceContractType.IsInterface && !serviceType.IsMarshalByRef && policyInjector is RemotingPolicyInjector)
   4: {
   5:          return serviceInstance;
   6: }

最后我们通过policyInjector 的Wrap方法对service instance进行封装并返回:

   1: return policyInjector.Wrap(serviceInstance, this._servi

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,