Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 640
O. Shai Avatar asked Nov 27 '18 23:11

O. Shai


1 Answers

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");
    }
    
like image 197
Edward Avatar answered Sep 24 '22 05:09

Edward