Web API 2的Autofac IAutofacActionFilter执行顺序

时间:2016-03-04 13:17:06

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

有没有办法在使用Autofac注册的web api操作过滤器上设置执行顺序? 目前,如果我注册以下内容:

builder.Register(x => new MyFirstAttribute(x.Resolve<IMyService>())).AsWebApiActionFilterFor<ApiController>().InstancePerRequest();
builder.Register(x => new MySecondAttribute(x.Resolve<IMyService>())).AsWebApiActionFilterFor<ApiController>().InstancePerRequest();

它是未知的&#39;这将是第一次和第二次执行。即使我创建了一个以特定方式对其进行排序的新FilterProvider,由于removal of any custom IFilterProvidera private ActionDescriptorFilterProvider,它也无法正常工作。

1 个答案:

答案 0 :(得分:2)

目前无法手动指定注册过滤器的运行顺序。

过滤器的解析方式与使用IEnumerable<T> implicit relationship type解析其他依赖项的方式相同。发生这种情况in the AutofacWebApiFilterProvider。与常规过滤器一样,它比仅仅按照XYZ顺序运行更复杂。 - 那里的控制器与行动范围也要考虑在内。

所以,请说你注册了这些:

builder.RegisterType<LoggingFilter>()
    .AsWebApiActionFilterFor<ValuesController>()
    .InstancePerApiRequest();
builder.RegisterType<AuthenticationFilter>()
    .AsWebApiActionFilterFor<ValuesController>()
    .InstancePerApiRequest();
builder.RegisterType<ErrorFilter>()
    .AsWebApiActionFilterFor<ValuesController>(c => c.Get(default(int)))
    .InstancePerApiRequest();
builder.RegisterType<RoundingFilter>()
    .AsWebApiActionFilterFor<ValuesController>(c => c.Get(default(int)))
    .InstancePerApiRequest();

Web API过滤器运行控制器级别然后运行级别; Autofac过滤器以反向注册顺序运行。如果有人在Get上调用ValuesController操作,则会运行过滤器:

  • AuthenticationFilter
  • LoggingFilter的
  • RoundingFilter
  • ErrorFilter

但是,它有时并不那么简单,因为如果你使用像PreserveExistingDefaults这样的扩展名,它会在内部更改注册顺序,使PreserveExistingDefaults注册最后一次。

这种注册排序复杂性与处理默认值等等是我无法指向代码的原因。您可以查看CollectionRegistrationSource,负责将IEnumerable<IActionFilter>集合作为过滤器提供程序的一部分进行解析。您还可以查看at the filter provider以查看事情是如何发生的。

如果您需要手动指定订单,则必须将自己的扩展程序写入AutofacWebApiFilterProvider,或者如果扩展程序不起作用,请自行填写。{p>如果你能以一种流利的方式使它运作良好,我们很高兴take a pull request