I think what the Pro ASP.NET MVC book means is that, by referring to a route by name you have now created a dependency on a particular route definition, rather than relying strictly on the action and controller that will be called.
The route is what determines the shape of the URL. If you create a link by using a route name, you are literally saying "I want the URL to be this shape," rather than saying "I want the URL to invoke this functionality" and letting the route engine decide which route is most appropriate.
Whether or not this makes sense in your particular application ultimately depends on your needs. Using a named route creates a level of indirection which allows you to change both the shape of the URL, and the controller/method that gets called, by merely changing the entry in the route table.
As to the coupling aspect, using a named route does tightly-couple the links to that specific route because no other route would be eligible, and because it requires the view to have knowledge of that specific route. Whether that is a problem or not, again, depends on your needs. If that coupling is a desirable feature, it doesn't really matter whether it is "tight" or not according to someone else's opinion.
I'm going to answer my own question after a day of research. In the end this ended up looking more towards cron jobs which support MVC web applications (which isn't exactly the same as my original question but yielded some interesting information none-the-less). Anyway, here's what I found:
Q. The concept of routing all requests to one file is a little bit redundant because there can only be one entry point?
A. Correct, it is redundant because command line applications can only have one entry point, the executable file itself. You do not need to use the Front Controller pattern in your executable file unless you have sub commands. A lot of simple command line applications are essentially modelled in the same way as a large Bash script. You may want to use the Front Controller pattern if your command line application has sub commands.
Q. It also feels to me as though the concept of routing using controllers and actions is a little bit odd as well. When I have stuck to the MVC pattern with command line applications I almost always end up with one controller with only one or two actions. This seems like a signal that I am not using the front controller (or possibly even the MVC pattern) correctly?
A. That is also correct. If you are building command line applications to support MVC web applications it does not make sense to put your command line application logic inside a controller. In terms of a web application, controllers are for web requests, not command line applications. It should instead go in its own class. Sometimes these classes are referred to as "Tasks" or "Commands" or "Console Commands" within web framework communities.
Try leaving your controllers just for web requests and adding those sort of things to a Commands
namespace or similar. There is one caveat here though, it is perfectly fine to use the M from MVC (Models) in your commands however. From my research it appears uncommon to utilise the V (views) in console commands either, just handle the output with simple echo
s and such.
Within your Command
class it appears that it is very common to have only one method called run
or execute
. This contains the logic of your command and this leads onto your next question.
Q. Is there a better way to handle routing and dispatching requests within a command line application?
A. Yes, leave the MVC pattern alone for a web frameworks as it works well. For running cron jobs add another C to your acronym, that C should represent the word Console. In this new MVCC (that it used in jest, I'm sure that is already a proper acronym for another pattern) web requests come in through a front controller and so on as usual. For cron jobs create a second entry point (outside of the webroot directory) which triggers a specific Console class's run method to be executed.
I hope this will help someone, I've included some suggested reading material below:
http://maxoffsky.com/code-blog/practical-laravel-using-cron-jobs-in-laravel/
http://symfony.com/doc/current/components/console/index.html
http://book.cakephp.org/2.0/en/console-and-shells.html
https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
Best Answer
The best thing for you to do is just to start with the default MVC scheme - where controllers and actions are 'allocated' by URL convention, with the first part of the path determining the controller, and the rest of the URL (and the request type, e.g. GET or POST) determining the action that'll be called.
Whilst at first this seems like it must lead to a 'mess' the reality is that most websites don't actually require loads of controllers, and certainly don't require loads of actions.
Sometimes you might wish to do some clever stuff to split one controller into two, whilst keeping the URLs the same - e.g you might have:
~/Products
going toProductsController.GetProducts()
~/Products/{id}
going toProductsController.GetProduct(id)
But then, let's say you have reviews of products too, you might have
~/Products/{id}/Reviews
going toProductReviewsController.GetReviews(id)
This could be legitimate since reviews functionality might require quite a lot of code, which isn't directly related to the products themselves.
That said, the motivation for splitting controllers shouldn't be to keep a code-file small (you can do that with partial classes), it should be to keep to a single-responsibility principle; that is - a controller should have responsiblity for single section of your site. The Users controller should not also be used for your homepage.
Don't spawn a new controller for everything you do, consider it based on the entity that the controller will operate on or provide details of (e.g. products, users etc). Thinking URL-first and then using that as the basis for new controllers is a very good starting point, because ultimately you want your site to be easily navigable by search engines as well as users.
The beauty of MVC, also, is that with the separation of controllers from the route patterns that trigger their actions, you can completely change the URL structure of all your existing code just by changing the routing. For that reason it's particularly important to remember always to use the
UrlHelper
for generating URLs to other actions, andHtmlHelper
'sActionLink
andRouteLink
operations in views for generaing cross-links; these honour routing, and so take away a lot of the pain associated with re-structuring a website at the URL level.