我有一个 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仍然是单例的。
然后,我们需要指定AuthorizationFilterWithFactoryAttributeoncontroller而不是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 次 |
| 最近记录: |