Reflection

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

我们常说的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的方法就是在配置文件里面写一写就行了。

  <system.serviceModel>
    
<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的类,比如像下面这样:
public class MyBinding : 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; }
    }

}
所有的Binding类呢都是继承于Binding这个基类的,我们需要重写一个方法CreateBindingElements(),这个方法就是把你所需要的Binding Element放进去。这样就可以了,我们在代码中就可以这样用这个Binding了。
host.AddServiceEndpoint(typeof(IMyContract), new MyBinding(), "http://localhost:8888/MyContract");
不过可能这样你会觉得很不爽,不够灵活。当然我们也可以在配置文件中来进行配置,不过呢还需要添加两个类。
public class MyBindingElement : StandardBindingElement
{
    
protected override Type BindingElementType
    
{
        
get return typeof(MyBinding); }
    }


    
protected override void OnApplyConfiguration(Binding binding)
    
{
        
    }

}


public class MyBindingSection : StandardBindingCollectionElement<MyBinding, MyBindingElement>
{
}
MyBindingElement继承于StandardBindingElement类,主要用来就是说定义了在Binding配置结点中可以配置的元素。MyBindingSection用来在WCF配置文件中注册一个新的Binding类型。所以我们的配置文件可以这么写:
  <system.serviceModel>
    
<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>
注意到我们需要在extensions结点中注册我们新加的binding。
至此,我们新开发的Binding就可以正常使用了,当然这个新的Binding没有加入任何东西,至于如何用它,那就看你的应用程序的需求了。
posted on 2008-05-22 15:25  Reflection  阅读(860)  评论(0编辑  收藏  举报