Search code examples
c#asp.net-coredependency-injectionasp.net-core-mvcasp.net-core-2.1

Asp.net Core dependency injection in filters without [ServiceFilter] or [TypeFilter]


I need to inject some services with dependency injection to action filters. I'm familiar with the [ServiceFilter] and [TypeFilter] approach, but it's kind of ugly, messy, and unclear.

Is there a way I can set a filter in the normal way? without wrapping the filter I'm using with [ServiceFilter] or [TypeFilter]?

For example what I want:

[SomeFilterWithDI]
[AnotherFilterWithDI("some value")]
public IActionResult Index()
{
    return View("Index");
}

Instead of:

[ServiceFilter(typeof(SomeFilterWithDI))]
[TypeFilter(typeof(AnotherFilterWithDI), Arguments = new string[] { "some value" })]
public IActionResult Index()
{
    return View("Index");
}

It looks way different, this approach doesn't seem right to me.


Solution

  • For [SomeFilterWithDI], you could refer the comment from @Kirk larkin.

    For [AnotherFilterWithDI("some value")], you could try passing Arguments from TypeFilterAttribute.

    • ParameterTypeFilter define the accept parameters.

      public class ParameterTypeFilter: TypeFilterAttribute
      {
      
          public ParameterTypeFilter(string para1, string para2):base(typeof(ParameterActionFilter))
          {
              Arguments = new object[] { para1, para2 };
          }
      }
      
    • ParameterActionFilter accept the passed parameters.

          public class ParameterActionFilter : IActionFilter
      {
          private readonly ILogger _logger;
          private readonly string _para1;
          private readonly string _para2;
      
          public ParameterActionFilter(ILoggerFactory loggerFactory, string para1, string para2)
          {
              _logger = loggerFactory.CreateLogger<ParameterTypeFilter>();
              _para1 = para1;
              _para2 = para2;
          }
      
          public void OnActionExecuting(ActionExecutingContext context)
          {
              _logger.LogInformation($"Parameter One is {_para1}");
              // perform some business logic work
      
          }
      
          public void OnActionExecuted(ActionExecutedContext context)
          {
              // perform some business logic work
              _logger.LogInformation($"Parameter Two is {_para2}");
          }
      }
      

      As the description from Arguments, ILoggerFactory loggerFactory is resolved by dependency injection container. para1 and para2 is resolved by ParameterTypeFilter.

          //
      // Summary:
      //     Gets or sets the non-service arguments to pass to the Microsoft.AspNetCore.Mvc.TypeFilterAttribute.ImplementationType
      //     constructor.
      //
      // Remarks:
      //     Service arguments are found in the dependency injection container i.e. this filter
      //     supports constructor injection in addition to passing the given Microsoft.AspNetCore.Mvc.TypeFilterAttribute.Arguments.
      public object[] Arguments { get; set; }
      
    • Useage

      [ParameterTypeFilter("T1","T2")]
      public ActionResult Parameter()
      {
          return Ok("Test");
      }