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

前端 未结 3 1682
夕颜
夕颜 2020-12-16 12:46

I use constructor-based dependency injection everywhere in my ASP.NET CORE application and I also need to resolve dependencies in my action filters:

<         


        
相关标签:
3条回答
  • 2020-12-16 13:29

    If you want to avoid the Service Locator pattern you can use DI by constructor injection with a TypeFilter.

    In your controller use

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

    And your ActionFilterAttribute does not need to access a service provider instance anymore.

    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();
        }
    }
    

    For me the annotation [TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]seems to be awkward. In order to get a more readable annotation like [MyActionFilter(Limit = 10)]your filter has to inherit from TypeFilterAttribute. My answer of How do I add a parameter to an action filter in asp.net? shows an example for this approach.

    0 讨论(0)
  • 2020-12-16 13:33

    You can use ServiceFilters to instantiate the ActionFilters you need in the controller.

    In the controller:

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

    You need to register TrackingAttribute in the dependency container so the ServiceFilter can resolve it.

    Read more about this at https://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/

    0 讨论(0)
  • 2020-12-16 13:38

    You can use Service Locator:

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

    Note that the generic method GetService<> is an extension method and lives in namespace Microsoft.Extensions.DependencyInjection.

    If you want to use constructor injection use TypeFilter. See How do I add a parameter to an action filter in asp.net?

    0 讨论(0)
提交回复
热议问题