WCF and Non-polymorphic bindings

I've been using WCF for the past few months and on the whole, I think the programming model works. I'm getting to really like the extensibility model and the whole deal seems to click rather well. One place where I feel it's a bit broken, though, is around the object model for Bindings.

 

The concept is simple – one of WCF's main selling point is having my communication channel be interchangeable, so I can replace a TCP/IP connection with HTTP or MSMQ almost seamlessly. This is translated into code by having each service have a Binding element which specifies the connection properties, and all these specific Binding objects – NetTcpBinding, NetMsmqBinding, etc – all derive from a shared Binding class.

It seems WCF sees seven layers to each binding, according to the SDK docs:

 

Layer

Options

Required

Transport Flow

TransportFlowBindingElement

No

Reliability

ReliableSessionBindingElement

No

Security

Symmetric, Asymmetric, Transport-Level

No

Shape Change

CompositeDuplexBindingElement

No

Transport Upgrades

SSL stream, Windows stream, Peer Resolver

No

Encoding

Text, Binary, MTOM, Custom

Yes

Transport

TCP, Named Pipes, HTTP, HTTPS, flavors of MSMQ, Custom

Yes

 

You would expect to have these as properties of the base Binding object – after all, if every binding has a required Encoding property, it makes sense, right?

 

Apparently this is not the case. The base Binding object contains only the most basic information – the naming information of the binding and the Timeout values, as well as shared functionality for opening and closing connections. Encoding? Security? All these are implemented individually in each binding class individually.

Not only that, but these settings are entirely incompatible – not only do I need to explicitly cast my Binding instance to a NetTcpBinding, the Security property of that object is of type NetTcpSecurity – a type that has nothing in common with, say, NetNamedPipeBinding's NetNamedPipeSecurity object. No inheritance, no shared interfaces, nothing.

 

Another example is the ReaderQuotas property, an XmlDictionaryReaderQuotas object that is defined seperately but identically in every Binding implementation. This means that I can't write code that sets the ReaderQuotas in a generic fashion, since there's no common interface or baseclass.

 

I find this very annoying. I'm trying to write a ConfigurationService component that supplies a client with the required binding information at runtime, but I find myself forced to hardcode several assumptions or else have very ugly try/catch code to explicitly see what type my Binding is and set the appropriate methods.

 

Seeing as we're in RC1, it's probably too late for this API to change. I wonder why it was developed this way. I hope the next version of WCF sees this revised.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.