我有一个 AuthorizationFilter 如下:
public class AuthorizationFilterAttribute : Attribute, IAuthorizationFilter
{
public AuthorizationFilterAttribute()
{
//Constructor of AuthorizationFilter will be called one time
}
public void OnAuthorization(AuthorizationFilterContext context)
{
//OnAuthorization method will be called per http request
}
}
Run Code Online (Sandbox Code Playgroud)
我发现 AuthorizationFilter 的构造函数在整个 ASP.NET Core 应用程序生命周期中只会被调用一次。但是它的 OnAuthorization 方法将在每个 HTTP 请求中被调用。
这是否意味着所有的过滤器(包括IAuthorizationFilter
,IActionFilter
,IResourceFilter
,IExceptionFilter
等)在ASP.NET MVC的核心是单身,这意味着他们将ASP.NET的核心应用生命周期过程中创建只是一个时间?
这取决于IFilterFactory.IsReusable
与您的过滤器关联的属性。
当IFilterProvider
(默认情况下是DefaultFilterProvider
) 即将提供所需的实例时,它首先检查过滤器是否也实现IFilterFactory
了:
IsReusable
属性来确定实例的生命周期。IsReusable
设置为 true
。在您的 custom 的情况下AuthorizationFilterAttribute
,由于您没有实现IFilterProvider
,它确实被认为是可重用的,并且只会创建一次。
查看来源
感谢haim770的回答。
我发现了一个可以为每个 http 请求而不是 ASP.NET Core 应用程序生命周期创建一个过滤器实例的实现。
实际上,我们需要在内部创建过滤器并将其包装到 IFilterFactory 中,如下所示:
using Microsoft.AspNetCore.Mvc.Filters;
using System;
namespace AspNetCoreFilterDemo.Filters
{
public class AuthorizationFilterWithFactoryAttribute : Attribute, IFilterFactory
{
//Return false, IFilterFactory.CreateInstance method will be called per http request
//Return true, InternalAuthorizationFilter will still be singleton, since IFilterFactory.CreateInstance will be called only one time during the whole ASP.NET Core application lifetime
public bool IsReusable
{
get
{
return false;
}
}
private class InternalAuthorizationFilter : IAuthorizationFilter
{
public InternalAuthorizationFilter()
{
//This InternalAuthorizationFilter constructor will be called per http request rather than ASP.NET Core application lifetime
}
public void OnAuthorization(AuthorizationFilterContext context)
{
//OnAuthorization method will be called per http request
}
}
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
//Create InternalAuthorizationFilter instance per http request
return new InternalAuthorizationFilter();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意IFilterFactory.IsReusable
属性,我们需要返回 false,否则该IFilterFactory.CreateInstance
方法将在 ASP.NET Core 应用程序生命周期内仅被调用一次,并且InternalAuthorizationFilter
仍然是单例的。
然后,我们需要指定AuthorizationFilterWithFactoryAttribute
oncontroller
而不是InternalAuthorizationFilter
,但AuthorizationFilterWithFactoryAttribute
实际上会为每个 http 请求创建一个InternalAuthorizationFilter
实例并对其进行操作:
using Microsoft.AspNetCore.Mvc;
using AspNetCoreFilterDemo.Filters;
namespace AspNetCoreFilterDemo.Controllers
{
public class HomeController : Controller
{
public HomeController()
{
}
[AuthorizationFilterWithFactory]
public IActionResult Index()
{
return View();
}
}
}
Run Code Online (Sandbox Code Playgroud)
AuthorizationFilterWithFactoryAttribute
仍将是单例且创建一次,但我们接近目标以针对InternalAuthorizationFilter
每个 http 请求创建过滤器 ( )。
您也可以从MSDN获取参考。
归档时间: |
|
查看次数: |
792 次 |
最近记录: |