2011-03-24 11 views
5

Me gustaría disparar un evento cada vez que llamo a un servicio WCF.Cómo activar un evento (lado del cliente) cuando llamo a un servicio WCF

He intentado lo siguiente:

var factory = new ChannelFactory<TService>(binding, endPointAdress); 

factory.Credentials.UserName.UserName = username; 
factory.Credentials.UserName.Password = password; 

var proxy = factory.CreateChannel(); 

((IContextChannel)this.Proxy).Opened += new EventHandler(FactoryOpeningEventHandler); 
this.Factory.Opened += new EventHandler(FactoryOpeningEventHandler); 

El problema con lo anterior es que el evento sólo se llama cuando se abre el proxy, pero yo quiero para disparar el evento cuando se realiza una llamada a través de este proxy, no solo cuando se abre. Sé que no hay ningún evento para IContextChannel que pueda hacer lo que quiero, por lo que me gustaría tener una solución alternativa.

Respuesta

6

Comienza creando una clase de inspector que implementa las interfaces IDispatchMessageInspector (cuando se envía) y IClientMessageInspector (cuando se reciben).

public class SendReceiveInspector : IDispatchMessageInspector, IClientMessageInspector 
{ 

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     // TODO: Fire your event here if needed 
     return null; 
    } 
    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     // TODO: Fire your event here if needed 
    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     // TODO: Fire your event here if needed 
    } 

    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     // TODO: Fire your event here if needed 
     return null; 
    } 
} 

Después de tener su clase de inspector, debe registrarla mediante un comportamiento.

public class SendReceiveBehavior : IEndpointBehavior, IServiceBehavior 
{ 
    void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
     clientRuntime.MessageInspectors.Add(new SendReceiveInspector()); 
    } 

    void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
    { 
     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new SendReceiveInspector()); 
    } 

    void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 
     // Leave empty 
    } 

    void IEndpointBehavior.Validate(ServiceEndpoint endpoint) 
    { 
     // Leave empty 
    } 

    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription desc, ServiceHostBase host) 
    { 
     foreach (ChannelDispatcher cDispatcher in host.ChannelDispatchers) 
     { 
      foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints) 
      { 
       eDispatcher.DispatchRuntime.MessageInspectors.Add(new SendReceiveInspector()); 
      } 
     } 
    } 

    void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
    { 
     // Leave empty 
    } 

    void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     // Leave empty 
    } 
} 

Por último, hay que registrarse que el comportamiento a su descripción del servicio:

host.Description.Behaviors.Add(new SendReceiveBehavior()); 
foreach (ServiceEndpoint se in host.Description.Endpoints) 
    se.Behaviors.Add(new SendReceiveBehavior()); 

Usted puede aprender más acerca de la ampliación de WCF en http://msdn.microsoft.com/en-us/magazine/cc163302.aspx

Cuestiones relacionadas