我们在应用程序中使用Autofac已有很长时间了(现在是MVC 4),基本 Controller 上都有数十个属性,所有继承自该属性,并且一切正常,因此当请求开始时,我们的服务就可以创建了,然后可以通过所有属性以及对 Controller 的操作。

现在,我们正在查看WebApi,并已创建WebApi Controller ,并使用HTTP命名空间中的ActionFilterAttribute在基本 Controller 上创建了属性。但是,问题从此处开始,其中注入(inject)到属性上的属性的服务与ApiController上的实例不同。查看下面的链接,这似乎是ASP.NET Web API and dependencies in request scope

但是,这里的解决方案并不理想,因为我们不希望我们的 Controller 知道有关依赖项注入(inject)的信息,我们只想使用将要注入(inject)属性的服务,并且知道每个请求只有一个实例。

我们称其为:

  builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);


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

我们的类当前已在Autofac上注册为InstancePerLifetimeScope,我们想要的是能够让每个请求适用于MvcControllers和ApiControllers。

那可能吗?

编辑:

因此,基本上,这一行会为请求返回正确的服务(即,同样在ApiController上的实例)
var service = actionContext.Request.GetDependencyScope().GetService(typeof(IOurService);

但是,ActionFilterAttribute上的属性注入(inject)实例并不相同,如果我将Autofac注册更改为InstancePerApiRequest,则会收到以下错误:

“从请求实例的范围中看不到带有匹配'AutofacWebRequest'的标记的范围。这通常表明SingleInstance()组件正在请求注册为HTTP请求的组件(或类似情况)。在网络集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,而不是从容器本身请求。”

最佳答案

这是Web API中的一个已知问题和一个设计问题。首次在Web API中创建筛选器实例时,将对其进行缓存,因此Autofac必须使用根生存期作用域而不是请求生存期作用域来解析属性注入(inject)。 Autofac在每个请求的基础上都没有机会进行任何属性注入(inject)-过滤器实际上是Web API中的单例,并且没有任何改变的钩子(Hook)。

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

有关更多详细信息,请参见Autofac上的以下问题:

  • Issue #452: Property Injection in Web API ActionFilterAttribute does not use Http request scope
  • Issue #525: Filter not getting instance per http request
  • 关于c# - 每个请求的WebApi,Autofac,System.Web.Http.Filters.ActionFilterAttribute实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23659108/

    10-13 06:24
    查看更多