WCF擴展系列 - 行爲擴展(Behaviors)

原文地址:http://www.cnblogs.com/Creator/archive/2011/05/21/2052687.htmlhtml

這個系列的第一部分將會重點關注WCF行爲(behaviors),WCF提供了四種類型的行爲:服務行爲、終結點行爲、契約行爲和操做行爲。這些行爲的接口幾乎是全部WCF的擴展入口。本篇文章只是對行爲拓展講述一些基礎的鋪設,具體到上面四個行爲的擴展以及使用案例,將會在後續的文章中講到.安全

Behaviors架構

上述這四個行爲的所定義的接口分別是IServiceBehavior,IEndpointBehavior,IContractBehavior以及 IOperationBehavior。雖然是四個不一樣的接口,但它們的接口方法卻基本相同,分別爲 AddBindingParameters(),ApplyClientBehavior()以及ApplyDispatchBehavior()。注意,IServiceBehavior因爲只能做用在服務端,所以並不包含ApplyClientBehavior()方法ide

public interface I[Service/Endpoint/Contract/Operation]Behavior { 
                void Validate(DescriptionObject); 
                void AddBindingParameters(DescriptionObject, BindingParameterCollection); 
                void ApplyDispatchBehavior(DescriptionObject, RuntimeObject); 
                void ApplyClientBehavior(DescriptionObject, RuntimeObject); // not on IServiceBehavior 
}post

其中的方法描述以下:this

  • AddBindingParameters用於向綁定元素傳遞自定義數據,以支持協定實現。
  • Validate:用於檢查服務宿主和服務說明,從而肯定服務是否可成功運行。
  • Apply[Client/Dispatch]Behavior這是咱們能夠引用和修改WCF運行時對象的地方,也是用得最多的行爲方法(大部分狀況,上兩個方法都會留空)。用於更改運行時屬性值或插入自定義擴展對象(例如錯誤處理程序、消息或參數攔截器、安全擴展以及其餘自定義擴展對象)。

他們各自的做用範圍以下圖所示(引用自張逸):spa

image

 

增長一個行爲(behaviors )code

向WCF中增長行爲有三種不一樣的方法:htm

    • 代碼:service / endpoint / contract / operation 的描述類有一個behaviors集合屬性,咱們能夠經過他簡單的增長一個行爲,具體作法,先將自定義服務行爲添加到 Behaviors 屬性,而後對 System.ServiceModel.ServiceHost 對象調用 ICommunicationObject.Open 方法。對象

    • 配置文件:經過配置文件system.serviceModel/behaviors 節點,咱們能夠指定service behaviors 和 endpoint behaviors,已達到添加行爲的目的

    • 特性: 添加行爲的簡單方法是使用特性 — — 除了終結點行爲。經過建立特性類 (基類型 = = System.Attribute) 和實現其中一個行爲接口,您能夠將特性應用於適當的元素,並添加行爲到元素的描述。下面的代碼顯示了一個簡單的服務,基於特性的行爲的添加以及輸出它們的調用順序 (以及經過代碼添加終結點行爲)。

  1 using System;
  2 using System.Collections.ObjectModel;
  3 using System.Reflection;
  4 using System.ServiceModel;
  5 using System.ServiceModel.Channels;
  6 using System.ServiceModel.Description;
  7 using System.ServiceModel.Dispatcher;
  8 
  9 namespace Behaviors
 10 {
 11     class MyServiceBehaviorAttribute : Attribute, IServiceBehavior
 12     {
 13         public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
 14         {
 15             Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
 16         }
 17 
 18         public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 19         {
 20             Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
 21         }
 22 
 23         public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 24         {
 25             Console.WriteLine("Inside {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name);
 26         }
 27     }
 28 
 29     class MyEndpointBehavior : IEndpointBehavior
 30     {
 31         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
 32         {
 33             Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
 34         }
 35 
 36         public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
 37         {
 38             Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
 39         }
 40 
 41         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
 42         {
 43             Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
 44         }
 45 
 46         public void Validate(ServiceEndpoint endpoint)
 47         {
 48             Console.WriteLine("Inside {0}.{1}, endpoint {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, endpoint.Name);
 49         }
 50     }
 51 
 52     class MyContractBehaviorAttribute : Attribute, IContractBehavior
 53     {
 54         public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
 55         {
 56             Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
 57         }
 58 
 59         public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
 60         {
 61             Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
 62         }
 63 
 64         public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
 65         {
 66             Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
 67         }
 68 
 69         public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
 70         {
 71             Console.WriteLine("Inside {0}.{1}, contract {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, contractDescription.ContractType.Name);
 72         }
 73     }
 74 
 75     class MyOperationBehaviorAttribute : Attribute, IOperationBehavior
 76     {
 77         public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
 78         {
 79             Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
 80         }
 81 
 82         public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
 83         {
 84             Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
 85         }
 86 
 87         public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
 88         {
 89             Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
 90         }
 91 
 92         public void Validate(OperationDescription operationDescription)
 93         {
 94             Console.WriteLine("Inside {0}.{1}, operation {2}", this.GetType().Name, MethodBase.GetCurrentMethod().Name, operationDescription.Name);
 95         }
 96     }
 97 
 98     [ServiceContract]
 99     [MyContractBehavior]
100     public interface ITest
101     {
102         [OperationContract]
103         [MyOperationBehavior]
104         int Add(int x, int y);
105         [OperationContract]
106         int Multiply(int x, int y);
107     }
108 
109     [ServiceContract]
110     [MyContractBehavior]
111     public interface ITest2
112     {
113         [OperationContract]
114         [MyOperationBehavior]
115         string Echo(string text);
116     }
117 
118     [MyServiceBehavior]
119     public class Service : ITest, ITest2
120     {
121         public int Add(int x, int y) { return x + y; }
122         public int Multiply(int x, int y) { return x * y; }
123         public string Echo(string text) { return text; }
124     }
125 
126     class Program
127     {
128         static void Main(string[] args)
129         {
130             string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
131             ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
132             ServiceEndpoint ep1 = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic");
133             ep1.Name = "Endpoint1-BasicHttp";
134             ep1.Behaviors.Add(new MyEndpointBehavior());
135             ServiceEndpoint ep2 = host.AddServiceEndpoint(typeof(ITest2), new WSHttpBinding(), "ws");
136             ep2.Name = "Endpoint2-WSHttp";
137             ep2.Behaviors.Add(new MyEndpointBehavior());
138             Console.WriteLine("Opening the host...");
139             host.Open();
140             Console.WriteLine("Host opened");
141         }
142     }
143 }

 

 

      我並不認爲這就是「最優」的添加方法,他只是描述經過特性增長行爲的一個特定的例子而已,具體什麼是「最優」的添加行爲的方法呢?其實這就像軟件架構同樣,永遠沒有最好的架構,只有最合適的架構。因此具體項目裏面採用哪一種方式去添加來得具體狀況具體分析。我的比較喜歡用使用配置文件添加的方法….

 

 


 在後面的文章中將會講訴到具體的行爲擴展,敬請期待..

 

        1.1.1. IServiceBehavior 
        1.1.2. IContractBehavior 
        1.1.3. IEndpointBehavior 
        1.1.4. IOperationBehavior

 


博客地址:Zealot Yin

歡迎轉載,轉載請註明出處[http://creator.cnblogs.com/]

相關文章
相關標籤/搜索