WebApi,Autofac,System.Web.Http.Filters.ActionFilterAttribute每个请求的实例

我们已经在我们的应用程序(现在的MVC 4)中使用了Autofac很长一段时间,我们在基本控制器上有很多属性,一切都是inheritance的,并且一切正常,所以当请求开始时我们的服务被创建然后通过所有属性和控制器操作。

我们现在正在查看WebApi并创建了我们的WebApi控制器,并使用HTTP命名空间中的ActionFilterAttribute在基本控制器上创建了一个属性。 但是问题从这里开始,在属性上的属性上注入的服务与ApiController上的服务不同。 查看下面的链接,这似乎是已知的ASP.NET Web API和请求范围中的依赖项

然而,这里的解决方案并不理想,因为我们不希望我们的控制器知道dependency injection,我们只想使用我们注入属性的服务并知道它是每个请求一个实例。

我们称之为:

builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration); 

  GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

我们的课程目前在Autofac注册为InstancePerLifetimeScope,我们想要的是能够为MvcControllers和ApiControllers提供每个请求。

那可能吗?

编辑:

所以基本上这行为请求返回正确的服务(即同样在ApiController上的实例)

 var service = actionContext.Request.GetDependencyScope().GetService(typeof(IOurService); 

但是ActionFilterAttribute上的属性注入实例是不一样的,如果我将Autofac注册更改为InstancePerApiRequest,我会收到以下错误:

“从请求实例的范围中看不到具有匹配’AutofacWebRequest’的标记的范围。这通常表示SingleInstance()组件(或类似方案)正在请求按HTTP请求注册的组件。在Web集成下,总是从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖,永远不要从容器本身请求。“

这是Web API中的已知问题和设计问题。 首次在Web API中创建filter实例时,它们会被缓存,因此Autofac必须使用根生存期范围而不是请求生存期范围来解析属性注入。 在每个请求的基础上,Autofac没有机会进行任何属性注入 – filter在Web API中是有效的单例,并且没有任何改变它的钩子。

此后,如果您需要在filter中使用每个请求服务,则必须使用该GetDependencyScope()技巧。

有关详细信息,请参阅Autofac上的这些问题:

  • 问题#452:Web API中的属性注入ActionFilterAttribute不使用Http请求范围
  • 问题#525:过滤每个http请求没有获取实例