我们常说的WCF里面有ABC,那么B代表的就是Binding。那首先来大致了解一下什么是Binding。
从图上可以看出,Binding为WCF运行时建立了Channel Stack,定义了消息在传输过程中比较重要的三件事:传输、编码、协议(包括安全性、可靠性等)。其中传输和编码是必须要提供的。
从我们开发者的角度来说,Binding就是一个Binding Element的集合。Binding Element就是指的protocols、encoding、transport。微软已经给我们提供了非常多的Binding Element。那么是不是Binding就是简单将各种Element放到一起就行了呢?答案是否定的,因为在Channel Stack中还要有一定的顺序:
在Stack中,由下至上的顺序是不能改变的。先加入的Element会放到最上面。其中Transport和Encoding是每个Binding所必须的。
了解了这一点接下来就简单了,为什么WCF提供了这么多的Binding呢?像什么BasicHttpBinding、NetTcpBinding、WSHttpBinding等等。原因就是往Channel Stack中放入了不同的Binding Element,所以组合出来这么多Binding。是不是有点像搭积木?
那我们要扩展Binding就比较方便了,不用什么新的东西,只需要用WCF已有的Binding Element来组合一下就可以了。WCF已经为我们想到了这一点,所以最简单的扩展Binding的方法就是在配置文件里面写一写就行了。
<services>
<service name="MyContract" behaviorConfiguration="MEX Enabled">
<endpoint address="http://localhost:8888/MyContract"
binding="customBinding"
bindingConfiguration="myBasicHttpBinding"
contract="IMyContract"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX Enabled">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="myBasicHttpBinding">
<!-- Add Binding Element here -->
<reliableSession ordered="true"/>
<mtomMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
使用的Binding呢是CustomBinding,这个Binding是WCF提供给用户客制化的,我们可以往里面随便添加需要用到的Binding Element。
大部分的情况像这样来扩展已经足够了,当然,如果你还觉得不够的话,自己开发一个Binding也是没有问题的。
首先需要写一个Binding的类,比如像下面这样:
{
private HttpTransportBindingElement transport = new HttpTransportBindingElement();
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection collection = new BindingElementCollection();
collection.Add(new ReliableSessionBindingElement());
collection.Add(new MtomMessageEncodingBindingElement());
collection.Add(transport);
return collection.Clone();
}
public override string Scheme
{
get { return this.transport.Scheme; }
}
}
{
protected override Type BindingElementType
{
get { return typeof(MyBinding); }
}
protected override void OnApplyConfiguration(Binding binding)
{
}
}
public class MyBindingSection : StandardBindingCollectionElement<MyBinding, MyBindingElement>
{
}
<extensions>
<bindingElementExtensions>
<add name="myBindingElement" type="ServiceExt.MyBindingElement, ServiceExt"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="myBinding" type="ServiceExt.MyBindingSection, ServiceExt"/>
</bindingExtensions>
</extensions>
<services>
<service name="MyContract" behaviorConfiguration="MEX Enabled">
<endpoint address="http://localhost:8888/MyContract"
binding="myBinding"
bindingConfiguration="myBindingElement"
contract="IMyContract"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX Enabled">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<myBinding>
<binding name="myBindingElement" />
</myBinding>
</bindings>
</system.serviceModel>
至此,我们新开发的Binding就可以正常使用了,当然这个新的Binding没有加入任何东西,至于如何用它,那就看你的应用程序的需求了。