11

我正在尝试连接我的 Web Api 项目以将 Castle Windsor 用于 IoC

按照这篇优秀的文章,我已经为我的控制器做到了这一点。

我现在正试图将依赖项注入我的 DelegatingHandler 和 ActionFilterAttribute

我试图复制常规 ASP.Net MVC 中用于过滤器的技术,但它们似乎不适用于 Web Api

有没有人设法让这个工作?

我不确定 Web Api 中的相关扩展点是什么

我已经看到有人建议这样做

config.MessageHandlers.Add(_myContainer.Resolve<IApiUsageLogger>());

但不确定是否有更好的方法。我更愿意利用创建这些处理程序/过滤器的机制

因为这对许多处理程序来说是服务位置的气味。是否有一个点可以创建所有处理程序?

有任何想法吗?

4

2 回答 2

15

由于该MessageHandlers集合是全局的,因此它实际上是一个单例列表。当处理程序本身没有状态和依赖项时,这很好,但在基于 SOLID 设计原则的系统中,这些处理程序很可能会有自己的依赖项,并且很可能其中一些依赖项需要一个寿命比单例短。

如果是这种情况,则不应将此类消息处理程序创建为单例,因为通常,组件的生命周期不应长于其依赖项的生命周期。

然而,Web API 缺少任何允许在每个请求上解析此类处理程序的钩子,但这种机制很容易通过使用代理类创建:

public class DelegatingHandlerProxy<TDelegatingHandler> : DelegatingHandler
    where TDelegatingHandler : DelegatingHandler
{
    private readonly WindsorContainer container;

    public DelegatingHandlerProxy(WindsorContainer container)
    {
        this.container = container;
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // trigger the creation of the scope.
        request.GetDependencyScope();

        var handler = this.container.Resolve<TDelegatingHandler>();

        handler.InnerHandler = this.InnerHandler;

        var invoker = new HttpMessageInvoker(handler);

        var response = await invoker.SendAsync(request, cancellationToken);

        container.Release(handler);

        return response;
    }
}

此代理可按如下方式使用:

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new DelegatingHandlerProxy<MyCustomHandler>(myContainer));

代理是一个单例,但它会解析MyCustomHandler每个请求中指定的。

于 2014-10-20T19:00:28.877 回答
0

到今天为止似乎没有扩展点。不过有一个请求,在http://aspnetwebstack.codeplex.com/workitem/62

于 2012-11-28T09:29:29.647 回答