Extending WCF clients

One of my readers asked me the other day about client(proxy) extensibility points on Windows Communication Foundation (WCF). Conceptually there a number of scenarios in which makes sense to extend proxy functionalities.

  • Custom Message Validation. A user may want to enforce that a message is valid for a certain schema. This can be done by implementing the IClientMessageInspector interface and assigning the implementation to the MessageInspectors property.
  • Custom Message Logging. A user may want to inspect and log some set of application messages that flow through an endpoint. This can also be accomplished with the message interceptor interfaces.
  • Custom Message Transformations. Rather than modifying application code, the user may want to apply certain transformations to the message in the runtime (for example, for versioning). This can be accomplished, again, with the message interceptor interfaces.
  • Custom Data Model. A user may want to have a data or serialization model other than those supported by default in WCF (namely, XmlFormatter, XmlSerializer, and raw Messages). This can be done by implementing the message formatter interfaces.
  • Custom Parameter Validation. A user may want to enforce that typed parameters are valid (as opposed to XML). This can be done using the parameter inspector interfaces.

As part of our daily interaction with customers we (TwoConnect) had developed different demos to illustrate these features.

On the WCF model there are two main client extension classes ClientRuntime and ClientOperation. Both classes are intended to extend the service proxy. However ClientRuntime extends the proxy at the contract level while ClientOperation works at operation level. In order to insert extension points in both cases you should use behaviors. Obviously ClientRuntime provides a broader set of options given that extension points can be inserted in endpoint, contract, operation or service behaviors respectively. On the other hand extension points for ClientOperation are typically represented by operation behaviors.

The following example shows how to create a custom endpoint behavior and add a custom message inspector to it.

 

public class SampleCustomBehavior: IEndpointBehavior

    {

 

        public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)

        { }

 

        public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)

        {

            //Add the inspector

            behavior.MessageInspectors.Add(new CustomMessageInspector());

        }

 

        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)

        { }

 

        public void Validate(ServiceEndpoint serviceEndpoint)

        { }

    }

 

CustomMessageInspector class declaration looks like the following

 

public class CustomMessageInspector : IClientMessageInspector

    {

        #region IClientMessageInspector Members

 

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

        {

        }

 

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)

        {

            Console.WriteLine(request.ToString());

            return null;

        }

 

        #endregion

    }

 

Finally the following code illustrates how to add the behavior to the service’s proxy

 

MyServiceClient proxy = new MyServiceClient();

proxy.Endpoint.Behaviors.Add(new SampleCustomBehavior());

 

1 Comment

  • This is excellent article. It helped me a lot.

    I have a question. Is there a way to add my custom behavior class through configuration -istead of through code?

    That will give me even more flexibility.

Comments have been disabled for this content.