![](/img/trans.png)
[英]How to use Action Filters with Dependency Injection in ASP.NET CORE?
[英]How can I use dependency injection in asp.net core action filter?
我有一個FilterAttribute,它有兩個參數,一個在依賴注入中定義,一個在控制器方法上定義為字符串
public controller : ControllerBase
{
[MyFilter("Parameter1", FromDependency)]
public ActionResult MyMethod()
{
....
}
}
和過濾器
public MyFilter : Attribute
{
MyFilter(string parameter1, context fromDependency)
{
}
}
如何從依賴注入中注入參數?
您可以為此目的實現IFilterFactory
。 運行時在創建過濾器時檢查此接口並調用獲取IServiceProvider
作為參數的CreateInstance
方法。 您可以使用此提供程序創建服務並將它們注入過濾器。
以下示例取自文檔:
public class ResponseHeaderFilterFactory : Attribute, IFilterFactory
{
public bool IsReusable => false;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) =>
new InternalResponseHeaderFilter();
private class InternalResponseHeaderFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context) =>
context.HttpContext.Response.Headers.Add(
nameof(OnActionExecuting), nameof(InternalResponseHeaderFilter));
public void OnActionExecuted(ActionExecutedContext context) { }
}
}
如果您需要同時使用 DI 中的服務和屬性上定義的值,則可以使用以下方法:
public class ResponseHeaderFilterFactory : Attribute, IFilterFactory
{
private readonly string _attrParam;
public ResponseHeaderFilterFactory(string attrParam)
{
_attrParam = attrParam;
}
public bool IsReusable => false;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
var svc = serviceProvider.GetRequiredService<IMyService>();
return new InternalResponseHeaderFilter(_attrParam, svc);
}
private class InternalResponseHeaderFilter : IActionFilter
{
private readonly string _attrParam;
private readonly IMyService _service;
public InternalResponseHeaderFilter(string attrParam, IMyService service)
{
_attrParam = attrParam;
_service = service;
}
public void OnActionExecuting(ActionExecutingContext context) =>
context.HttpContext.Response.Headers.Add(
nameof(OnActionExecuting), nameof(InternalResponseHeaderFilter));
public void OnActionExecuted(ActionExecutedContext context) { }
}
}
然后,您可以像這樣應用過濾器:
public controller : ControllerBase
{
[ResponseHeaderFilterFactory("Parameter1")]
public ActionResult MyMethod()
{
....
}
}
您可以實現ActionFilterAttribute
以從HttpContext.RequestServices
獲取 DI 依賴項:
public sealed class MyAttr : ActionFilterAttribute
{
MyAttr(string parameter1)
{
}
public override void OnActionExecuting(ActionExecutingContext context)
{
//Get dependency from HttpContext services
var myDependency = context.HttpContext.RequestServices.GetService<MyDependency>();
//Use it
myDependency.DoSomething();
//....
}
}
直接將組件注入到動作過濾器屬性中是不可能的,但是有各種變通方法可以讓我們有效地完成同樣的事情。 使用 ServiceFilter 是一種允許將依賴項注入到單個操作過濾器中的相對干凈的方法。
ServiceFilter 屬性可以在操作或控制器級別使用。 用法非常簡單:
[ServiceFilter(typeof(MyFilter))]
還有我們的過濾器:
public class MyFilter: IActionFilter
{
MyFilter(string parameter1, context fromDependency)
{
}
}
顯然,當我們從 IoC 容器解析過濾器時,我們需要注冊它:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<MyFilter>(x =>
new Service(x.GetRequiredService<IOtherService>(),
"parameter1"));
...
}
Paul Hiles 文章中的更多詳細信息: 這里
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.