Injecting dependencies into ASP.NET MVC 3 action filters. What’s wrong with this approach?

Yes, there are downsides, as there are lots of issues with IDependencyResolver itself, and to those you can add the use of a Singleton Service Locator, as well as Bastard Injection.

A better option is to implement the filter as a normal class into which you can inject whichever services you’d like:

public class MyActionFilter : IActionFilter
{
    private readonly IMyService myService;

    public MyActionFilter(IMyService myService)
    {
        this.myService = myService;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if(this.ApplyBehavior(filterContext))
            this.myService.DoSomething();
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if(this.ApplyBehavior(filterContext))
            this.myService.DoSomething();
    }

    private bool ApplyBehavior(ActionExecutingContext filterContext)
    {
        // Look for a marker attribute in the filterContext or use some other rule
        // to determine whether or not to apply the behavior.
    }

    private bool ApplyBehavior(ActionExecutedContext filterContext)
    {
        // Same as above
    }
}

Notice how the filter examines the filterContext to determine whether or not the behavior should be applied.

This means that you can still use attributes to control whether or not the filter should be applied:

public class MyActionFilterAttribute : Attribute { }

However, now that attribute is completely inert.

The filter can be composed with the required dependency and added to the global filters in global.asax:

GlobalFilters.Filters.Add(new MyActionFilter(new MyService()));

For a more detailed example of this technique, although applied to ASP.NET Web API instead of MVC, see this article: http://blog.ploeh.dk/2014/06/13/passive-attributes

Leave a Comment