Autofac IAutofacActionFilter execution order for Web API 2

▼魔方 西西 提交于 2020-01-07 01:48:10

问题


Are there any ways to set the order of execution on web api action filters registered with Autofac? Currently, if I register the following:

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

it is 'unknown' which will be executing first and second. Even if I'd create a new FilterProvider which orders them in a specific way it will not work due to removal of any custom IFilterProvider and a private ActionDescriptorFilterProvider.


回答1:


There is currently no way to manually specify the order in which registered filters run.

Filters get resolved in the same way other dependencies get resolved using the IEnumerable<T> implicit relationship type. This happens in the AutofacWebApiFilterProvider. As with regular filters, it's more complex than just "run in XYZ order" - there's controller vs. action scoping to take into account as well.

So, say you registered these:

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 filters run controller level then action level; Autofac filters run in reverse registration order. If someone calls the Get action on the ValuesController the filters will run:

  • AuthenticationFilter
  • LoggingFilter
  • RoundingFilter
  • ErrorFilter

However, it's sometimes not as straightforward as that, since if you use an extension like PreserveExistingDefaults it internally changes the order of registrations to put the PreserveExistingDefaults registration last.

That sort of registration ordering complexity with handling defaults and so forth is why I can't point you to a line of code.You can look at the CollectionRegistrationSource which is responsible for resolving the IEnumerable<IActionFilter> collections as part of the filter provider. You can also look at the filter provider to see how things happen.

If you need to manually specify order, you'll have to write your own extension to the AutofacWebApiFilterProvider or, if extension doesn't work, roll your own. If you get it working well in a nice fluent manner, we'd be happy to take a pull request.



来源:https://stackoverflow.com/questions/35797079/autofac-iautofacactionfilter-execution-order-for-web-api-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!