c# - Autofac.WebApi2 全局操作过滤器注入(inject)失败

标签 c# asp.net-web-api2 autofac

我面临的问题是 AutoFac 没有将预期的参数注入(inject)相应的过滤器。

我有一个过滤器,用于记录我所有 Controller 中所有方法的执行持续时间。为了完成这项任务,我创建了一个像这样的 ActionFilter:

//... other usings here...
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace MyNamespace
{
    internal class ExecutionTimeFilter : ActionFilterAttribute
    {
        public Logger _logger { get; set; }

        public ExecutionTimeFilter(Logger logger)
        {
            _logger = logger;
        }

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            _logger.Log("Log the starting time + controller + action + etc");
            actionContext.Request.Properties["Stopwatch"] = Stopwatch.StartNew();
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            var stopwatch = (Stopwatch)actionExecutedContext.Request.Properties["Stopwatch"];
            _logger.Log("Log the stopwatch.ElapsedMilliseconds + controller + action + etc");
        }
    }
}

我正在注册我的依赖项如下:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    var container = new IocConfiguration().Configure(GlobalConfiguration.Configuration);
    var resolver = new AutofacWebApiDependencyResolver(container);

    GlobalConfiguration.Configuration.DependencyResolver = resolver;

    //This is the only way I can get the logger injected
    //This is what ideally I want to avoid
    GlobalConfiguration.Configuration.Filters.Add(new ExecutionTimeFilter(_logger));
}

//IocConfiguration
using Autofac;
using Autofac.Integration.WebApi;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;

namespace MyNamespace
{
    internal class IocConfiguration
    {
        public IContainer Configure(HttpConfiguration httpConfiguration)
        {
            var builder = new ContainerBuilder();

            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            builder.RegisterInstance(LogManager.GetLogger("LoggerName")).As<Logger>().SingleInstance();

            builder.RegisterWebApiFilterProvider(httpConfiguration);

            return builder.Build();
        }
    }
}

如果我按照 official site 中描述的步骤进行操作我收到代码片段后描述的错误:

var builder = new ContainerBuilder();

builder.Register(c => new ExecutionTimeFilter(c.Resolve<Logger>()))
    .AsWebApiActionFilterFor<MyController>()
    .InstancePerRequest();

The type 'MyController' must be assignable to 'Autofac.Integration.WebApi.IAutofacActionFilter'. Parameter name: registration

这是 Controller 的摘录:

//...Other usings...
using System.Threading.Tasks;
using System.Web.Http;
using System;

namespace MyNamespace.Controllers
{
    public class MyController : ApiController
    {
        private readonly Logger _logger;

        public MarketoController(Logger logger)
        {
            _logger = logger;
        }
    }

    [HttpGet]
    [Route("path/{entityId}")]
    [ValidateEntityId]
    public async Task<IHttpActionResult> Get(int? entityId = null)
    {
        return Ok();
    }
}

我错过了什么?

最佳答案

我看到你的过滤器,ExecutionTimeFilter , 继承自 ActionFilterAttribute . If you notice in the docs Autofac 过滤器机制不使用 Web API 操作过滤器接口(interface)

异常消息有点令人困惑,但我猜问题是您正尝试在注册中使用 Web API 属性过滤器,而该注册期望您使用 Autofac 过滤器接口(interface)。

您可能在文档中错过的关键步骤是第二步,它说:

Instead of deriving from one of the existing Web API filter attributes your class implements the appropriate filter interface defined in the integration. The filter below is an action filter and implements IAutofacActionFilter instead of System.Web.Http.Filters.IActionFilter.

我在最重要的地方添加了一些粗体。

文档归结为:

  • 如果您想使用 Register(...).AsWebApiActionFilterFor<T>()东西,你需要使用 Autofac 过滤器接口(interface)。
  • 如果您想使用标准的 Web API 过滤器,您需要进行服务定位,因为标准的 Web API 过滤器不会通过依赖注入(inject)运行。

文档中有关于 Autofac 使用自定义接口(interface)的确切原因以及 DI 不适用于标准过滤器的原因的详细解释。

关于c# - Autofac.WebApi2 全局操作过滤器注入(inject)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50634363/

相关文章:

c# - 接口(interface)优化代码?

html - MultipartMemoryStreamProvider 和从 MultiPart/Form Data 中读取用户数据

asp.net-web-api - 没有 Controller 后缀的 Controller

c# - 如何在 ASP.NET Web API 上获取对象?

c# - 使用多重绑定(bind)更新源

c# - 将指针传递给 DLL 中的函数

c# - 线程卡在 MySqlCommand.ExecuteNonQuery() 中

c# - Autofac:如何加载引用但未直接使用的程序集

c# - 使用 AutoFac 根据构造函数参数名传递不同的实例

asp.net-mvc-4 - Autofac 和 ASP .Net MVC 4 Web API