Autofac - DelegatingHandler (HttpMessageHandler) Registration

I have a custom one DelegatingHandler

in a class library that I need to register with Autofac

. The webapi host solves its runtime dependencies, so the host has no references to this library.

public class LocalizationHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken )
    {}
}

      

In my Autofac initializer class, I've tried things like:

protected override void Load( ContainerBuilder builder )
{
     builder.RegisterType<LocalizationHandler>();
     builder.Register(c => new LocalizationHandler());
}

      

The usual way to register such handlers inside the host is:

public static void Register(HttpConfiguration httpConfiguration)
{        
    httpConfiguration.MapHttpAttributeRoutes();          
    httpConfiguration.MessageHandlers.Add(new LocalizationHandler());
}

      

But I don't have access to the host project here. Any ideas on how to inject the handler over ContainerBuilder

?

+3


source to share


2 answers


Here is my solution for late binding:

Global.asax

protected void Application_Start()
{
    List<DelegatingHandler> messageHandlers = GlobalConfiguration.Configuration.DependencyResolver.GetMessageHandlers();
    messageHandlers.ForEach(GlobalConfiguration.Configuration.MessageHandlers.Add);
}

      

Assistant



public static class DependencyHelper
{
    public static List<DelegatingHandler> GetMessageHandlers(this IDependencyResolver dependencyResolver)
    {
        return dependencyResolver.GetServices(typeof (DelegatingHandler)).Cast<DelegatingHandler>().ToList();
    }
}

      

Library

protected override void Load(ContainerBuilder builder)
{
    builder.RegisterType<GlobalLocalizationHandler>().As<DelegatingHandler>();
}

      

0


source


It seems that you cannot type HttpMessageHandler

into the web API

Considering the message handler is passed as an instance and initialized once for the entire service. I think it is easier for custom code to inject its dependency first and register an instance with http config. This allows people to write their own constructor message handler, but doesn't need dependency injection. The current model is more flexible.


http://aspnetwebstack.codeplex.com/workitem/62

But you can create a proxy that will do what you want. For example:



public class ProxyDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        IEnumerable<DelegatingHandler> innerHandlers = 
            request.GetDependencyScope()
                   .GetServices(typeof(DelegatingHandler))
                   .OfType<DelegatingHandler>();

        HttpMessageHandler handler = this.InnerHandler;
        foreach (DelegatingHandler innerHandler in innerHandlers)
        {
            innerHandler.InnerHandler = handler;
            handler = innerHandler;
        }

        HttpMessageInvoker invoker = new HttpMessageInvoker(handler, false);
        return invoker.SendAsync(request, cancellationToken);
    }
}

      

And register your handlers like this:

        builder.RegisterType<X1Handler>().As<DelegatingHandler>().InstancePerRequest();
        builder.RegisterType<X2Handler>().As<DelegatingHandler>().InstancePerRequest();

        config.MessageHandlers.Add(new ProxyDelegatingHandler());

      

+6


source







All Articles