Autofac - DelegatingHandler(HttpMessageHandler)注册

时间:2015-06-15 12:50:01

标签: c# asp.net-web-api asp.net-web-api2 autofac ioc-container

我在类库中有一个自定义DelegatingHandler,我需要在Autofac注册。 webapi主机解析了它对运行时的依赖性,因此主机没有对此库的引用。

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

在我的Autofac初始化程序类中,我尝试过以下内容:

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

在主机中注册此类处理程序的常规方法是:

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

但我不能在这里访问主机项目。有关如何在ContainerBuilder

上注入处理程序的任何想法

2 个答案:

答案 0 :(得分:7)

您似乎无法在Web API

中注入HttpMessageHandler
  

给定消息处理程序作为实例传递并为整个服务初始化一次。我认为让用户代码首先注入依赖项并使用http配置注册实例更容易。这允许人们编写具有构造函数但不需要依赖注入的自定义消息处理程序。目前的模型更灵活。   
  
&gt;&gt;   http://aspnetwebstack.codeplex.com/workitem/62

但是你可以创建能够做你想做的代理。例如:

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);
    }
}

并注册您的处理程序:

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

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

答案 1 :(得分:3)

这是我的后期绑定解决方案:

Global.asax中

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

辅助

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

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