【问题标题】:Autofac.WebApi2 Global Action FIlters injection failedAutofac.WebApi2 全局操作过滤器注入失败
【发布时间】:2018-05-31 23:58:25
【问题描述】:

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

我有一个过滤器,用于记录所有控制器中所有方法的执行持续时间。为了完成该任务,我创建了一个 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 中描述的步骤操作,我会收到代码 sn-p 后描述的错误:

var builder = new ContainerBuilder();

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

类型“MyController”必须可分配给 'Autofac.Integration.WebApi.IAutofacActionFilter'。参数名称: 注册

这是控制器的摘录:

//...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();
    }
}

我错过了什么?

【问题讨论】:

  • 请附上MyController的源代码(尤其是前30行)。
  • 我已经完成了控制器 sn-p。谢谢!
  • 您是否在 Autofac 构建器中注册过滤器提供程序? builder.RegisterWebApiFilterProvider(config); 可能有助于查看您的 IocConfiguration.Configure 方法。
  • 是的,抱歉,我不想让问题变得非常大。我已经包括了所有涉及的组件。谢谢。

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


【解决方案1】:

我看到您的过滤器ExecutionTimeFilter 继承自ActionFilterAttributeIf you notice in the docs Autofac 过滤器机制不使用 Web API 操作过滤器接口

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

您可能在文档中遗漏的关键步骤是第二步:

您的类不会从现有的 Web API 过滤器属性之一派生,而是实现集成中定义的适当过滤器接口。下面的过滤器是一个动作过滤器,实现IAutofacActionFilter而不是System.Web.Http.Filters.IActionFilter

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

文档归结为:

  • 如果你想使用Register(...).AsWebApiActionFilterFor&lt;T&gt;()这个东西,你需要使用Autofac过滤器接口。
  • 如果要使用标准 Web API 过滤器,则需要进行服务定位,因为标准 Web API 过滤器不会通过依赖注入运行。

文档中有详细说明 Autofac 使用自定义接口的确切原因以及 DI 不能使用标准过滤器的原因。

【讨论】:

  • 感谢您的澄清。我想我将不得不使用标准注册。
猜你喜欢
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
  • 2021-01-20
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多