wcfdependency-injectionstructuremapwcf-clientendpointbehavior

WCF shared IClientMessageInspector instance across multiple clients


I'm managing a shared auth cookie when making WCF service calls via this methodology outlined under the header "Centralized cookie management" located here: http://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/

I've set up a custom IClientMessageInspector, IEndpointBehavior, BehaviorExtensionElement, the works. My endpoint behavior adds a message inspector as follows:

public class MyEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        // yuck.. Wish I had an instance of MyClientMessageInspector
        // (which has the auth cookie already) so I could just inject that
        // instance here instead of creating a new instance
        clientRuntime.MessageInspectors.Add(new MyClientMessageInspector());
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
    }
    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

It all works flawlessly, but this solution breaks down when you want to share cookies over multiple clients. Because the ApplyDispatchBehavior() method creates a new instance, any other client wouldn't get that message inspector instance, and thus, the auth ticket.

So then I thought of trying to create a custom constructor where I could inject the instance like so:

MyEndpointBehavior(MyClientMessageInspector msgInspector) { ... }

But, WCF needs parameter-less constructors. Weeding through the internets, WCF has hooks to allow for dependency injection, creating an IInstanceProvider, IServiceBehavior, etc. But I don't think that's what I'm looking for here.

Can anyone help guide me in the right direction?


Solution

  • I liked the answers provided by @carlosfigueira and @drew, but I ultimately came up with a slightly different approach. I opted to configure my IEndpointBehavior PROGRAMMATICALLY, vs via config. Made things much simpler. I changed my endpoint behavior to store my client message inspector as follows:

    public class MyEndpointBehavior : IEndpointBehavior
    {
        private MyClientMessageInspector_myClientMessageInspector;
    
        public MyClientMessageInspector MyClientMessageInspector
        {
            get
            {
                if (_myClientMessageInspector == null)
                {
                    _myClientMessageInspector = new MyClientMessageInspector();
                }
                return _myClientMessageInspector;
             }
        }
        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(MyClientMessageInspector);
        }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
        }
        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    

    Then I simply shared this behavior between clients, as follows:

    var behavior = new MyEndpointBehavior();
    client1.Endpoint.Behaviors.Add(behavior);
    client2.Endpoint.Behaviors.Add(behavior);
    

    Now both clients will share the same auth cookie.