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

时间:2014-05-14 15:33:26

标签: c# asp.net-mvc asp.net-web-api autofac

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

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

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

我们称之为:

  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请求依赖项,从不从容器本身请求"

1 个答案:

答案 0 :(得分:10)

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

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

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