I am currently working on building a hybrid WCF binding. I want to build a custom binding to address a common problem domain that no existing bindings out-of-the-box address directly. As you will see, this is by no means a limitation of WCF, in fact, it is with WCF that I am actually creating the custom binding.
Specifically, I want a binding that will allow me to host a service in IIS so that I can take advantage of the IIS hosting model which will immediately provide message activation and a robust transport security platform essentially for free. In addition, I might have a network topology between endpoints such that firewalls will be involved so I might want to use port 80 to allay any concerns by the router cops. I also want to take advantage of reliable messaging using the WS-Reliable Messaging specification so that I can get delivery assurance between endpoints as well as the ability to flow transactions from endpoint to endpoint using WS-Atomic Transactions.
Last but not least, I want to take advantage of the binary encoder that is used by default in the NetTCPBinding so that message payloads are compact and optimized.
I am calling this binding NeuNetHttpBinding because I want to combine the best of both worlds that the NetTcpBinding and WSHttpBinding provide.
So what's the "Neu" for? Well, the good guys at Neudesic sign my paycheck so it is only natural to give them props for letting me have so much fun and still get paid for it!
Now that you understand the heritage of the binnding, let's talk about how I might accomplish this.
Creating a custom binding can be done in one of two ways. The first is using straight configuration, and the second requires working for a living and writing some code!
I am a big fan of the fantastic way in which WCF seperates the service implementation from hosting details and this approach definetely has its place in most scenarios. In this scenario, however, I don't want to give an adminstrator this ginormous configuration file that needs to be duplicated across several services. I also don't want them to have to worry about all the configuration switches to get things just right, and I especially don't want them twiddling knobs that will only break the service model.
Regardless of the approach taken, there are some canonical rules that must be followed in building a custom binding in accordance to the layers that make up each and every binding.
Below is a table that summarizes each layer, the binding element or property that represents each layer and whether each layer is required:
Layer
|
Options
|
Required
|
Transaction Flow
|
TransactionFlowBindingElement
|
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, MSMQ, Custom
|
Yes
|
As you can see, the only two layers that are required for a binding are transport and encoding. You will also notice that there is a layer dedicated to Security, Reliability and Transactions.
You can really think of bindings as nothing more than a configuration store that is read by the service model at runtime. The binding is actually interpreted at runtime and the appropriate channel factory and channel listeners are created on the client and service respectively and these channels are what make the magic between the endpoints happen.
More to come...