The Ties that Bind Us, Part 2: Binding

Back to the subject of bindings, a binding is what ties together the description of a channel stack.  A binding contains a collection of binding elements that correspond to protocol channels, transport channels, and message encoders.  In the binding, there can be any number of binding elements for protocol channels but one and only one binding element for each the transport and message encoder.  Actually, as I mentioned earlier, you can sometimes get away with not specifying the message encoder and instead let the transport decide the encoding for you.  But as I also mentioned earlier, you probably should just go ahead and specify the message encoder explicitly.

The definition of a binding is quite a bit more complicated than the classes we've been looking at so far.

 public abstract class Binding : IDefaultCommunicationTimeouts
{
   protected Binding();
   protected Binding(string name, string ns);

   public TimeSpan CloseTimeout { get; set; }
   public string Name { get; set; }
   public string Namespace { get; set; }
   public TimeSpan OpenTimeout { get; set; }
   public TimeSpan ReceiveTimeout { get; set; }
   public abstract string Scheme { get; }
   public TimeSpan SendTimeout { get; set; }

   public virtual IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingParameterCollection parameters);
   public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(params object[] parameters);
   public virtual bool CanBuildChannelFactory<TChannel>(BindingParameterCollection parameters);
   public bool CanBuildChannelFactory<TChannel>(params object[] parameters);
   public abstract BindingElementCollection CreateBindingElements();
   public T GetProperty<T>(BindingParameterCollection parameters) where T : class;
}

I've talked about timeouts in the past and I'll talk about them again in the future, but for now, timeouts don't matter because we aren't actually sending data or making connections at this point.  Instead, I want to draw your attention to the Name, Namespace, and Scheme properties.  We've split the specification of the user name for the binding apart from the specification of the protocol name.  If you want to add more HTTP bindings, you can name them whatever you want and set all of their schemes to "http".  There's no inherent application or machine dispatch based on scheme, which means you avoid the common problem of being unable to register additional handlers for well-known protocols.  You can also work with multiple versions of a binding side-by-side easily by giving each version a different name.

We've seen the BuildChannelFactory, CanBuildChannelFactory, and GetProperty methods before in binding elements.  The parameters are different because we haven't built a binding context at this point.  That happens during the handoff from binding to binding element.  The only new method is CreateBindingElements which generates the binding elements for this binding.  You probably guessed that from the name.  Changing one collection of binding elements should not affect other users of the binding, so this collection is typically cloned off of a master copy.

We're making fast progress towards covering the basics of the channel model.  What's left is mostly looking at channels themselves and how to build them.

Next time: And Starring IChannel