I use constructor-based dependency injection everywhere in my ASP.NET CORE
application and I also need to resolve dependencies in my action filters:
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(); } }
Then in Controller:
[MyAttribute(Limit = 10)] public IActionResult() { ...
If I put ICustomService to the constructor, then I'm unable to compile my project. So, how do I supossed to get interface instances in action filter?
Action filters – They run right before and after the action method execution. Exception filters – They are used to handle exceptions before the response body is populated. Result filters – They run before and after the execution of the action methods result.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With