簡體   English   中英

如何在 ASP.NET CORE 中使用帶有依賴注入的動作過濾器?

[英]How to use Action Filters with Dependency Injection in ASP.NET CORE?

我在我的ASP.NET CORE應用程序中到處使用基於構造函數的依賴注入,我還需要在我的操作過濾器中解決依賴關系:

public class MyAttribute : ActionFilterAttribute
{
    public int Limit { get; set; } // some custom parameters passed from Action
    private ICustomService CustomService { get; } // this must be resolved

    public MyAttribute()
    {
    }

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // my code
        ...

        await next();
    }
}

然后在控制器中:

[MyAttribute(Limit = 10)]
public IActionResult()
{
    ...

如果我將 ICustomService 放到構造函數中,那么我將無法編譯我的項目。 那么,我該如何在操作過濾器中獲取接口實例呢?

如果你想避免服務定位器模式,你可以通過構造函數注入使用 DI 和TypeFilter

在您的控制器中使用

[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
public IActionResult() NiceAction
{
   ...
}

並且您的ActionFilterAttribute不再需要訪問服務提供者實例。

public class MyActionFilterAttribute : ActionFilterAttribute
{
    public int Limit { get; set; } // some custom parameters passed from Action
    private ICustomService CustomService { get; } // this must be resolved

    public MyActionFilterAttribute(ICustomService service, int limit)
    {
        CustomService = service;
        Limit = limit;
    }

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        await next();
    }
}

對我來說,注釋[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]似乎很尷尬。 為了獲得更易讀的注釋,如[MyActionFilter(Limit = 10)]您的過濾器必須從TypeFilterAttribute繼承。 如何將參數添加到 asp.net 中的操作過濾器? 顯示了此方法的示例。

您可以使用Service Locator

public void OnActionExecuting(ActionExecutingContext actionContext)
{
     var service = actionContext.HttpContext.RequestServices.GetService<IService>();
}

請注意,通用方法GetService<>是一個擴展方法,位於命名空間Microsoft.Extensions.DependencyInjection

如果要使用構造函數注入,請使用TypeFilter 請參閱如何將參數添加到 asp.net 中的操作過濾器?

您可以使用ServiceFilters在控制器中實例化您需要的 ActionFilters。

在控制器中:

[ServiceFilter(typeof(TrackingAttribute), Order = 2)]

您需要在依賴項容器中注冊 TrackingAttribute 以便 ServiceFilter 可以解析它。

https://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/閱讀更多相關信息

一個不錯的選擇是這樣做(在 .NET Core 3.1 中測試)

  1. 在 Filter 類中放置:

    公共靜態類 FilterContainer {

     public class GenericFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { string Action = filterContext.ActionDescriptor.RouteValues["action"]; Console.WriteLine($"[action]: {Action} STARTING"); } public override void OnActionExecuted(ActionExecutedContext filterContext) { string Action = filterContext.ActionDescriptor.RouteValues["action"]; Console.WriteLine($"[action]: {Action} FINISHED"); } public override void OnResultExecuting(ResultExecutingContext filterContext) { string Action = filterContext.ActionDescriptor.RouteValues["action"]; Console.WriteLine($"[action]: {Action} GIVING RESULT"); } public override void OnResultExecuted(ResultExecutedContext filterContext) { string Action = filterContext.ActionDescriptor.RouteValues["action"]; ObjectResult ObjectResult = (ObjectResult)filterContext.Result; Console.WriteLine($"[action]: {Action} RESULT GIVEN. Value: {ObjectResult.Value}"); } } }
  2. 在 Startup.cs/ConfigureServices(IServiceCollection services) 里面放這個:

    services.AddControllers().AddMvcOptions(options => options.Filters.Add(new FilterContainer.GenericFilter()));

結果是,對 .NET Core 應用程序內任何類型操作的請求將通過此管道進出,而無需在任何操作上方聲明過濾器屬性。

讓我向您展示 Visual Studio 的輸出窗口中的一個示例:

[action]: JSON STARTING
[action]: JSON FINISHED
[action]: JSON GIVING RESULT
[action]: JSON RESULT GIVEN. Value: TestId: 103, FullName:...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM