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.
Overview
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.
Adding a Binding Element
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 and CanBuildChannelListener 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 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 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. 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.
Clone. Returns 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.
CreateMessageEncoderFactory. Returns a MessageEncoderFactory, which provides a handle to the actual class that implements your new encoder and which should extend MessageEncoder. For more information, see MessageEncoderFactory and MessageEncoder.
MessageVersion. Returns the MessageVersion used in this encoding, which represents the versions of SOAP and WS-Addressing in use.
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.