A CustomBinding defines a binding by providing a thin wrapper around a collection of binding elements. Custom bindings don't have any of the niceities of a handcrafted binding, such as properties that provide direct control over the binding elements and their settings. However, in return, a custom binding is very cheap to create and doesn't require defining a new class.

The bulk of the methods for the CustomBinding class deal with importing the binding elements for the binding.

public class CustomBinding : Binding, ISecurityCapabilities
{
public CustomBinding();
public CustomBinding(Binding binding);
public CustomBinding(IEnumerable<BindingElement> bindingElementsInTopDownChannelStackOrder);
public CustomBinding(params BindingElement[] bindingElementsInTopDownChannelStackOrder);
public CustomBinding(string configurationName);
public CustomBinding(string name, string ns, params BindingElement[] bindingElementsInTopDownChannelStackOrder);

public BindingElementCollection Elements { get; }
public override string Scheme { get; }

public override BindingElementCollection CreateBindingElements();
}

Each constructor provides a different way to specify the contents of the binding. After defining the custom binding, you can still access the binding elements for modification through the Elements collection. The CreateBindingElements method is the standard way for consuming the binding elements of the binding. In this case, calling CreateBindingElements() simply returns a collection containing your specified binding elements. However, you can't change the binding through this collection because it's only a copy of the elements that are inside.

You specify the order of binding elements in the same order that you want for your channel stack. There's a rough order that typically occurs:

  1. conversation modifiers (such as reliable messaging or transactions)
  2. message modifiers (such as message security)
  3. stream modifiers (such as transport security)
  4. the message encoder
  5. the transport

Intermixed in these binding elements can be shape changers that change the apparent structure of the underlying channels. I won't get into the topic today, but you generally want to push shape changers as far down your channel stack as you can.

Here's an example of the binding element stack using the WSDualHttpBinding:

System.ServiceModel.Channels.TransactionFlowBindingElement
System.ServiceModel.Channels.ReliableSessionBindingElement
System.ServiceModel.Channels.SymmetricSecurityBindingElement
System.ServiceModel.Channels.CompositeDuplexBindingElement
System.ServiceModel.Channels.TextMessageEncodingBindingElement
System.ServiceModel.Channels.HttpTransportBindingElement

That's two conversation modifiers, a message modifier, a shape changer, the message encoder, and finally the transport.

Next time: What Data Looks Like on an Ethernet Network