How to (really) implement your own ActionFilterAttribute

In ASP.NET MVC you may “tag” your actions with attributes derived from ActionFilterAttribute and automatically have their OnActionExecuting and OnActionExecuted methods called before and after the framework invokes your action, thus achieving a simple form of method interception by using attributes.

Pretty simple model, but it falls apart if you are using an IoC container to wire things up. Moreover, having application logic embedded in properties is sort of icky. It just so happens that we can solve both problems and end up with a pretty nice solution at the same time 🙂

First, create the interface you wish to use to denote an action filter – e.g. something like this:

Note that I have used interfaces for the arguments. This allows us to decouple the action filter from the framework classes, thus making our stuff more easily testable.
In this example I have only put one method – ProvideViewData – on IAfterActionContext, allowing my action filters to insert additional key-value-pairs into the ViewData. More methods should of course be added if they are needed.

Then, create the actual action filter attribute, and make it accept a type as ctor argument – e.g. like this (assuming I want to resolve dependencies through the Windsor container installed as my controller factory):

And then implement the before and after argument classes – e.g. like this:

Now you may use the action filter like this:

where your IProvideProductCount will have all its dependencies automatically resolve by the container. That’s just sweet 🙂

In this example I made this simple implementation:

– thus allowing any views rendered from an action tagged with [ServiceFilter(typeof(IProvideProductCount))] to show how many products we have.

If your action filter attributes need arguments, then it’s another story. I wonder how one could get around to implement that?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.