Creating a BindingElement

 

Bindings and binding elements (objects that extend System.ServiceModel.Channels.Binding and System.ServiceModel.Channels.BindingElement, respectively) are the place where the Windows Communication Foundation (WCF) application model is associated with channel factories and channel listeners. Without bindings, using custom channels requires programming at the channel level as described in Service Channel-Level Programming and Client Channel-Level Programming. This topic discusses the minimum requirement to enable using your channel in WCF, the development of a BindingElement for your channel, and enable use from the application as described in step 4 of Developing Channels.

Creating a BindingElement for your channel enables developers to use it in an WCF application. BindingElement objects can be used from the System.ServiceModel.ServiceHost class to connect an WCF application to your channel without having to the precise type information of your channel.

Once a BindingElement has been created, you can enable more functionality depending upon your requirements by following the remaining channel development steps described in Developing Channels.

To implement a custom BindingElement, write a class that inherits from BindingElement. For example, if you have developed a ChunkingChannel that can break up large messages into chunks and reassemble them on the other end, you can use this channel in any binding by implementing a BindingElement and configuring the binding to use it. The remainder of this topic uses the ChunkingChannel as an example to demonstrate the requirements of implementing a binding element.

A ChunkingBindingElement is responsible for creating the ChunkingChannelFactory and ChunkingChannelListener. It overrides CanBuildChannelFactory<TChannel> and CanBuildChannelListener<TChannel> implementations, and checks that the type parameter is IDuplexSessionChannel (in our example this is the only channel shape supported by the ChunkingChannel) and that the other binding elements in the binding support this channel shape.

BuildChannelFactory<TChannel> first checks that the requested channel shape can be built and then gets a list of message actions to be chunked. It then creates a new ChunkingChannelFactory, passing it the inner channel factory. (If you are creating a transport binding element, that element is the last one in the binding stack and therefore must create a channel listener or channel factory.)

BuildChannelListener<TChannel> has a similar implementation for creating ChunkingChannelListener and passing it the inner channel listener.

As another example using a transport channel, the Transport: UDP sample provides the following override.

In the sample, the binding element is UdpTransportBindingElement, which derives from TransportBindingElement. It overrides the following methods to build the factories associated with the channel.

public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)  
{  
            return (IChannelFactory<TChannel>)(object)new UdpChannelFactory(this, context);  
}  
  
public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)  
{  
            return (IChannelListener<TChannel>)(object)new UdpChannelListener(this, context);  
}  

It also contains members for cloning the BindingElement and returning our scheme (soap.udp).

Protocol Binding Elements

New binding elements can replace or augment any of the included binding elements, adding new transports, encodings, or higher-level protocols. To create a new Protocol Binding Element, start by extending the BindingElement class. At a minimum, you must then implement the BindingElement.Clone and implement the ChannelProtectionRequirements using IChannel.GetProperty<T>. This returns the ChannelProtectionRequirements for this binding element. For more information, see ChannelProtectionRequirements.

Clone should return a fresh copy of this binding element. As a best practice, we recommend that binding element authors implement Clone by using a copy constructor that calls the base copy constructor, then clones any additional fields in this class.

Transport Binding Elements

To create a new Transport Binding Element, extend the TransportBindingElement interface. At a minimum, you must then implement the Clone method and the TransportBindingElement.Scheme property.

Clone – Should return a fresh copy of this Binding Element. As a best practice, we recommend that Binding Element authors implement Clone by way of a copy constructor that calls the base copy constructor, then clones any additional fields in this class.

Scheme – The Scheme get property returns the URI scheme for the transport protocol represented by the binding element. For example, the System.ServiceModel.Channels.HttpTransportBindingElement and the System.ServiceModel.Channels.TcpTransportBindingElement return “http” and “net.tcp” from their respective Scheme properties.

Encoding Binding Elements

To create new Encoding Binding Elements, start by extending the BindingElement class and implementing the System.ServiceModel.Channels.MessageEncodingBindingElement class. At a minimum, you must then implement the Clone, MessageEncodingBindingElement.CreateMessageEncoderFactory methods and the MessageEncodingBindingElement.MessageVersion property.

For a complete listing of optional methods and properties for user-defined encoding binding elements, see MessageEncodingBindingElement.

For more information on creating a new binding element, see Creating User-Defined Bindings.

Once you have created a binding element for your channel, return to the Developing Channels topic to see whether you want to add configuration file support to your binding element, if and how to add metadata publication support, and whether and how to construct a user-defined binding that uses your binding element.

BindingElement
Developing Channels
Transport: UDP

Show: