As per 文档 https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.1#dependency-injection,您在这里有几个选择:
如果您的过滤器具有需要从 DI 访问的依赖项,则有多种受支持的方法。您可以使用以下方法之一将过滤器应用于类或操作方法:
- ServiceFilterAttribute https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.servicefilterattribute?view=aspnetcore-2.1
- TypeFilterAttribute https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.typefilterattribute?view=aspnetcore-2.1
-
IFilterFactory https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.filters.ifilterfactory?view=aspnetcore-2.1根据您的属性实施
ServiceFilter 或 TypeFilter 属性
如果您只是想快速完成此操作,则只需使用前两个选项之一即可将过滤器应用到控制器或控制器操作。执行此操作时,您的过滤器本身不需要是属性:
[TypeFilter(typeof(ExampleActionFilter))]
public IActionResult Example()
=> View();
The ExampleActionFilter
然后就可以实施例如IAsyncActionFilter https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.filters.iasyncactionfilter?view=aspnetcore-2.1您可以使用构造函数注入直接依赖于事物:
public class ExampleActionFilter : IAsyncActionFilter
{
private readonly IMemoryCache _memoryCache;
public ExampleActionFilter(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ … }
}
您还可以使用[ServiceFilter]
属性而不是获得相同的效果,但是您还需要注册您的ExampleActionFilter
使用您的依赖注入容器Startup
.
过滤器厂
如果您需要更大的灵活性,您可以实现自己的过滤器工厂。这允许您编写工厂代码来自己创建实际的过滤器实例。上述的一个可能的实现ExampleActionFilter
可能看起来像这样:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ExampleActionFilterAttribute : Attribute, IFilterFactory
{
public bool IsReusable => false;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return serviceProvider.GetService<ExampleActionFilter>();
}
}
然后你可以使用它[ExampleActionFilter]
属性使 MVC 框架创建一个实例ExampleActionFilter
为您使用 DI 容器。
请注意,此实现基本上与ServiceFilterAttribute
做。只是自己实现它可以避免使用ServiceFilterAttribute
直接让你拥有自己的属性。
使用服务定位器
最后,还有另一个快速选项可以让您完全避免构造函数注入。这使用服务定位器模式在过滤器实际运行时动态解析服务。因此,您不需要注入依赖项并直接使用它,而是从上下文中显式检索它:
public class ExampleActionFilter : ActionFilterAttribute
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var memoryCache = context.HttpContext.RequestServices.GetService<IMemoryCache>();
// …
}
}