Enforcing a Base Controller

In the previous post we talked about using a base controller class in ASP.NET MVC. The truly paranoid will worry about new developers on the team who don't know the rules and don't use the base class. One automated solution to this problem is to write a unit test to enforce the rule.

[TestMethod]
public void AllControllersDeriveFromFootballController()
{
    var badControllers =
        GetConcreteTypesAssignableTo<IController>()
       .Where(TypeIsNotDerivedFrom<FootballController>);

    if(badControllers.Any())
    {
        var controllerNames = AggregateTypeNames(badControllers);
        

        Assert.Fail("Controllers are out of line: {0}", 
                     controllerNames);
    }            
}

The above code uses a few helper methods:

IEnumerable<Type> GetConcreteTypesAssignableTo<T>()
{
    return
        Assembly
            .GetExecutingAssembly()
            .GetReferencedAssemblies()
            .Select(name => Assembly.Load(name.FullName))
            .SelectMany(assembly => assembly.GetTypes())
            .Where(type => typeof (T).IsAssignableFrom(type))
            .Where(type => !type.IsAbstract);
}

bool TypeIsNotDerivedFrom<TBase>(Type type)
{
    return !(typeof (TBase).IsAssignableFrom(type));
}

string AggregateTypeNames(IEnumerable<Type> types)
{
    return
        types
            .Select(type => type.Name)
            .Aggregate(new StringBuilder(),
                       (sb, name) => sb.Append(name + " "))
            .ToString();
}

Of course the test isn't so simple if controllers might use different base classes (think asynchronous controllers), and I'm sure some people question the value of a test like this in any case. Right?

Print | posted @ Tuesday, June 29, 2010 9:12 PM

Comments on this entry:

Gravatar # re: Enforcing a Base Controller
by Wyatt Barnett at 6/30/2010 10:18 AM

But what if the junior devs skip the tests (as they are wont to do)? Then you can be even more insidious and enforce it in the controller factory too, so their stuff will blow up in the debugger.

Yeah, I've had lots of bad junior devs . . ..
  
Gravatar # re: Enforcing a Base Controller
by scott at 6/30/2010 1:05 PM

@Wyatt - how have you been? Yes, controller factory would be an easy place to check.
  
Gravatar # re: Enforcing a Base Controller
by Nick at 6/30/2010 1:21 PM

Another thing that can help is to modify the T4 template used to create Controllers so that the base class inheritance is automatically wired up from the start. I've had good results from this in the projects I work on.
  
Gravatar # re: Enforcing a Base Controller
by Caio Kinzel Filho at 9/15/2010 4:39 PM

@Wyatt: if a dev forget to run tests, that is why we have CI right?! :)

Also, what you guys think about IoC interception features to register those action filters?
  
Gravatar # re: Enforcing a Base Controller
by Caio Kinzel Filho at 9/15/2010 4:43 PM

@Wyatt: if a dev forget to run tests, that is why we have CI right?! :)

Also, what you guys think about IoC interception features to register those action filters?
  
Comments have been closed on this topic.
Scott Allen
Posts - 869
Comments - 4493
Stories - 14