如何在ASP.NET CORE中使用具有依赖注入的动作过滤器?

Jam*_*ith 14 c# asp.net asp.net-mvc action-filter 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在控制器中:

[MyAttribute(Limit = 10)]
public IActionResult()
{
    ...
Run Code Online (Sandbox Code Playgroud)

如果我把ICustomService放到构造函数中,那么我就无法编译我的项目了.那么,我如何在动作过滤器中获取接口实例呢?

Ral*_*ing 17

如果你想避免服务定位器模式,你可以通过构造函数注入使用DI TypeFilter.

在您的控制器中使用

[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
public IActionResult() NiceAction
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

而且您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();
    }
}
Run Code Online (Sandbox Code Playgroud)

对我来说,注释[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]似乎很尴尬.为了获得更可读的注释,[MyActionFilter(Limit = 10)]过滤器必须继承TypeFilterAttribute.我的答案如何在asp.net中的动作过滤器中添加参数?显示了这种方法的一个例子.


ade*_*lin 6

您可以使用Service Locator

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

注意,泛型方法GetService<>是扩展方法,位于命名空间中Microsoft.Extensions.DependencyInjection

如果要使用构造函数注入,请使用TypeFilter。请参阅如何在asp.net中向操作过滤器添加参数?

  • 这是一个很好的建议,但是需要更多的工作来对其进行单元测试。 (3认同)

Fra*_*ein 5

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

在控制器中:

[ServiceFilter(typeof(TrackingAttribute), Order = 2)]
Run Code Online (Sandbox Code Playgroud)

您需要在依赖项容器中注册 TrackingAttribute 以便 ServiceFilter 可以解析它。

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