Monday, January 21, 2008

The basics of the WCF stack

During CodeMash I did two "Ask the Experts" sessions where it was my intention to talk about WCF, which I've really been "geeking-out" on for several months. In the combined two hours that I "served" I only had one person come in with an issue, and it was really more of a complaint about why he couldn't use WCF.

I spoke to him for a few minutes and while his communication needs were not exactly run of the mill, they certainly weren't outside of the scope of WCF, given a few extension to the stack with a custom behavior or a custom channel.

After talking to him and a few other people I came to a realization; while there are many people who are using WCF, the vast majority of them don't really know how powerful it is. Most people seem to be content using the out of the box features of creating the normal endpoints. And granted, for 90% of the situations you face those may be fine.

But WCF offers a lot more. It is a open and extendable architecture, and with a little knowledge of the stack, what piece does what and how to extend those pieces, you can have almost unlimited power over the universe!

OK, I'm exaggerating a little. But you can still do some pretty cool stuff!

Lets review the WCF stack. This will provide the foundation for subsequent posts about extending WCF.

Basic WCF Stack

As you can see from the diagram there are a lot of pieces of functionality between your service code and the client. In actuality the client side of the stack also consists of dispatchers, at least one binding, a channel stack and a transport as well. To keep this diagram simple I've aggregated those down to the proxy object that developers use everyday with WCF but keep in mind that these things exist on the client side and the ability to customize WCF extends to that side as well (There are a few things you have to keep in mind with that, more in another post)

When a client makes a call to your service, it invokes a method on the proxy. A transport carries the message across a network to the transport on the service side. Between the transport  and the binding element is the channel stack. For an incoming message, each channel on the stack has a channel listener that receives the message from the previous channel (or in the case of the first channel in the stack, the transport) and creates your custom channel object. The custom channel then performs some action, which may or may not be based on the message, and passes it on to the next channel listener in the stack (or the binding element if it's the last channel in the stack).

This binding/channel/transport stack is what is know to most WCF developers as and endpoint. When you create an endpoint for your WCF service you are selecting a binding/channel/transport stack to for your service to use to communicate with the world. Your service can support as many endpoints as you wish, each with a unique and independent binding/channel/transport stack.

The binding hands the message off to a series of dispatchers. I'll get into these in more details when I discuss custom behaviors, but the three dispatchers that the message passes through in it's way to your service code are the channel dispatcher, the endpoint dispatcher and finally the operation dispatcher. At each one of these dispatchers, behaviors have an opportunity to be invoked. As I'll demonstrate in a future post, while custom channels are responsible for controlling how your service communicates with external applications, behaviors influence how messages are communicated internally to your service.

The response from your service back the client is essentially the reverse of the path the request just took; the response is passed through the dispatchers (this time operation, then endpoint and then channel) to the binding. The binding passes the message to the channel stack, however this time the channel listeners have been replaced with channel factories. The transport passes the message to the network where the it is returned to the client via the proxy.

With all these steps it's clear to see that there are several opportunities for customization. The ability to create these extensions give WCF it's power to allow unlimited ability to tailor how users consume your service and gives a great amount of flexibility that allows systems on disparate technologies to communicate with each other without having to worry about it at the service layer.

Up next, custom behaviors...

1 comment:

Anonymous said...

You said: "The binding hands the message off to a series of dispatchers."

Actually, a casual inspection of BasicHttpBinding shows that it has no mechanism for handling Message instances at all (look at its public interface, and its base class). Indeed, a Binding is not even part of a stack. Rather, a Binding is simply instrumental in creating a channel stack.

I wish there was documentation on the internet of exactly how dispatchers are invoked, and by what?