【问题标题】:can global filters have Singleton or Transient Scope全局过滤器可以有 Singleton 或 Transient Scope
【发布时间】:2019-08-05 11:42:51
【问题描述】:

我是 ASP.NET Core MVC 的新手,只是一个关于全局过滤器生命周期的问题。 我创建了一个全局过滤器(结果过滤器)为:

public class MessageAttribute : ResultFilterAttribute
{
   private int GetNum { get; set; } = 0;
   ...
   public override void OnResultExecuting(ResultExecutingContext context)
   {
       GetNum += 1;
       WriteMessage(context, $"<div>The Num is:{GetNum }</div>");
   }
   ...
   private void WriteMessage(FilterContext context, string msg)
   {
      byte[] bytes = Encoding.ASCII.GetBytes($"<div>{msg}</div>");
      context.HttpContext.Response.Body.Write(bytes, 0, bytes.Length);
   }
}

然后我运行了应用程序,每次我从 1、2、3....等刷新页面时,Num 输出都会增加

然后我在startup.cs 中注册了MessageAttribute 为:

services.AddTransient<MessageAttribute>();
services.AddMvc().AddMvcOptions(options =>{
   options.Filters.Add(new MessageAttribute());
});

所以无论我刷新页面多少次,我都希望 Num 输出始终为“1”,因为 MessageAttribute 已注册为“瞬态”,这意味着创建了一个新的 MessageAttribute 实例每次对于每个新请求,但是当我运行应用程序时,Num 输出仍然从 1 增加到 2、3 ...每次我刷新页面时,并不意味着全局过滤器只能注册为:

services.AddSingleton<MessageAttribute>();

不知何故,asp.net core MVC 只是用上面的语句覆盖了我的注册,我的理解是否正确?

【问题讨论】:

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


    【解决方案1】:

    我认为这是行为: 当您将值传递给 add 方法时,您会以某种方式创建过滤器的单例实例。 MVC 将使用您创建的确切实例:

    var alwaysUseThis = new MessageAttribute();
    options.Filters.Add(alwaysUseThis);
    

    如果您将类型传递给 Add() 方法,则 MVC 将在每次需要时创建过滤器。 请注意,创建过滤器对象的是 MVC 过滤器管道,而不是服务提供者:

    options.Filters.Add<MessageAttribute>();
    

    如果你希望你的过滤器像其他依赖一样被解析,你应该使用 AddService() 方法:

    options.Filters.AddService<MessageAttribute>();
    // services:
    services.AddTransient<MessageAttribute>();
    

    通过这种注册,您可以使用过滤器所需的任何生命周期(瞬态、单例、..)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-28
      • 2014-09-20
      • 2019-08-09
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      相关资源
      最近更新 更多