Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac - DelegatingHandler (HttpMessageHandler) Registration

I have a custom DelegatingHandler in a class library that I need to register with Autofac. The webapi host resolves it's dependencies on runtime, so the host has no references to this library.

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

On my Autofac initializer class I've tried things like:

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

The normal way to register such handlers within the host would be:

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 how to inject the handler over the ContainerBuilder?

like image 584
endeffects Avatar asked Dec 20 '22 03:12

endeffects


1 Answers

It seems that you can't inject HttpMessageHandler in Web API

Given the message handler is passed as instance and being initialized once for the entire service. I think it is easier to have user code inject the dependency themselves first and register the instance with http configuration. This allow people to write custom message handler that has constructor but do not need dependency injection as well. The current model is more flexible.

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

But you can create 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());
like image 125
Cyril Durand Avatar answered Dec 29 '22 12:12

Cyril Durand