閱讀346 返回首頁    go 阿裏雲 go 技術社區[雲棲]


WCF後續之旅(8):通過WCF Extension 實現與MS Enterprise Library Policy Injection Application Block 的集成

上一篇文章中,我們通過自定義InstanceProvider實現了WCF和微軟Enterprise Library Unity Application Block的集成, 今天我們已相同的方式實現WCF與Enterprise Library的另一個Application Block的集成:Policy Injection Application Block (PIAB)。

一、創建基於PolicyInjection的InstanceProvider

   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: } 

   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: } 

   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: } 

   1: return policyInjector.Wrap(serviceInstance, this._serviceContractType);

二、為PolicyInjectionInstanceProvider創建Behavior

I、ContractBehavior:PolicyInjectionBehaviorAttribute

   1: namespace Artech.WCFExtensions
   2: {
   3:     public class PolicyInjectionBehaviorAttribute : Attribute, IContractBehavior
   4:     {
   5:         public string PolicyInjectorName{ get; set; }
   6:         public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){ }
   7:         public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime){ }
   8:         public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
   9:         {
  10:             Type serviceContractType = contractDescription.ContractType;
  11:             dispatchRuntime.InstanceProvider = new PolicyInjectionInstanceProvider(serviceContractType, this.PolicyInjectorName);
  12:         }
  13:         public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint){ 
  14:     }
  15: } 

   1: namespace Artech.WCFExtensions
   2: {
   3:     public class PolicyInjectionBehavior : IEndpointBehavior
   4:     {
   5:         private string _policyInjectorName;
   6:         public PolicyInjectionBehavior(string policyInjectorName)
   7:         {
   8:             this._policyInjectorName = policyInjectorName;
   9:         }
  10:         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){ }
  11:         public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime){ }
  12:         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
  13:         {
  14:             Type serviceContractType = endpoint.Contract.ContractType;
  15:             endpointDispatcher.DispatchRuntime.InstanceProvider = new PolicyInjectionInstanceProvider(serviceContractType, this._policyInjectorName);
  16:         }
  17:         public void Validate(ServiceEndpoint endpoint){ }
  18:     }
  19: } 

   1: namespace Artech.WCFExtensions
   2: {
   3:     public class PolicyInjectionBehaviorElement:BehaviorExtensionElement
   4:     {
   5:         [ConfigurationProperty("policyInjectorName",IsRequired = false, DefaultValue = "")]
   6:         public string PolicyInjectorName
   7:         {
   8:             get
   9:             {
  10:                 return this["policyInjectorName"] as string;
  11:             }
  12:             set
  13:             {
  14:                 this["policyInjectorName"] = value;
  15:             }
  16:         } 
  17:  
  18:         public override Type BehaviorType
  19:         {
  20:             get { return typeof(PolicyInjectionBehavior); }
  21:         } 
  22:  
  23:         protected override object CreateBehavior()
  24:         {
  25:             return new PolicyInjectionBehavior(this.PolicyInjectorName);
  26:         }
  27:     }
  28: } 
  29:  

三、應用我們的PolicyInjectionBehavior

wcf_02_08_01

I、Artech.TimeService.Contract

   1: namespace Artech.TimeService.Contract
   2: {
   3:     [ServiceContract]
   4:     [PolicyInjectionBehavior]
   5:     public interface ITime
   6:     {
   7:         [OperationContract]
   8:         DateTime GetCurrentTime();
   9:     }
  10: } 

II、Artech.TimeService.Service

   1: namespace Artech.TimeService.Service
   2: {
   3:     public class TimeService:ITime
   4:     {
   5:        [CachingCallHandler]
   6:         public DateTime GetCurrentTime()
   7:         {
   8:             return DateTime.Now;
   9:         } 
  10:     }
  11: } 

III、Artech.TimeService.Hosting

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <services>
   5:             <service name="Artech.TimeService.Service.TimeService">
   6:                 <endpoint behaviorConfiguration="" binding="basicHttpBinding"
   7:                     contract="Artech.TimeService.Contract.ITime" />
   8:                 <host>
   9:                     <baseAddresses>
  10:                         <add baseAddress="https://127.0.0.1/timeservice" />
  11:                     </baseAddresses>
  12:                 </host>
  13:             </service>
  14:         </services>
  15:     </system.serviceModel>
  16: </configuration> 
   1: namespace Artech.TimeService.Hosting
   2: {
   3:     class Program
   4:     {
   5:         static void Main(string[] args)
   6:         {
   7:             using (ServiceHost host = new ServiceHost(typeof(Artech.TimeService.Service.TimeService)))
   8:             {
   9:                 host.Opened += delegate
  10:                 {
  11:                     Console.WriteLine("Time service has been started up!");
  12:                 };
  13:                 host.Open(); 
  14:  
  15:                 Console.Read();
  16:             }
  17:         }
  18:     }
  19: } 
  20:  

IV、Artech.TimeService.Client

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <client>
   5:             <endpoint address="https://127.0.0.1/timeservice" binding="basicHttpBinding"
   6:                 contract="Artech.TimeService.Contract.ITime" name="timeservice" />
   7:         </client>
   8:     </system.serviceModel>
   9: </configuration> 

   1: namespace Artech.TimeService.Client
   2: {
   3:     class Program
   4:     {
   5:         static void Main(string[] args)
   6:         {
   7:             using (ChannelFactory<ITime> channelFactory = new ChannelFactory<ITime>("timeservice"))
   8:             {
   9:                 ITime proxy = channelFactory.CreateChannel(); 
  10:  
  11:                 for (int i = 0; i < 10; i++)
  12:                 {
  13:                     Console.WriteLine(proxy.GetCurrentTime());
  14:                    Thread.Sleep(1000);
  15:                 }
  16:             } 
  17:  
  18:             Console.Read();
  19:         }
  20:     }
  21: } 
  22:  

wcf_02_08_02

   1: namespace Artech.TimeService.Contract
   2: {
   3:     [ServiceContract]
   4:    //[PolicyInjectionBehavior]
   5:     public interface ITime
   6:     {
   7:         [OperationContract]
   8:         DateTime GetCurrentTime();
   9:     }
  10: } 

wcf_02_08_03

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <endpointBehaviors>
   6:                 <behavior name="PolicyInjectionBehavior">
   7:                     <PolicyInjectionBehaviorExtension />
   8:                 </behavior>
   9:             </endpointBehaviors>
  10:         </behaviors>
  11:         <extensions>
  12:             <behaviorExtensions>
  13:                 <add name="PolicyInjectionBehaviorExtension" type="Artech.WCFExtensions.PolicyInjectionBehaviorElement, Artech.WCFExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  14:             </behaviorExtensions>
  15:         </extensions>
  16:         <services>
  17:             <service name="Artech.TimeService.Service.TimeService">
  18:                 <endpoint behaviorConfiguration="PolicyInjectionBehavior" binding="basicHttpBinding"
  19:                     contract="Artech.TimeService.Contract.ITime" />
  20:                 <host>
  21:                     <baseAddresses>
  22:                         <add baseAddress="https://127.0.0.1/timeservice" />
  23:                     </baseAddresses>
  24:                 </host>
  25:             </service>
  26:         </services>
  27:     </system.serviceModel>
  28: </configuration>

wcf_02_08_04

 

WCF後續之旅:
WCF後續之旅(1): WCF是如何通過Binding進行通信的
WCF後續之旅(2): 如何對Channel Layer進行擴展——創建自定義Channel
WCF後續之旅(3): WCF Service Mode Layer 的中樞—Dispatcher
WCF後續之旅(4):WCF Extension Point 概覽
WCF後續之旅(5): 通過WCF Extension實現Localization
WCF後續之旅(6): 通過WCF Extension實現Context信息的傳遞
WCF後續之旅(7):通過WCF Extension實現和Enterprise Library Unity Container的集成
WCF後續之旅(8):通過WCF Extension 實現與MS Enterprise Library Policy Injection Application Block 的集成
WCF後續之旅(9):通過WCF的雙向通信實現Session管理[Part I]
WCF後續之旅(9): 通過WCF雙向通信實現Session管理[Part II]
WCF後續之旅(10): 通過WCF Extension實現以對象池的方式創建Service Instance
WCF後續之旅(11): 關於並發、回調的線程關聯性(Thread Affinity)
WCF後續之旅(12): 線程關聯性(Thread Affinity)對WCF並發訪問的影響
WCF後續之旅(13): 創建一個簡單的WCF SOAP Message攔截、轉發工具[上篇]
WCF後續之旅(13):創建一個簡單的SOAP Message攔截、轉發工具[下篇]
WCF後續之旅(14):TCP端口共享
WCF後續之旅(15): 邏輯地址和物理地址
WCF後續之旅(16): 消息是如何分發到Endpoint的--消息篩選(Message Filter)
WCF後續之旅(17):通過tcpTracer進行消息的路由


作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-30 17:04:47

  上一篇:go  近百年前寶潔發明“肥皂劇”,阿裏要創造“種草劇”!
  下一篇:go  一個通過BackgroundWorker實現WinForm異步操作的例子