【问题标题】:strange behaviour that filters have when dealing with each request过滤器在处理每个请求时的奇怪行为
【发布时间】:2021-10-11 18:33:31
【问题描述】:

下面是一些简单的代码:

[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的两个实例被更新了,那么为什么应用程序创建这个fiter的两个实例呢?

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

【问题讨论】:

  • 控制器有生命周期的依赖,就像 DbContext 一样,所以状态管理是绝对需要的。属性具有静态数据,在编译期间已知,因此您可以使用相同的实例。
  • @FireAlkazar 感谢您的回答。但是为什么过滤器会被创建两次呢?

标签: c# .net asp.net-core asp.net-core-mvc


【解决方案1】:

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

看起来这是 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2013-06-24
    • 1970-01-01
    相关资源
    最近更新 更多