WCF offers
immensely valuable support for reliability, transactions, concurrency
management, security, and instance activation, all of which rely on the WCF
interception-based architecture. Having the client interact with a proxy means
that WCF is always present between the service and the client, intercepting the
call and performing pre-call and post-call processing.The interception starts
when the proxy serializes the call stack frame to a message and sends the
message down a chain of channels. The channel is merely an interceptor
whose purpose is to perform a specific task. Each client-side channel does
pre-call processing of the message. The exact structure and composition of the
chain depend mostly on the binding. For example, one of the channels may be
responsible for encoding the message (binary, text, or MTOM), another for
passing the security call context, another for propagating the client
transaction, another for managing the reliable session, another for encrypting
the message body (if so configured), and so on. The last channel on the client side
is the transport channel, which sends the message over the configured transport
to the host.
On the host
side, the message goes through another chain of channels that perform host-side
pre-call processing of the message. The first channel on the host side is the
transport channel, which receives the message from the transport. Subsequent
channels perform various tasks, such as decryption of the message body,
decoding of the message, joining the propagated transaction, setting the
security principal, managing the session, and activating the service instance.
The last channel on the host side passes the message to the dispatcher. The
dispatcher converts the message to a stack frame and calls the service
instance.
This sequence is depicted in Figure 1
The service has
no way of knowing that it was not called by a local client. In fact, it was called
by a local client—the dispatcher. The interception both on the client and the
service sides ensures that the client and the service get the runtime
environments they require to operate properly.
The service
instance executes the call and returns control to the dispatcher, which then converts
the returned values and error information (if any) into a return message. The process
is then reversed: the dispatcher passes the message through the host-side channels
to perform post-call processing, such as managing the transaction, deactivating
the instance, encoding the reply, encrypting it, and so on. The returned
message then goes to the transport channel, which sends it to the client-side
channels for clientside post-call processing. This process in turn consists of
tasks such as decryption, decoding, committing or aborting the transaction, and
so on. The last channel passes the message to the proxy, which converts the
returned message to a stack frame and returns control to the client.