No matter how much I read about WCF in online forums and blog posts, I still couldn’t grasp the whole idea behind the extensibility model until I was able to play with it myself. What I discovered along the way is how the entire channel model works and how the binding and endpoint address fit into the equation. Although this may seem like I’m diving in details quickly, I personally find it very useful to illustrate real world scenarios to really show you the power of the API. On that note, I’d like to dive right in to how WCF generates your proxy channel for you at runtime and how the binding fits into this model. With this knowledge we will be able to create our own custom channel implementation that provides a sort of “message replay” ability in the face of connectivity issues.
The way I think about the binding class is that it is nothing more than the actual networking stack implementation. If you have any background in computer networking, you should be fully aware that the low-level TCP/IP network protocols are layered on top of each other. In this example, IP is the core transport protocol and TCP packets are simply carried as a payload. If we view this layering of protocols by analyzing the flow of packets, we find something like this:
Sender: TCP –> IP ……. Receiver: IP –> TCP
As you can see, on the way out the IP layer is the last to see the packets, and on the way in the IP layer is the first to receive the packets. In order for this system to work the two layers need to play by the rules, meaning they conform to a common set of rules and restrictions. Much in this same way, the Binding object provides the ability to layer protocols on top of one another, just at a higher level than the previous example. This provides a generic way to model a networking stack, where each layer performs some function and typically delegates further behavior to the next layer down in the stack. From a binding, you can build a IChannelFactory<TChannel> instance where TChannel is one of the built-in channel shapes (e.g. IRequestChannel, IOutputChannel, etc). Depending on how you order the binding elements in the binding, you wind up with a different layering of the channels involved.
The main purpose of the Binding object is to construct the lower level networking stack, which by itself this is not completely useful since we are still communicating with remote services at a very low level. We still need to handle formatting incoming and outgoing messages manually, which typically isn’t the most desirable thing to do. This is where the next layer of the WCF model comes in, which provides this mapping of service methods to messages and understands how to format both requests and responses to and from the remote service.
Next time we’ll take a look at the ServiceChannel object and how it uses the Binding to provide us with a usable client service.