在第1章中,最有價值的內容應該是本章的圖1-4,如下所示:
圖中給WCF使用者展示了如何根據不同的情境選擇合適的綁定。書中描述如下:
“首先需要叩問自己服務是否需要與非WCF的用戶端互動。如果是,同時用戶端又是舊的MSMQ用戶端,選擇MsmqIntegrationBinding綁定就能夠使得服務通過MSMQ與該用戶端實現互操作。如果服務需要與非WCF用戶端互動,並且該用戶端期望調用基本的Web服務合約(ASMX Web服務),那麼選擇BasicHttpBinding綁定就能夠類比ASMX Web服務(即WSI-Basic Profile)公開WCF服務。缺點是我們無法使用大多數最新的WS-*協議的優勢。但是,如果非WCF用戶端能夠識別這些標準,就應該選擇其中一種WS綁定,例如WSHttpBinding、WSFederationBinding或者WSDualHttpBinding。如果假定用戶端為WCF用戶端,同時需要支援離線或斷開狀態下的互動,則可以選擇NetMsmqBinding使用MSMQ傳輸訊息。如果用戶端需要聯機通訊,但是需要跨機器邊界調用,則應該選擇NetTcpBinding通過TCP協議進行通訊。如果相同機器上的用戶端同時又是服務,選擇NetNamePipeBinding使用具名管道可以使效能達到最佳化。如果基於額外的標準,例如回調(選擇WSDualHttpBinding)或者聯邦安全(選擇WSFederationBinding),則應對選擇的綁定進行微調。”
“即使超出了使用的目標情境,大多數綁定工作仍然良好。例如,我們可以使用TCP綁定實現相同機器甚至進程內的通訊;我們也可以使用基本綁定實現Intranet中WCF對WCF的通訊。然而,我們還是應盡量按照圖1-4選擇綁定。”
第1章作為WCF基礎的整體介紹,不可避免要介紹WCF的體系架構,書中的描述如下:
“WCF提供了對可靠性、事務性、並發管理、安全性以及執行個體啟用等技術的有力支援,它們均依賴於基於攔截機制的WCF體系架構。通過代理與用戶端的互動意味著WCF總是處於服務與用戶端之間,攔截所有的調用,執行調用前和調用後的處理。當代理將調用棧幀(Stack Frame)序列化到訊息中,並將訊息通過通道鏈向下傳遞時,WCF就開始執行攔截。通道相當於一個攔截器,目的在於執行一個特定的任務。每個用戶端通道都會執行訊息的調用前處理。鏈的組成與結構主要依賴於綁定。例如,一個通道對訊息編碼(二進位格式、文字格式設定或者MTOM),另一個通道傳遞安全的調用上下文;還有一個通道傳播用戶端的事務,一個通道管理可靠會話,另一個通道對訊息本文(Message Body)加密(如果進行了配置),諸如此類。用戶端的最後一個通道是傳輸通道,根據配置的傳輸方式發送訊息給宿主。”
“在宿主端,訊息同樣通過通道鏈進行傳輸,它會對訊息執行宿主端的調用前處理。宿主端的第一個通道是傳輸通道,接收傳輸過來的訊息。隨後的通道執行不同的任務,例如訊息本文的解密、訊息的解碼、參與傳播事務、設定安全準則、管理會話、啟用服務執行個體。宿主端的最後一個通道負責將訊息傳遞給分發器(Dispatcher)。分發器將訊息轉換到一個棧幀,並調用服務執行個體。執行順序1-11所示。”
書中的圖1-11如下所示:
“服務並不知道它是否被本地用戶端調用。事實上,服務會被本地用戶端——分發器調用。用戶端與服務端的攔截器確保了它們能夠獲得運行時環境,以便於它們執行正確的操作。服務執行個體會執行調用,然後將控制權(Control)返回給分發器。分發器負責將傳回值以及錯誤資訊(如果存在)轉換為一條返回訊息。分發器獲得控制權,執行的過程則剛好相反:分發器通過宿主端通道傳遞訊息,執行調用後的處理,例如管理事務、停用執行個體、回複訊息的編碼與加密等。為了執行用戶端調用後的處理,包括解密、解碼、提交或取消事務等任務,傳輸通道會將返回訊息發送到用戶端通道。最後一個通道將訊息傳遞給代理。代理將返回訊息轉化到棧幀,然後將控制權返回給用戶端。”
“特別值得注意的是,體系架構中的所有要點均與可擴充性息息相關。我們可以為專有互動定製通道,為執行個體管理定製行為,以及定製安全行為等。事實上,WCF提供的標準功能都能夠通過相同的可擴充模式實現。”
通過WCF實現SOA的一個關鍵問題是,如何將與技術無關的服務轉換為CLR。一旦提供了這種轉換,WCF的服務設計者與開發人員就可以根據自己擁有的CLR的知識,進行WCF面向服務開發。為兩者搭建橋樑的是宿主。一個宿主可以包含多個上下文,而在上下文中則可以包含服務執行個體。特殊的,宿主的上下文也可以為空白。如所示:
用戶端若要調用服務,可以採用代理或通道的方式。這兩種方式在很多資料上已經有了詳盡的介紹。在這裡,我不準備重複。如果需要詳細瞭解甚至掌握著兩種方式,當然可以購買Programming WCF Services一書一探究竟。這裡我想介紹的是本書中頻繁使用的一種簡化WCF類庫的一個樣本,主要是引入泛型來簡化以及各種步驟地自動化處理。例如ServiceHost<T>類,就是通過引入泛型簡化了WCF提供的ServiceHost類:
public class ServiceHost<T> : ServiceHost
{
public ServiceHost( ) : base(typeof(T))
{}
public ServiceHost(params string[] baseAddresses) :
base(typeof(T),Convert(baseAddresses))
{}
public ServiceHost(params Uri[] baseAddresses) :
base(typeof(T),baseAddresses)
{}
static Uri[] Convert(string[] baseAddresses)
{
Converter<string,Uri> convert = delegate(string address)
{
return new Uri(address);
};
return Array.ConvertAll(baseAddresses,convert);
}
}
如果是使用ServiceHost類,則託管服務的代碼如下所示:
public static void Main( )
{
Uri baseAddress = new Uri("http://localhost:8000/");
ServiceHost host = new ServiceHost(typeof(MyService),baseAddress);
host.Open( );
//Can do blocking calls:
Application.Run(new MyForm( ));
host.Close( );
}
使用ServiceHost類,則可修改為:
public static void Main( )
{
Uri baseAddress = new Uri("http://localhost:8000/");
ServiceHost<MyService> host = new ServiceHost<MyService>(baseAddress);
host.Open( );
//Can do blocking calls:
Application.Run(new MyForm( ));
host.Close( );
}
在ServiceHost<T>類的實現中,使用了.NET 2.0中才引入的一個方法Array.ConvertAll(),它的方法簽名為:
public static TOutput[] ConvertAll<TInput,TOutput> (
TInput[] array,
Converter<TInput,TOutput> converter
)
它能夠根據Converter對象將一種類型的數群組轉換為另一種類型的數組。
本書中,還使用了很多.NET的進階特性,特別是一些在.NET 2.0才引入的技術。所以作者在本書的前言中寫到:“本書大量使用了.NET 2.0技術,從某種角度來說,本書也可以算是一本進階的C#技術書籍。”