过滤器在处理每个请求时的奇怪行为
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
下面是一些简单的代码:
[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