- WCF技術剖析(卷1)
- 蔣金楠
- 1390字
- 2018-12-27 11:32:53
3.5.1 綁定元素(Binding Element)
綁定元素,顧名思義就是構成一個綁定對象的元素。綁定對象最根本的目的就是創建信道棧,借此實現對消息的傳輸、編碼和其他消息處理功能,比如安全、可靠傳輸、事務流轉等。組成信道棧的單個信道對象基于對某項單一消息處理功能的實現,在不同環境中,可以按照具體的需求選擇所需的信道,并根據一定的順序對其重組。一般來說,綁定元素的組合方式,決定了綁定對象最終創建的信道棧。綁定元素的重組決定了信道的重組。
關于綁定元素
一個綁定對象由一系列綁定元素組成,一般來講,每個綁定元素負責創建相應的信道。所以綁定元素集合的構成及它們之間的先后順序,決定了最終生成的信道棧中的信道組成,以及它們位于棧中的先后順序。WCF之所以在設計的時候將綁定和綁定元素分離開發,是基于靈活性、可擴展性考慮的。
我們不可能、也沒有必要創建一個萬能的信道以提供消息交換中的所有功能,所以我們讓一個信道只承載某個單一的功能,比如傳輸信道專注于網絡傳輸,壓縮信道專注于消息的壓縮和解壓縮。WCF還定義了一系列的信道,它們分別專注于安全、可靠傳輸和事務流轉等。這種信道組合的設計方式使得我們可以根據具體的需求來定制將要創建的信道棧,讓它只保留必需的功能,去除不必要的功能。
同理,我們可以根據具體實際需求,將必要的綁定元素進行有序的重組,從而創建最能適合具體通信場景的綁定。由于信道可以分為必須的傳輸信道、消息編碼信道和可選的基于某種WS-*協議實現的協議信道,與之相對,綁定元素可以分為傳輸綁定元素、消息編碼綁定元素和協議綁定元素。
注: 并非所有綁定元素都會從事信道的創建。實際上WCF中并不存在消息編碼信道,消息編碼綁定元素,僅僅是傳遞一些編碼相關的綁定參數給綁定上下文,以便傳輸綁定元素選擇相應的消息編碼方式。在第6章會對編碼的實現進行詳細的介紹,在這里主要是對整個綁定模型進行介紹,所以還是采用了“編碼信道”這一說法。
綁定元素的最根本功能就是實現對信道監聽器和信道工廠的創建。這可以從所有綁定元素的基類, System.ServiceModel.Channels.BindingElement的定義上看出來。
public abstract class BindingElement { protected BindingElement(); protected BindingElement(BindingElement elementToBeCloned); public virtual IChannelFactory<TChannel> BuildChannelFactory<TChannel> (BindingContext context); public virtual IChannelListener<TChannel> BuildChannelListener<TChannel> (BindingContext context) where TChannel : class, IChannel; public virtual bool CanBuildChannelFactory<TChannel>(BindingContext context); public virtual bool CanBuildChannelListener<TChannel>(BindingContext context) where TChannel : class, IChannel; public abstract BindingElement Clone(); public abstract T GetProperty<T>(BindingContext context) where T : class; }
BindingElement的核心方法成員有兩個:BuildChannelListener<TChannel>和Build-ChannelFactory<TChannel>,用于創建相應的信道監聽器和信道工廠。兩個Build方法的參數都是BindingContext。而CanBuildChannelFactory<TChannel>和CanBuildChannel- Listener<TChannel>則屬于兩個測試性質的方法,用于檢驗相應的信道監聽器和信道功能是否可以被創建。
案例演示:如何自定義綁定元素
在上面的案例中,我們自定義了兩種類型的信道管理器:數據報信道管理器和會話信道信道管理器,它們又包含各自的信道監聽器和信道工廠。在這里須要為它們分別創建綁定元素。
1.創建數據報綁定元素
針對上面創建的兩個數據報信道管理器:SimpleDatagramChannelFactory和SimpleDatagramChannelListener,創建了相應綁定元素SimpleDatagramBindingElement。SimpleDatagramChannelFactory和SimpleDatagramChannelListener的創建分別實現在兩個被重寫的方法:BuildChannelFactory<TChannel>和BuildChannelListener<TChannel>中。此外還重寫了兩個額外的方法:Clone和GetProperty<T>,前者用于克隆一個新的綁定元素,后一個和定義在信道、信道管理器的同名方法一樣,用于獲取基于某種類型的屬性。
public class SimpleDatagramBindingElement : BindingElement {
public SimpleDatagramBindingElement() { PrintHelper.Print(this, "SimpleDatagramBindingElement"); } public override BindingElement Clone() { PrintHelper.Print(this, "Clone"); return new SimpleDatagramBindingElement(); } public override T GetProperty<T>(BindingContext context) { PrintHelper.Print(this, string.Format("GetProperty<{0}>", typeof(T) .Name)); return context.GetInnerProperty<T>(); } public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (BindingContext context) { PrintHelper.Print(this, "BuildChannelFactory<TChannel>"); return new SimpleDatagramChannelFactory<TChannel>(context) as IChannelFactory<TChannel>; } public override IChannelListener<TChannel> BuildChannelListener <TChannel>(BindingContext context) { PrintHelper.Print(this, "BuildChannelListener<TChannel>"); return new SimpleDatagramChannelListener<TChannel>(context) as IChannelListener<TChannel>; } }
2.創建會話綁定元素
按照與創建SimpleDatagramBindingElement相同的方式,為先前創建的會話信道管理器(SimpleSessionChannelListener和SimpleSessionChannelFactory)建立相應的綁定元素:SimpleSessionBindingElement。
using System.ServiceModel.Channels; namespace Artech.CustomChannels { public class SimpleSessionBindingElement : BindingElement { public override BindingElement Clone() { return new SimpleSessionBindingElement(); } public override T GetProperty<T>(BindingContext context) { return context.GetInnerProperty<T>(); } public override IChannelFactory<TChannel> BuildChannelFactory <TChannel>(BindingContext context) { PrintHelper.Print(this, "BuildChannelFactory<TChannel>"); return new SimpleSessionChannelFactory<TChannel>(context) as IChannelFactory<TChannel>; } public override IChannelListener<TChannel> BuildChannelListener <TChannel>(BindingContext context) { PrintHelper.Print(this, "BuildChannelListener<TChannel>"); return new SimpleSessionChannelListener<TChannel>(context) as IChannelListener<TChannel>; } } }
- Getting Started with Citrix XenApp? 7.6
- C語言程序設計(第3版)
- SpringMVC+MyBatis快速開發與項目實戰
- 算法零基礎一本通(Python版)
- Mastering Julia
- Getting Started with Python Data Analysis
- Tableau 10 Bootcamp
- JSP程序設計與案例實戰(慕課版)
- UML軟件建模
- C語言程序設計實踐
- 基于GPU加速的計算機視覺編程:使用OpenCV和CUDA實時處理復雜圖像數據
- Robot Framework Test Automation
- SQL Server on Linux
- 前端架構設計
- 城市信息模型平臺頂層設計與實踐