原文地址: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
他們各自的做用範圍以下圖所示(引用自張逸):spa
增長一個行爲(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