Autofac IAutofacActionFilter for Web API 2 的执行顺序

本文关键字:执行 顺序 API IAutofacActionFilter for Web Autofac | 更新日期: 2023-09-27 18:37:18

有没有办法在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();

它是"未知",它将首先和第二次执行。即使我创建了一个新的 FilterProvider,它以特定的方式对它们进行排序,由于删除了任何自定义 IFilterProvider 和私有 ActionDescriptorFilterProvider,它也不会起作用。

Autofac IAutofacActionFilter for Web API 2 的执行顺序

目前无法手动指定已注册筛选器的运行顺序。

筛选器的解析方式与使用 IEnumerable<T> 隐式关系类型解析其他依赖项的方式相同。这发生在 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 筛选器以相反的注册顺序运行。如果有人对ValuesController调用Get操作,筛选器将运行:

  • 身份验证筛选器
  • 日志记录筛选器
  • 舍入过滤器
  • 错误过滤器

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

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

如果需要手动指定顺序,则必须将自己的扩展写入AutofacWebApiFilterProvider或者,如果扩展不起作用,则创建自己的扩展。如果您以流畅的方式使其运行良好,我们很乐意接受拉取请求。