Intercepting Client Calls

To intercept client-side calls, WCF provides the interface IClientMessageInspector, defined as:

public interface IClientMessageInspector
{
   object BeforeSendRequest(ref Message request,IClientChannel channel);
   void AfterReceiveReply(ref Message reply,object correlationState);
}

The BeforeSendRequest() method is called just before the message is sent down the wire, allowing you to affect the request message. Similarly, the AfterReceiveReply() method is your chance to interact with the reply message for post-call processing.

The client runtime represented by the ClientRuntime class contains a collection of message inspectors:

public sealed class ClientRuntime
{
   public SynchronizedCollection<IClientMessageInspector> MessageInspectors
   {get;}

  //More members
}

You can add your message inspector to the collection by associating the proxy with an endpoint behavior. That behavior needs to add the inspector in the ApplyClientBehavior() method:

public interface IEndpointBehavior
{
   void ApplyClientBehavior(ServiceEndpoint endpoint,ClientRuntime clientRuntime);
   //More members
}

To encapsulate these steps I wrote the class InterceptorClientBase<T>, defined in Example E-4.

Example E-4. The InterceptorClientBase<T> class

public abstract class InterceptorClientBase<T> : ClientBase<T> where T : class
{
   public InterceptorClientBase()
   {
      Endpoint.Behaviors.Add(new ClientInterceptor(this));
   }
   public InterceptorClientBase(string endpointName) : base(endpointName)
   {
      Endpoint.Behaviors.Add(new ClientInterceptor(this));
   }

   //More constructors

   protected virtual void PreInvoke(ref Message request)
   {}

   protected virtual void PostInvoke(ref Message reply)
   {}

   class ClientInterceptor : IEndpointBehavior,IClientMessageInspector
   {
      InterceptorClientBase<T> Proxy
      {get;set;}

      internal ClientInterceptor(InterceptorClientBase<T> proxy)
      {
         Proxy = proxy;
      }
      object IClientMessageInspector.BeforeSendRequest(ref Message request,
                                                       IClientChannel channel)
      {
         Proxy.PreInvoke(ref request);
         return null;
      }
      void IClientMessageInspector.AfterReceiveReply(ref Message reply,
                                                     object correlationState)
      {
         Proxy.PostInvoke(ref reply);
      }

      void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint,
                                                 ClientRuntime clientRuntime)
      {
         clientRuntime.MessageInspectors.Add(this);
      }
      //Rest of the implementation
   }
}

InterceptorClientBase<T> defines a nested private class called ClientInterceptor that implements both IEndpointBehavior and IClientMessageInspector. The constructors of InterceptorClientBase<T> add an instance of ClientInterceptor to the proxy’s collection of endpoint behaviors. Inside ClientInterceptor, the implementation of ApplyClientBehavior() adds itself to the collection of client runtime interceptors. InterceptorClientBase<T> provides two virtual methods, PreInvoke() and PostInvoke(), for the use of derived classes. The constructor of ClientInterceptor takes a back reference to the calling InterceptorClientBase<T>, and it uses that reference to call back to the PreInvoke() and PostInvoke() methods during the calls to BeforeSendRequest() and AfterReceiveReply() respectively.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.130.201