二、绑定元素
每一个类型的绑定最重要的就是绑定元素了,每个绑定的功能特性都由绑定元素决定。BasicHttpBinding由用于编码的TextMessageEncodingBindingElement和用于httpp协议传输的HttpTransportBindingElement 构成。
NetTcpBinding由下列绑定元素组成,可以看出NetTcpBinding支持事务、二进制编码、信道安全、底层使用Tcp协议传输。
TransactionFlowBindingElement
BinaryMessageEncodingBindingElement
WindowsStreamSecurityBindingElement
TcpTransportBindingElement
可以通绑定的CreateBindingElements方法获取当前绑定元素。
WSHttpBinding bind = new WSHttpBinding(); foreach (var ele in bind.CreateBindingElements()) { Console.WriteLine("{0}", ele.GetType().Name); }
整个绑定模型可以由下面这张图表示:
绑定元素能够创建信道管理器,再由信道管理器创建信道。信道管理器就是前面说到的信道监听器、信道工厂的简称,因为它们都继承自ChannelManagerBase。信道位于最底层,提供对消息的某种功能处理,对消息进行编码、传输是最基本的两种信道。
三、创建自定义信道
myChannelBase,继承信道基类ChannelBase,由一个InnerChannel表示下一个信道。所以方法都是简单输出当前类的名称,并调用下一个信道的方法来实现,本信道是打酱油的,只为看出后续绑定执行流程。
class myChannelBase:ChannelBase { public ChannelBase InnerChannel { get; private set; } public myChannelBase(ChannelManagerBase channelManager, ChannelBase InnerChannel) : base(channelManager) { this.InnerChannel = InnerChannel; } public override T GetProperty<T>() { print("GetProperty<T>"); return InnerChannel.GetProperty<T>(); } protected void print(string methodname) { Console.WriteLine("{0}:{1}", this.GetType().Name, methodname); } protected override void OnAbort() { print("OnAbort"); InnerChannel.Abort(); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { print("OnBeginClose"); return InnerChannel.BeginClose(timeout, callback, state); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { print("OnBeginOpen"); return InnerChannel.BeginOpen(timeout, callback, state); } protected override void OnClose(TimeSpan timeout) { print("OnClose"); InnerChannel.Close(timeout); } protected override void OnEndClose(IAsyncResult result) { print("OnEndClose"); InnerChannel.EndClose(result); } protected override void OnEndOpen(IAsyncResult result) { print("OnEndOpen"); InnerChannel.EndOpen(result); } protected override void OnOpen(TimeSpan timeout) { print("OnOpen"); InnerChannel.Open(timeout); } }