The TransportBindingElement Type


Virtually the only hard rule applied to a Binding is that one of the BindingElement objects returned from CreateBindingElements must have the capability to create a transport channel factory or transport channel listener. From a theoretical perspective, this seems completely reasonable, since a messaging endpoint is of little value unless it is going to use some form of transport. Out of the necessity of this requirement, the WCF type system defines an abstract type named System.ServiceModel.Channels.TransportBindingElement. The TransportBindingElement type defines several members needed by transport channel factories and listeners only, but it derives from BindingElement.

Because the BindingElement collection is a blueprint for the channel listener and channel factory stacks, a TransportBindingElement must appear at the end of the collection returned from the CreateBindingElements method on the Binding type. Both the Binding type and the BindingContext type enforce this rule.

The TransportBindingElement is shown here:

 public abstract class TransportBindingElement : BindingElement {   protected TransportBindingElement();   protected TransportBindingElement(TransportBindingElement     elementToBeCloned);   public override T GetProperty<T>(BindingContext context) where T: class;   // does the channel add WS-Addressing info to messages   public bool ManualAddressing { get; set; }   // the size of the buffer pool   public virtual long MaxBufferPoolSize { get; set; }   // the maximum received message size   public virtual long MaxReceivedMessageSize { get; set; }   // the URI scheme   public abstract string Scheme { get; } }

The names of the MaxBufferPoolSize and MaxReceivedMessageSize properties describe their purpose. The MaxBufferPoolSize sets the maximum size of the entire buffer pool in bytes, which can consist of zero or more buffers, while the MaxReceivedMessageSize property sets the maximum size of a received message in bytes. The ManualAddress property, however, requires some explanation. By default, this property has a value of false. When this property is set to false, the channel stack can add addresses to a message before it is sent. The format of the address depends on the binding used. More specifically, it depends on the MessageVersion of the Message objects that the channel stack uses. When this property is set to true, the channel stack does not add any addresses, but instead assumes that the caller has placed the appropriate addresses in outgoing messages. This capability is quite useful in more advanced addressing scenarios intrinsic to applications that serve as a router or an intermediary between other messaging participants.

The BindingContext Type

The Binding and BindingElement objects delegate most of the work of building a channel factory stack and channel listener stack to the System.ServiceModel.Channels.BindingContext type. As mentioned earlier in this chapter, the BindingContext type provides contextual information to the BindingElement collection during the creation, testing, or querying of the channel factory stack or channel listener stack. Each BindingElement must know the next BindingElement in the collection so that a channel factory or channel listener can reference the next channel factory or channel listener in the stack. Furthermore, each BindingElement must have access to any additional information (security options, transactional options, and so on) required to build each channel factory or channel listener. To this end, the BindingContext type stores a collection of BindingElement objects, exposes methods that build the channel factory or channel listener stack in an orderly manner, and maintains a collection of additional information that a channel factory or channel listener can use during its instantiation. The BindingContext type is shown here:

 public class BindingContext {   // calls the other ctor, passing null for addresses   public BindingContext(CustomBinding binding,                         BindingParameterCollection parameters);   public BindingContext(CustomBinding binding,                         BindingParameterCollection parameters,                         Uri listenUriBaseAddress,                         String listenUriRelativeAddress,                         ListenUriMode listenUriMode);   // factory methods for building channel factory / listener stacks   public IChannelFactory<TChannel> BuildInnerChannelFactory<TChannel>();   public IChannelListener<TChannel> BuildInnerChannelListener<TChannel>()     where TChannel: class, IChannel;   // test methods   public bool CanBuildInnerChannelFactory<TChannel>();   public bool CanBuildInnerChannelListener<TChannel>()     where TChannel: class, IChannel;   // shallow copy of the BindingContext   public BindingContext Clone();   // Query mechanism   public T GetInnerProperty<T>() where T: class;   // removes the next BindingElement in the collection   // (private method shown intentionally)   private BindingElement RemoveNextElement();   // the Binding   public CustomBinding Binding { get; }   // extra information used in factory / listener creation   public BindingParameterCollection BindingParameters { get; }   // listening base address (channel listener only)   public Uri ListenUriBaseAddress { get; set; }   // listening mode (channel listener only)   public ListenUriMode ListenUriMode { get; set; }   // relative address (channel listener only)   public string ListenUriRelativeAddress { get; set; }   // the remaining binding elements   public BindingElementCollection RemainingBindingElements { get; } }

Notice that the constructor has arguments of type CustomBinding and BindingParameterCollection, as well as the listening arguments required to build a channel listener. The CustomBinding argument is a general way to reference a Binding, and the constructor uses this Binding to create a private collection of BindingElement objects. The BindingElement object collection is available via the RemainingBindingElements property. In essence, a CustomBinding object can take the shape of any other Binding derived type.

BindingContext Factory Methods

The size of the collection returned from this method monotonically decreases as the BuildInnerChannelFactory<TChannel> or BuildInnerChannelListener<TChannel> is invoked. The general implementation of the BuildInnerChannelFactory<TChannel> and BuildInnerChannelListener<TChannel> methods is shown here:

 public IChannelFactory<TChannel> BuildInnerChannelFactory<TChannel>() {   // removes the next BindingElement from the private list,   // then calls BuildChannelFactory on the removed BindingElement   // the "this" argument contains the new list of BindingElements   return this.RemoveNextElement().BuildChannelFactory<TChannel>(this); } public IChannelListener<TChannel> BuildInnerChannelListener<TChannel>()     where TChannel: class, IChannel {   // removes the next BindingElement from the private list,   // then calls BuildChannelListener on the removed BindingElement   // the "this" argument contains the new list of BindingElements   return this.RemoveNextElement().BuildChannelListener<TChannel>(this); }

The RemoveNextElement private method removes and then returns the next BindingElement from the internal list of BindingElement objects. When RemoveNextElement returns, the BuildChannelListener<TChannel> or BuildChannelFactory<TChannel> method executes on the newly removed BindingElement. Notice that this is passed to the BuildChannelListener <TChannel> and BuildChannelFactory<TChannel> methods, and this contains the shorter list of BindingElement objects.

Note 

The test methods on the BindingContext type operate much the same way-that is, they use an internal collection of BindingElement objects and consume nodes in that collection until there are no more to consume.




Inside Windows Communication Foundation
Inside Windows Communication Foundation (Pro Developer)
ISBN: 0735623066
EAN: 2147483647
Year: 2007
Pages: 106
Authors: Justin Smith

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net