You can implement an IFilterFactory for this purpose. The runtime checks for this interface when creating filters and calls the CreateInstance method that gets an IServiceProvider as a parameter. You can use this provider to create services and inject them into the filter.
The following sample is taken from the docs:
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) { }
}
}
If you need to both use services from DI and values defined on the attribute, you can use the following approach:
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) { }
}
}
You can then apply the filter like this:
public controller : ControllerBase
{
[ResponseHeaderFilterFactory("Parameter1")]
public ActionResult MyMethod()
{
....
}
}
ActionFilterAttribute? If yes I'll post an answer that explains how to do.