过滤器在处理每个请求时的奇怪行为

strange behaviour that filters have when dealing with each request

下面是一些简单的代码:

[SimpleFilter]
public class MyController : ControllerBase
{
   public MyController() {
      <---------- I put a debugger here
   }

   [Route("")]
   public string Get() {
      return DateTime.Now.ToLongTimeString();
   }
}

public class SimpleFilterAttribute : Attribute, IAsyncResourceFilter
{
   
   public SimpleFilterAttribute() {
      // <---------- I put a debugger here
   }

   public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) {
     ...
   }
}

所以我们知道当应用程序是运行时,它会创建一个新的控制器实例来处理每个请求,所以如果我发出5个请求,那么5个MyController实例将被更新,我可以通过在 MyController 的构造函数中放置一个调试器来验证它,每次控件转到调试器时。

所以我假设过滤器也应该发生同样的事情,将创建一个新的 fiter 实例来处理每个新请求,但奇怪的事情发生如下:

1-当应用程序第一次启动时,SimpleFilter 的构造函数被调用两次,这意味着 SimpleFilter 的两个实例被更新,那么为什么应用程序创建这个过滤器的两个实例?

2-在应用程序运行之后,每次我发起一个新的请求,都没有创建新的SimpleFilter实例,看起来像一个单独的过滤器实例来处理所有的请求,是这样吗?如果是这样,为什么我们每个请求都需要一个新的控制器实例,而所有请求只需要一个过滤器实例?

关于两次调用过滤器构造函数的有趣问题。

它看起来是 CLR 特定行为而不是 aspnet-core。每次调用 TypeInfo.GetCustomAttributes() 时,都会创建属性实例。

您可以致电

自行确认
var typeInfo = typeof(MyController).GetTypeInfo();
var attribes = typeInfo.GetCustomAttributes();

并且在构造控制器信息时 TypeInfo.GetCustomAttributes() 至少被调用了 2 次 https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs#L110