Guidelines aren’t rules

I’m a huge fan of the Framework Design Guidelines book.  It provides great instruction on creating reusable libraries, based on Microsoft’s design on the .NET Framework.

But it’s important to remember that guidelines aren’t rules.  Guidelines are recommendations based on a set of perceived best practices.  Even a “DO” or “MUST” guideline can be broken in rare cases where following the guideline creates a negative user experience.  In these cases, you need a pretty overwhelming case against the guideline to not follow it.

ASP.NET MVC Example

Looking at Action Filters in ASP.NET MVC (Preview 2), I found an…interesting naming convention for creating action filters:

public class AdminRoleAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.IsInRole("Administrator"))
            throw new ApplicationException("For cool dudes only.");
    }
}

In the ASP.NET MVC framework, we’re required to create a custom attribute to create action filters.  Taking a look at the method I override, when exactly does this method get executed?  Is it before, after or during?  The present tense of the verb implies that it’s during, but that’s not possible.  I have to deduce that it gets executed before the action.

The naming convention here is a little strange, with “OnActionExecuting” the method for “before” and “OnActionExecuted” for “after”.  This naming style is normally used for event raising, where you’d create protected “On<EventName>” methods that would in turn raise the event.

In the ActionFilterAttribute, there are no events being raised, so this guideline shouldn’t apply. That’s where more clear names like say, “BeforeAction” and “AfterAction” would be far more explicit about when these methods get called.

Other frameworks

Action filters are fairly common in MVC frameworks.  I wouldn’t want to call out this design choice without looking at a few others, so let’s check out what the other cool kids are doing.

MonoRail

To create a custom filter in MonoRail, you don’t need to create a new attribute type.  In the ASP.NET MVC example, I’d decorate my controllers with the specific “AdminRole” attribute.  The filters in MonoRail are somewhat decoupled from when they’re executed:

public class AdminRoleFilter : IFilter
{
    public bool Perform(ExecuteEnum exec, IRailsEngineContext context, Controller controller)
    {
        if (!context.CurrentUser.IsInRole("Administrator"))
        {
            controller.Flash.Add("For cool dudes only.");
            controller.Redirect("", "login", "login");
            return false;
        }

        return true;
    }
}

You then decorate your controller with the FilterAttribute, specifying when the filter gets executed:

    [Filter(ExecuteEnum.BeforeAction, typeof(AdminRoleFilter))]
    public class AdminController : SmartDispatcherController

Note the nice pretty name, “BeforeAction”.  Other values for the ExecuteEnum include “AfterAction”, “Around”, “AfterRendering”, etc.  These names are very expressive for exactly when this action should get executed.  I don’t get names like “OnViewRendered” or “OnActionExecutingOhAndByTheWayOnActionExecutedAlso”.

Non-.NET frameworks

Rails has equally expressive manner of doing actions.  This makes sense as MonoRail was heavily influenced by Rails.  In Rails, you can specify then name of the methods to be executed:

  class BankController < ActionController::Base
    before_filter :audit

    private
      def audit
        # record the action and parameters in an audit log
      end
  end

  class VaultController < BankController
    before_filter :verify_credentials

    private
      def verify_credentials
        # make sure the user is allowed into the vault
      end
  end

Rails provides many descriptive methods (which can be chained) to modify the filters for a particular controller: “before_filter”, “after_filter”, “around_filter” and others.  Note again the obviously named methods, where the time the filter executes is explicitly named “before” or “after”.

Finally, in Django, filter-like features are created through the Decorator pattern, where you explicitly wrap a controller action in another method that adds functionality:

from django.contrib.auth.decorators import login_required

def my_view(request):
    # ...
my_view = login_required(my_view)

Instead of specifying when the filter is executed, it’s up to the implementer of the decorator to determine when to call the underlying action.  This gives quite a bit of flexibility to the designers of the decorator, but takes it away from the developer, as they can no longer specify when the filter should execute.

Intention-revealing interfaces

In the end, the difference between a good and not-so-good framework can be found in its success in creating Intention-revealing interfaces.  If you can’t look at a component or class and infer its responsibility and purpose without exercising the component, chances are good that you have an intention-revealing interface.

In the ASP.NET MVC filters, I had to guess which one executed before the action, as the word “before” was nowhere to be seen.  When guidelines directly contradict a clear, intention-revealing interface, it’s safe to choose to not follow the guideline.  If we had an ActionFilterAttribute that had only “BeforeFilter” and “AfterFilter”, I don’t think the FDG police will come knocking at anyone’s door.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in ASP.NET MVC, Domain-Driven Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://devlicio.us/blogs/sergio_pereira/ Sergio Pereira

    Very true. This is a plague spread by careless modeling. Thank God for the current crop of OSS .Net projects, which draw inspiration from the right places.

  • http://brackett@ufl.edu Mark Brackett

    I dunno – seeing as how we (.NET devs, that is) are all used to the ing and ed naming convention, it’s not too much of a leap to apply that to Oning, and Oned. The consistency of that naming convention wins out to me, vs. the Before/After pair.

    The only thing that might give me pause is if there was a chance that you could actually be in the process of ing, and then there’d be some confusion between before and during. But, with an ActionAttribute (like an event), there really is no chance for “during”.

    But, since I was confused for a bit about the “Action” (thinking it was my “Action” that was being referred to, instead of the ControllerAction), I’d vote for OnControllerActionExecuting. That removes all ambiguity for me.

  • http://jimmybogard.lostechies.com Jimmy Bogard

    No offense Mark, but that’s about the ugliest way of describing “BeforeAction” I’ve seen.

    Those conventions are for events, which this is clearly not an event. These are method calls on an attribute. It’s like someone had a contest, “who can think of the most obfuscated name to call a Before and After method”. It only removes ambiguity for those that are already familiar with event naming conventions.

    Event naming conventions remove possibilities for other options, like “Around”, which _all_ other frameworks listed allow.

    public void OnCommentWritingFinished()
    {
    Sigh();
    }