23

I find it ridiculous that MVC doesn't recognize a controller unless it has 'Controller' appended to the class name. This answer mentions the ControllerDescriptor and ControllerTypeCache as the two places in MVC where this convention is set up.

My question is why? It's clearly not a convention over configuration thing, as IsControllerType in ControllerTypeCache checks that the class:

  • Is public
  • Is not abstract
  • Implementes IController
  • Ends with "Controller"

Does anybody know the reason for this? After all controllers are likely to be in an actual MVC project, in a folder named 'Controllers', and a simple double click on the file will show us that the class inherits Controller.

Just seems silly to me - but I was wondering if there is an actual reason they have done this.

EDIT

Just seen this blog post by Phil Haack from yesterday where he discusses the decision this convention - he is of the same mind of me - Probably a bit pointless!

Community
  • 1
  • 1
jcvandan
  • 14,124
  • 18
  • 66
  • 103
  • 1
    http://stackoverflow.com/questions/266106/why-are-the-controllers-on-asp-net-mvc-name-based?rq=1 (not the accepted answer) –  Jul 19 '12 at 09:23
  • 2
    **There's no convention that controllers have to be in the *Controllers* subfolder.** Actually Asp.net MVC OOB processing looks for types everywhere in all assemblies used by the app. So you controllers can be anywhere. Asp.net MVC project template provides this folder structure to make it easy for developers to have at least some basic application structure. – Robert Koritnik Jul 19 '12 at 09:23
  • Because MVC follows Convention over Configuration ! – Anand Jul 19 '12 at 11:40
  • @Anand - if that was true then you wouldn't have to implement IController, it would just assume that you have implemented the appropriate methods, and only check the type name – jcvandan Jul 19 '12 at 13:06

3 Answers3

18

Custom controller factory

You can always provide a custom controller factory that will resolve these classes differently. And I do agree that controllers need no Controller type name appending because after all they're just like any other class. Their OOP ancestor type defines them as controllers anyway (IController, Controller...)

Visual Studio maybe?

Although it may have something to do with Visual Studio. Similar to Attribute classes. Maybe Visual Studio wouldn't provide additional context menu items to classes that don't end with Controller. When being in controller action you can easily navigate (or create) to the matching view.

Conventions are good

So say the experts and I do agree. There are other conventions like these in .net framework as well but people don't complain about them.

Think of collections, dictionaries, attributes, lists and other types that also use similar suffixes without particular reason. They'd work either way, but they're much easier recognisable by their users - developers - who instinctively know how they should work and when to use them.

Type clashes as per Asp.net MVC team

Imagine having a ProductController that likely handles Product application model entity instances. By not having the controller naming convention, we'd have two types with the same name hence would always have to provide namespaces to distinguish between the two. But because we do have this convention this is not necessary and no type clashes occur.

public class ProductController : Controller
{
    public ActionResult Index()
    {
        // we'd have to distinguish this Product type here
        IEnumerable<Product> result = GetProducts();
        return View(result);
    }
    ...
}
Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • 1
    I agree that conventions are good and they are present throughout .NET for a reason, but most conventions aren't enforced, I just find it a strange decision to enforce the convention in this case as there is absolutely no need. A dictionary, list etc will be used throughout an application, whereas in 99.9999999% of the times controllers are going to be in the same place. – jcvandan Jul 19 '12 at 10:37
  • 1
    @dormisher: that is true, but with those 99.9% of times it doesn't hurt to have convention but the rest 0.1% benefits lots by them. So let's have a convention. – Robert Koritnik Jul 19 '12 at 10:55
  • 3
    @dormisher: **Even more important**: as Asp.net MVC team says, this convention has been introduced, because you may have a `ProductController` class that will likely be handling `Product` application model class. If there was no *controller* convention, you'd have type name clashes and would always have to provide namespaces to distinguish between the two. By having *Controller* suffix on controller types, this is not necessary. – Robert Koritnik Jul 19 '12 at 10:57
  • @dormisher: I added this additional info to my answer that explains type clashes. – Robert Koritnik Jul 19 '12 at 11:02
  • @dormisher: It's interesting that you up and downvoted my answer... :) If you've changed your mind, you should click on the previously clicked vote arrow not the opposite one. :) – Robert Koritnik Jul 19 '12 at 12:58
  • 5
    also I take your point about the type clashes, that is a good enough reason I think – jcvandan Jul 19 '12 at 13:06
0

First 2 are needed so that mvc can instantiate the controller, 3rd is needed so that mvc knows how to use the controller (to call Execute method), and 4th I guess is simply to find the type faster.

frennky
  • 12,581
  • 10
  • 47
  • 63
  • Nicely put, but I suppose that #4 is actually *the convention*... Everything else is plain old OOP. – Robert Koritnik Jul 19 '12 at 09:24
  • I understand why the first 3 are needed, but this is exactly my point. The class does NEED the first 3 to work - whereas the 4th just seems superfluous to me. By all means have the convention of appending 'Controller' to the class name when we add a controller via a VS wizard, but to bury that as a requirement in the framework so that a controller won't work if you don't adhere to the convention? Strange decision imo – jcvandan Jul 19 '12 at 10:41
0

Yes conventions are good, but I don't think this is a matter of convention. It's a matter of selecting a good name from the solution domain for the pattern one is using.

For example, if the UX of dealing with products involves a list then you can simply call the controller ProductList and it need not be confused with List. As human beings we easily disambiguate everyday based on context and naming in software should be no exception. Now the role of a controller is to coordinate. In the case of our ProductList. It will coordinate actions like ProductList.sort(byField), ProductList.delete(product).

As far as taking advantage of the the concept of convention over configuration, one can do that at a meta-level. In .Net one could use an attribute to identify a controller or a model.

What's the big deal? Stating the pattern in the name invites lazy naming and thus lazy modeling. A name is not just a name, it selects a concept that you're using to model the solution domain whose meaning drives decisions about what code represents that concept and what other code that code is coupled to. The more generic and/or ambiguous your names are the more you invite your design to be extended and changed in ways that are harder to maintain.

Aeden
  • 195
  • 9