Constructor Injection for ASP.NET MVC Action Filters

An entry about asp.net mvc | inversion of control Publication date 9. April 2009 11:50

ASP.NET MVC’s action filters allow you to execute some code before/after an action in a declarative manner, manipulating what goes into or comes out of the action. In essence, they are what’s called aspects in Aspect Oriented Programming; a way of encapsulating crosscutting concerns into reusable components. For example, instead of this:

public ActionResult SomeActionWhichRequiresAuthentication()

{

    if (!User.Identity.IsAuthenticated)

    {

        return RedirectToAction("Login", "Authentication");

    }

    else

    {

        // ...

    }

}

You’ll do this:

[Authorize]

public ActionResult SomeActionWhichRequiresAuthentication()

{

    // ...

}

However, a problem with ASP.NET MVC’s action filters is that there’s no support for having an IOC container manage them, which means that if I need to do something more complicated that requires calling into a domain service/repository for example, I cannot get these injected easily. Jeremy Skinner has a solution which enables property injection, but what I really want is constructor injection.

Solution: The Proxy Pattern

What I came up with, was to build a filter proxy. Using it looks like this:

[Filter(typeof(AuthorizationFilter))]

public ActionResult SomeActionWhichRequiresAuthentication()

{

    // ...

}

Internally, the FilterAttribute resolves the actual filter using the IOC container and forwards all its calls to it:

public class FilterAttribute : ActionFilterAttribute

{

    private readonly Type _actionFilterType;

    private IActionFilter _action;

 

    public FilterAttribute(Type actionFilterType)

    {

        _actionFilterType = actionFilterType;

    }

 

    public override void OnActionExecuting(ActionExecutingContext filterContext)

    {

        // resolve the action filter using the IOC container

        var container = (ICanResolveDependencies) HttpContext.Current.ApplicationInstance;

        _action = (IActionFilter)container.Resolve(_actionFilterType);

 

        _action.OnActionExecuting(filterContext);

        base.OnActionExecuting(filterContext);

    }

 

    public override void OnActionExecuted(ActionExecutedContext filterContext)

    {

        _action.OnActionExecuted(filterContext);

        base.OnActionExecuted(filterContext);

    }

}

This allows the IOC container to manage the instantiation and lifetime of the action filter. Note the assumption that the applications Application object (Global.asax) implements the ICanResolveDependencies interface, which essentially is an abstraction of the IOC container.

Currently rated 3.3 by 3 people

  • Currently 3.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

NDC 2010

The conference to attend this summer happens June 16th-18th in Oslo, Norway. Are you going? Be sure to catch my talk on AOP while you're there!

 

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS