J. Doe
J. Doe

Reputation: 2747

ASP.Net Core filters with arguments and DI

Is there a way to make filter with arguments and DI in ASP.NET Core?

My working TestFilterAttribute with TestFilterFilter and DI without arguments:

public class TestFilterAttribute : TypeFilterAttribute
{
    public TestFilterAttribute() : base(typeof(TestFilterFilter))
    {
    }

    private class TestFilterFilter : IActionFilter
    {
        private readonly MainDbContext _mainDbContext;

        public TestFilterFilter(MainDbContext mainDbContext)
        {
            _mainDbContext = mainDbContext;
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {


        }

        public void OnActionExecuted(ActionExecutedContext context)
        {


        }
    }
}

I want to simply use [TestFilter('MyFirstArgument', 'MySecondArgument')] with arguments, instead of [TestFilter] without arguments.

Upvotes: 8

Views: 6629

Answers (1)

Tseng
Tseng

Reputation: 64121

There is, if you look at the source. Never tried though, so you got to try it yourself (can't test it at work and internet issues at home).

The documentation names one of it, for untyped parameters:

[TypeFilter(typeof(AddHeaderAttribute),
    Arguments = new object[] { "Author", "Steve Smith (@ardalis)" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}

The xmldoc of TypeFilterAttribute says

    /// <summary>
    /// Gets or sets the non-service arguments to pass to the <see cref="ImplementationType"/> constructor.
    /// </summary>
    /// <remarks>
    /// Service arguments are found in the dependency injection container i.e. this filter supports constructor
    /// injection in addition to passing the given <see cref="Arguments"/>.
    /// </remarks>
    public object[] Arguments { get; set; }

Alternatively, you can add properties to your TestFilterAttribute and assign them in the constructor, but this only works if the parameter is mandatory and hence set via constructor

public class TestFilterAttribute : TypeFilterAttribute
{
    public TestFilterAttribute(string firstArg, string secondArg) : base(typeof(TestFilterFilter))
    {
        this.Arguments = new object[] { firstArg, secondArg }
    }

    private class TestFilterFilter : IActionFilter
    {
        private readonly MainDbContext _mainDbContext;
        private readonly string _firstArg;
        private readonly string _secondArg;

        public TestFilterFilter(string firstArg, string secondArg, MainDbContext mainDbContext)
        {
            _mainDbContext = mainDbContext;
            _firstArg= firstArg;
            _secondArg= secondArg;
        }

        public void OnActionExecuting(ActionExecutingContext context) { }

        public void OnActionExecuted(ActionExecutedContext context) { }
    }
}

Upvotes: 20

Related Questions