程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WCF技術剖析之二十: 服務在WCF體系中是如何被描述的?

WCF技術剖析之二十: 服務在WCF體系中是如何被描述的?

編輯:關於.NET

任何一個程序都需要運行於一個確定的進程中,進程是一個容器,其中包含程序實例運行所需的資源。同理,一個WCF服務的監聽與執行同樣需要通過一個進程來承載。我們將為WCF服務創建或指定一個進程的方式稱為服務寄宿(Service Hosting)。服務寄宿的本質通過某種方式,創建或者指定一個進程用以監聽服務的請求和執行服務操作,為服務提供一個運行環境。

服務寄宿的方式大體分兩種:一種是為一組WCF服務創建一個托管的應用程序,通過手工啟動程序的方式對服務進行寄宿,所有的托管的應用程序均可作為WCF服務的宿主,比如Console應用、Windows Forms應用和ASP.NET應用等,我們把這種方式的服務寄宿方式稱為自我寄宿(Self Hosting)。另一種則是通過操作系統現有的進程激活方式為WCF服務提過宿主,Windows下的進程激活手段包括IIS、Windows Service或者WAS(Windows Process Activation Service)等。

服務寄宿的手段是為一個WCF服務類型創建一個ServiceHost對象(或者任何繼承於ServiceHostBase的對象)。無論采用哪種寄宿方式,在為某個服務創建ServiceHost的過程中,WCF框架內部會執行一系列的操作,其中最重要的步驟就是為服務創建服務描述(Service Description)。在本篇文章中,我們將對服務描述進行全面的介紹。

WCF服務描述通過類型System.ServiceModel.Description.ServiceDescription表示,ServiceDescription對象是WCF服務運行時的描述。除了包含WCF服務的一些基本信息,比如服務的名稱、命名空間和CLR類型等,ServiceDescription還包含服務所有終結點和服務行為的描述。

一、 ServiceDescription與ServiceBehavior

從下面ServiceDescription的定義可以看出,ServiceDescription中定義了一系列屬性,它們的含義如下:

Behaviors服務行為(Service Behavior)的集合

ConfigurationName:服務的在配置文件中的名稱,默認為服務類型的全名(命名空間+類型名稱)

Name服務的名稱,默認為服務類型名稱(不包含命名空間)

Namespace服務的命名空間,默認為“http://tempuri.org/”

ServiceType服務的CLR類型

   1: public class ServiceDescription
2: {
3: //其他成員
4: public KeyedByTypeCollection<IServiceBehavior> Behaviors { get; }
5: public string ConfigurationName { get; set; }
6: public ServiceEndpointCollection Endpoints { get; }
7: public string Name { get; set; }
8: public string Namespace { get; set; }
9: public Type ServiceType { get; set; }
10: }

1、Name與Namespace

ServiceDescription的NameNamespace分別表示服務的名稱和命名空間,這兩個屬性同樣體現在服務發布的WSDL中。可以通過System.ServiceModel.ServiceBehaviorAttribute的NameNamespace屬性進行設定。ServiceDescription的Name和Namespace的默認值分別為服務類型名稱和http://tempuri.org/,所以下面兩種定義是等效的。

   1: [ServiceBehavior]
2: public class CalculatorService : ICalculator
3: {
4: //省略成員
5: }
1: [ServiceBehavior(Name = "CalculatorService", Namespace = "http://tempuri.org/")]
2: public class CalculatorService : ICalculator
3: {
4: //省略成員
5: }

而ServiceDescription的Namespace映射WSDL的目標命名空間(targetNamespace),Name則直接對應<wsdl:service>節點的Name屬性。在下面的服務定義中,通過ServiceBehaviorAttribute將Name和Namespace設置為“CalcService”和“http://www.artech.com/”,後面的XML體現了服務在WSDL表示。

   1: [ServiceBehavior(Name = "CalcService", Namespace = "http://www.artech.com/")]
2: public class CalculatorService : ICalculator
3: {
4: //省略成員
5: }
1: <?xml version="1.0" encoding="utf-8"?>
2: <wsdl:definitions name="CalcService" targetNamespace= http://www.artech.com/
3: ...>
4: ......
5: <wsdl:service name="CalcService">
6: ......
7: </wsdl:service>
8: </wsdl:definitions>

2、ConfigurationName

ServiceDescription的ConfiguraitonName表示服務的配置名稱,可以同樣可以通過System.ServiceModel.ServiceBehaviorAttribute的同名屬性進行設定。在默認情況下,ConfiguraitonName的值為服務類型的全名(命名空間+類型名稱),下面兩種服務的定義是等效的。

   1: namespace Artech.ServiceDescriptionDemos
2: {
3: [ServiceBehavior]
4: public class CalculatorService : ICalculator
5: {
6: //省略成員
7: }
8: }
1: namespace Artech.ServiceDescriptionDemos
2: {
3: [ServiceBehavior(ConfigurationName = "Artech.ServiceDescriptionDemos.CalculatorService")]
4: public class CalculatorService : ICalculator
5: {
6: //省略成員
7: }
8: }

如果配置文件中<service>的Name屬性更改了,在服務定義中需要通過ServiceBehaviorAttribute對ConfigurationName進行相應的修正,如下面的代碼所示。

   1: namespace Artech.ServiceDescriptionDemos
2: {
3: [ServiceBehavior(ConfigurationName = "CalculatorService")]
4: public class CalculatorService : ICalculator
5: {
6: //省略成員
7: }
8: }
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <system.serviceModel>
4: <services>
5: <service name="CalculatorService">
6: ......
7: </service>
8: </services>
9: </system.serviceModel>
10: </configuration>

3、服務行為(Service Behavior)

如果說契約(Contract)是涉及雙邊的描述(契約是服務的提供者和服務消費者進行交互的依據),那麼行為(Behavior)就是基於單邊的描述。客戶端行為體現的是WCF如何進行服務調用的方式,而服務端行為則體現了WCF的請求分發方式。行為是對WCF進行擴展的最為重要的方式,按照行為作用域的不同,WCF的行為大體包含以下四種:

服務行為(Service Behavior):基於服務本身的行為,實現了接口System.ServiceModel.Description.IServiceBehavior,可以通過Attribute或者配置的方式進行指定

終結點行為(Endpoint Behavior):基於某個服務終結點(客戶端或者服務端)的行為,實現了接口System.ServiceModel.Description.IEndpointBehavior,可以通過配置的方式進行指定

契約行為(Contract Behavior):基於某個服務契約的行為,作用於實現了該契約的所有服務(服務端行為)和基於該契約進行服務調用的服務代理(客戶端行為),實現了接口System.ServiceModel.Description.IContractBehavior,可以通過Attribute的方式進行指定

操作行為(Operation Behavior):基於服務契約中的某個操作契約,作用於實現了該服務契約的服務對應的服務操作(DispatchOperation)和基於該操作契約進行服務調用的客戶操作(ClientOperation),實現了接口System.ServiceModel.Description.IOperationBehavior,可以通過Attribute進行指定

在ServiceDescription中,類型為KeyedByTypeCollection<IServiceBehavior>的Behaviors屬性表示服務所有的服務行為集合。所有的服務行為都實現了System.ServiceModel.Description.IServiceBehavior接口。IServiceBehavior定義如下,從中可以看出IServiceBehavior定義了如下三個方法。

注:KeyedByTypeCollection<T>可以看成是以T實例為Value,Value對象真實類型為Key的Dictionary,可以通過類型定位並獲取相應的成員對象。

AddBindingParameters為某個自定義綁定元素(Custom Binding Element)添加綁定參數,以指導或者確保綁定元素的正常操作,比如通過設置的綁定參數創建相應的信道

ApplyDispatchBehavior通過改變WCF服務端分發系統的屬性,或者添加/替換分發系統中用以實現某種分發操作的可擴展對象,進而改變服務分發的行為

Validate:通過檢驗服務描述,用以保證後續工作的正常執行

   1: public interface IServiceBehavior
2: {
3: void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters);
4: void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase);
5: void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase);
6: }

WCF為我們預定義了一系列的ServiceBehavior,其中ServiceBehaviorAttribute就是其中之一。ServiceBehaviorAttribute不僅僅是一個自定義特性(Custom Attribute),實際上它本身就是一個實現了IServiceBehavior的服務行為。

   1: [AttributeUsage(AttributeTargets.Class)]
2: public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
3: {
4: //省略成員
5: }

對於其他一些預定義服務行為,比如用於實現與ASP.NET兼容的AspNetCompatibilityRequirementsAttribute;用於進行限流控制的ServiceThrottlingBehavior;用於進行服務授權的ServiceAuthorizationBehavior等,可以通過配置的方式應用於某個WCF服務。

對於ServiceDescription來說,最重要的要數System.ServiceModel.Description.ServiceEndpointCollection類型的Endpoints屬性。該屬性表示為服務添加的所有在終結點集合,集合的每個元素為System.ServiceModel.Description.ServiceEndpoint對象,接下來我們就來著重討論ServiceEndpoint。

二、 ServiceEndpoint與EndpointBehavior

ServiceEndpoint對象是對終結點的運行時描述,終結點的三要素(ABC:Address、Binding、Contract)分別由同名的屬性表示。ListenUri和ListenUriMode表示終結點真正的監聽地址和監聽模式,Address和ListenUri由被稱為邏輯地址和物理地址(關於邏輯地址和物理地址,可以參考[原創]WCF後續之旅(15): 邏輯地址和物理地址)。

   1: public class ServiceEndpoint
2: {
3: //其他成員
4: public EndpointAddress Address { get; set; }
5: public KeyedByTypeCollection<IEndpointBehavior> Behaviors { get; }
6: public Binding Binding { get; set; }
7: public ContractDescription Contract { get; }
8: public Uri ListenUri { get; set; }
9: public ListenUriMode ListenUriMode { get; set; }
10: public string Name { get; set; }
11: }

在ServiceEndpoint中,類型為KeyedByTypeCollection<IEndpointBehavior>的Behaviors屬性表示綁定到該終結點的終結點行為(Endpoint Behavior)集合。集合的成員為實現了IEndpointBehavior接口的終結點行為對象。IEndpointBehavior的定義如下,AddBindingParameters、ApplyDispatchBehavior和Validate與IServiceBehavior同名方法語義類似。不同的是,IEndpointBehavior的所有方法的作用域僅限於當前終結點,並且IEndpointBehavior既可以作用於服務端,也可以用於客戶端。為此,增加了一個新的方法:ApplyClientBehavior。ApplyClientBehavior方法與ApplyDispatchBehavior相對,通過修改客戶端運行時(Client Runtime)的屬性,或者添加/替換客戶端運行時某些可擴展對象,進而實現控制客戶端行為的目的。

   1: public interface IEndpointBehavior
2: {
3: void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters);
4: void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime);
5: void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher);
6: void Validate(ServiceEndpoint endpoint);
7: }

終結點的契約通過ContractDescription對象表示,為了讓大家對服務描述有一個系統的認識,接下來我們繼續介紹ContractDescription。

三、ContractDescription和ContractBehavior

System.ServiceModel.Description.ContractDescription定義了以下一些屬性用於描述服務契約。由於服務契約通過System.ServiceModel.ServiceContractAttribute定義,所以大部分的屬性都和ServiceContractAttribute的屬性相匹配,在這裡就不再作重復的介紹了。

   1: public class ContractDescription
2: {
3: //其他成員
4: public KeyedByTypeCollection<IContractBehavior> Behaviors { get; }
5: public OperationDescriptionCollection Operations { get; }
6: }

在ContractDescription中,類型為KeyedByTypeCollection<IContractBehavior>的屬性Behaviors代表基於服務契約的契約行為(Contract Behavior)集合,集合成員為實現了接口IContractBehavior的契約行為對象。IContractBehavior具有與IEndpointBehavior一樣的方法成員,但是契約行為作用於實現了該服務契約的所有服務(服務端行為),基於使用該服務契約進行服務調用的服務代理(客戶端行為)。

   1: public interface IContractBehavior
2: {
3: void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters);
4: void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime);
5: void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime);
6: void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint);
7: }

ContractDescription的Operations屬性表示服務契約的所有操作的描述,類型為OperationDescriptionCollection,表示一個OperationDescription對象的集合。接下來,我們來介紹OperationDescription。

四、 OperationDescription和OperationBehavior

System.ServiceModel.Description.OperationDescription定義了一系列的屬性用以描述定義在服務契約中操作契約。由於操作契約通過System.ServiceModel.OperationContractAttribute定義,所以OperationDescription的大部分屬性與OperationContractAttribute屬性一一匹配,在這裡就不再作重復的介紹了。

   1: public class OperationDescription
2: {
3: //其他成員
4: public KeyedByTypeCollection<IOperationBehavior> Behaviors { get; }
5: }

上面我不止一次地提出客戶端操作(Client Operation)和服務端操作(Dispatch Operation)的概念,這是由於在運行時,基於相同的OperationDescription創建操作對象在客戶端和服務端是不同的,服務端操作稱為分發操作(DispatchOperation),通過類型System.ServiceModel.Dispatcher.DispatchOperation 表示,客戶端操作通過類型System.ServiceModel.Dispatcher.ClientOperation 表示。

在OperationDescription中,類型為KeyedByTypeCollection<IOperationBehavior>的Behaviors屬性表示基於操作的所有操作行為(Operation Behavior)集合,集合成員為實現了IOperationBehavior接口的類型對象。IOperationBehavior具有與IEndpointBehavior、IContractBehavior一樣的方法成員。IOperationBehavior的作用域僅限於當前的操作(客戶端操作或者服務端操作)。

   1: public interface IOperationBehavior
2: {
3: void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters);
4: void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation);
5: void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation);
6: void Validate(OperationDescription operationDescription);
7: }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved