Bindings represent a wide variety of functionality. Everything from different transports, to different security mechanisms, delivery mechanisms, transactions, and custom protocols. Nonetheless, there are times where you want to make a decision based on a binding’s capabilities.
For example: “Does this binding support ordered delivery?”
Or: “Does this binding support both client and server authentication?”
WCF has a polymorphic way of making such inquiries of a Binding, though there are a few subtleties involved.
The first pivot point is to decide whether the capability is a property of the actual Binding, or a property exposed by the stack of Binding Elements. For example, supporting client authentication is a property of the underlying stack. It can be added at different layers (e.g. transport, WS-Security, etc), and can even be removed by some layers. These capabilities are accessed though a method on the Binding:
T GetProperty<T>()
As in:
ISecurityCapabilities
s = binding.GetProperty<ISecurityCapabilities
>();GetProperty<T> simply constructs a Binding Context representing the stack of Binding Elements, and queries them through:
T GetProperty<T>(
BindingContext
context)Each individual Binding Element can handle the inquiry itself, delegate the inquiry, or a combination of the two. GetProperty is also supported by the runtime objects (IChannelFactory, IChannelListener, IChannel, etc).
Conversely, if a Binding claims to support Basic Profile 1.0, that is a claim about a particular coordination and configuration of binding elements. Therefore, this is not a feature to expose through T GetProperty<T>()
. The Binding should instead implement the capability directly. For example:
public class
MyBasicProfileBinding : IBasicProfile10Binding
Where IBasicProfile10Binding
is an agreed upon interface. It is queried as “if
(binding
is
IBasicProfile10Binding
)
”
Lastly, there are a handful of cases where a particular property is applicable to all bindings. In that case, we use the traditional approach of a strongly typed property on our base class. For example:
public abstract string
Scheme {
get
; }
To re-cap: for polymorphic properties, use GetProperty<T>. For capabilities of the binding element stack, and interface implementation for composite capabilities provided by the concrete binding.