Going Controller-less in MVC: The Way Fowler Meant It To Be

This is sort of a stream-of-consciousness post. Several folks have been asking me what I mean by ‘Controllerless actions’ and what I’m thinking about doing in FubuMVC.  The conversation has already started publically on twitter, so I thought I’d try to capture a brain-dump of my thoughts in a blog post so the conversation can continue.  This post likely won’t be up to my normally high (read: barely legible) standards. Please forgive.

Before we go further, read this:

http://www.martinfowler.com/eaaCatalog/frontController.html

And then view this:

public class ProductController : Controller
{
    private IProductRepository _repository;

    public ProductController()
    {
        /// That is the only point you need to replace
        /// if the data source changes.
         _repository = new EntityProductRepository();
    }

    public ProductController(IProductRepository repository)
    {
        this._repository = repository;
    }

    public ActionResult Index()
    {
        return View(_repository.GetAll());
    }

    public ActionResult Create()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
    {
        if (_repository.Create(productToCreate))
            return RedirectToAction(“Index”);

        return View();
    }

    public ActionResult Edit(int id)
    {
        return View(_repository.Get(id));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Product productToEdit)
    {
        if (_repository.Update(productToEdit))
            return RedirectToAction(“Index”);

        return View();
    }

    public ActionResult Delete(int id)
    {
        return View(_repository.Get(id));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Delete(Product productToDelete)
    {
        if (_repository.Delete(productToDelete.ID))
            return RedirectToAction(“Index”);

        return View();
    }
}

I’m pretty sure this ProductController is not exactly what Martin Fowler had in mind.  Yet, it’s probably an actually cleaner example of what most controllers that are currently being written “in the wild” for ASP.NET MVC and MonoRail (the two most popular MVC frameworks for .NET) look like.

ProductController is a somewhat monolithic controller in that it has many actions.  It’s structured this way for several different reasons, a few of which I’ll list here:

  • The limitations of the framework upon which it’s built.  ASP.NET MVC, MonoRail, FubuMVC, and others are structured around controllers and actions (yes, even the venerable, estimable Ruby on Rails [peace be upon it] has this mindset to one extent or another).
  • The limitations of our imaginations: That’s how we’ve always done MVC!
  • The habit of doing Model2 style MVC (from which the Heavy Controller/Action paradigm comes)

Reading Fowler’s ideas on Front Controller, and looking at these Model2-esque controllers and actions, I scratched my head and said, ‘Huh. That isn’t right!’

Model 2

Model2-style MVC is concerned primarily with whole request handling and/or whole page rendering.  This was OK in the days of non-AJAX whole page post-backs (uphill, both ways, in the snow, with bare feet).  But in the modern day of heavily templated, composite UIs (think ASP.NET WebForms MasterPages, Spark Layouts, Partials, etc), and with heavy AJAX use for browser-initiated partial updates, the whole-page rendering concept doesn’t really hold up.

We usually end up contorting and bending the framework to do things that don’t really hold up that well under the Model2 way of thinking.

Front Controller

In the Front Controller pattern, the only “Controller” present is the dumb front controller that has two methods on it: Get() and Post() and you could probably just boil those down to HandleRequest().  If this sounds oddly reminiscent of IHttpHandler, you’re thinking correctly.  An IHttpHandler is, in one manner of speaking, a Front Controller.  Properly implemented, the Front Controller would load a series of commands for that particular URL/request context and then execute them either via round robin or via chain-of-responsibility (in serial).

In ASP.NET MVC, MonoRail, FubuMVC, and several other MVC frameworks for .NET, the Controller Action is essentially one BIG command that handles almost all aspects of the request.  Action Filters and FubuMVC’s Behaviors serve as a way of achieving the more compositional benefits of Commands, but they both have some limitations.

If you’ve been doing any serious MVC work with any of the popular frameworks recently, you will have certainly felt the pain of controller actions getting too large, or having too many concerns.  You may also have noticed that your views require data that’s otherwise totally unrelated to the current request (i.e. the user’s current login status for a request to retrieve a list of all products in the persistence store).  So you might use Action Filters or FubuMVC Behaviors to compose all the data the view will eventually need.  Action Filters, being attributes on the Action and thus explicitly declared, present a strong challenge to proper compositional assembly of the data needed by the view for that request. FubuMVC behaviors certainly handle this better, but the configuration can get a little messy and verbose wiring them up explicitly or even conventionally to your actions. So they are not without their drawbacks also.

This all leads inexorably to the questions: Why even have a controller at all?  Aren’t actions really just things-to-do in their own right? And aren’t Actions only a part of the responsibility of fulfilling the request (the rest being satisfied by Action Filters/Behaviors)?

What if we promoted that idea of action filters/behaviors, and the stuff-to-do-for-this-request to equal footing – each simply being a command that gets executed for a particular request?

There’s one little tiny problem in that, when in your Master Page, for example, you may need one tiny nugget of information that’s completely unrelated to the current request, but otherwise needs to be satisfied.  Rendering the view, then, becomes yet another command that can actually trigger more commands to be executed.

Explicitly Configured combined with View-Driven Command Resolution and Execution

After several talks with folks like Mark Nijhof, Jeremy Miller, Jimmy Bogard, and others, it soon became clear that we needed to rethink how we were approaching our MVC-based designs and to try to get more in touch with our “Inner Fowler” so to speak (but not too much).

I have observed that there are, in any MVC request, explicit things that need to happen (NHibernate Session-per-Request, load the current IPrincipal for ASP.NET Authorization, load the current user’s culture and timezone information, etc).  There are also things that MAY need to happen based on whether the View needs some particular type of information.  The view generally shouldn’t be making decisions other than to simply declare that it needs a partial rendered (or a MasterPage, etc).  Theoretically with WebForms or Spark views, we could, at config-time, figure out just exactly what information the view and its various partials are going to require. This way you could resolve everything at config-time and avoid any nasty runtime problems with missing information and such. I’m somewhat down on this theory and I’m anticipating this won’t work out like I hope and that there will always be runtime gotchas here.

At any rate, if we have to live with runtime surprises while we flush out this idea, that’s OK for right now.  But I really feel that the general idea (that is, demand-based command execution) is going on the right track.

Explicitly Configured Command Resolution and Execution

This one is easy: Just configure it!  We’ll have a fluent API or some sort of conventional way (or both) of automatically determining which commands need to be executed for a given request/URL.  FubuMVC currently has this with behaviors so this is achievable today, but I think we can do better and I intend to.

View-Driven Command Resolution and Execution

This one is a little tricky since the View will be requesting this at render time, on-the-fly and may result in YSOD’s if something it depends upon isn’t available. 

I’m thinking that the View would have access to the IoC Container (or Common Service Locator as the case may be) and will request something like IFubuCommand<TModel> where TModel is the particular type of model that partial requires. So you might see something like this:

<%= this.RenderPartialFor<LoginStatusModel>().Using<LoginStatusPartial>() %>

The RenderPartialForExpression would then access the IoC container and retrieve an implementation of IFubuCommand<LoginStatusModel> and then pass that to the LoginStatusPartial (which may turn around and request other IFubuCommand<XYZ>’s.

Command Registration

Commands would be registered at config-time via the normal IoC container configuration.  Using StructureMap, for example, you would simply scan all or certain assemblies for any class implementing ICommand<TModel> and load them automatically into the container as handlers.

Diagnostics

This is also somewhat complicated since the views may request different things at runtime (they may request an IFubuCommand<MODEL> where MODEL may not be known until runtime in which case things may go awry.

You could probe the Container for all IFubuCommand<TModels>’s and then simply observe Views as they execute and deliver a report after-the-fact to show what was used, by whom, and how much.  While this won’t necessarily be exhaustive, it would likely help a developer who’s troubleshooting a particular issue (or perhaps a transient, occasional error).

URL Resolution

This is perhaps the biggest change. Since there are no controllers or actions, the URL becomes the only distinguishing characteristic between two “actions” (or chains of commands) to be performed server-side.  That means the URL (or URL stub like /blah/baz/{Id}) becomes a first-class citizen – probably even its own class/type. 

One thought I’ve been kicking around about this is that you would have a class per URL Stub which has c’tor parameters or properties representing the various options of the URL.  For example, consider this “URL object” or “Action object”:

public class EditProduct
{
  // /products/edit
  public EditProduct()
  {
  }
  
  // /products/edit/9
  public EditProduct(int id)
  {
    Id = id;
  }
  
  public Id{ get; set;}
}

And to render a hyperlink to this action, for example, you might: <%= this.LinkTo<EditProduct>(Model.ProductId) %>

or even:  <%= new EditProduct(Model.ProductId) %>

Which is a lot cleaner than: <%= this.HyperLinkTo<ProductController>((p,i)=>p.EditProduct(i)) %>

Wrapping Up

So this is my brain dump and currently the rough plan I’m using to spike out some of these things in FubuMVC.  Some of it is working out, other things I’m still skeptical.

I’d love to hear what you’re thinking with your MVC-based designs.  How are YOU handling the composition problems?

Related Articles:

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

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in Controllerless, FubuMVC, MVC. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.mostlyclean.com Steve Burman

    All of your points about the current MVC frameworks certainly resonate with me.

    Where you suggest a syntax like
    < %= this.RenderPartialFor().Using() %>

    I am currently doing similar with Steve Sanderson’s IPartialRequest implementation. Working well so far and I think something of that flavour is the best solution to the dependent view model issue.

    I am looking forward to any developments in this space in FubuMVC.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    I think it _really_ depends on what you want to do in your view. If it’s a composite UI, then filters are the way to go. Other wise, RenderAction (from the MVC futures assembly) is great for orthogonal information in the views. I really don’t want to muck up my view model just for the header information bar (Welcome Jimmy, [logout]).

    So, your IFubuCommand is ASP.NET MVC’s version of RenderAction.

    But filters just to show common data? Blech, it bleeds concerns into my controller structure.

    Anyway, orthogonal concerns get even worse in regular MVC when you want to do things like attribute validation, then business-rule validation, all of which is still orthogonal to doing the work of the command. We get around it with a “ProcessXyz” method on our base controller class, which then delegates to the real command processor. TEMPLATE METHOD PATTERN GONE HORRIBLY AWRY

  • http://blog.dynamicprogrammer.com Hernan Garcia

    I already started going on a similar path.
    Allthough on top of ASP.NET MVC. A very, very, very rought idea at http://pronghorn.codeplex.com lot’s of thing will change. But in this case the views call for the partials and the partials each know what they need. They all have access to the Container that is injected in the controller (or front controller althought is not unique).

  • http://persistall.com Brian Donahue

    I’ve been really interested in Actions/Commands as first class citizens in the MVC/MVA model for a while (see post last Feb: http://is.gd/15OX2), and am really glad to hear you, Jimmy, Jeremy, et al talking about it. I think this would make an awesome VAN talk for sharing ideas. I played around with a web stack where the request would first be handled by a request action, following the thunderdome principal, and then based on the request (e.g. “accepts” header, or whatever) and the model returned, the framework would execute the appropriate response action. Anyway, very interested to see what you come up with and/or discuss with you all sometime.

  • http://wizardsofsmart.net/author/riles Ryan Riley

    This sounds very similar to what Sebastian Lambla is doing with Open Rasta, except that each HTTP verb would be mapped to an individual command. Is that about right? In other words, and keeping it simple, you would create a handler for a specific URI and verb combination?

  • http://www.assembla.com/wiki/show/snooze Andrew Davey

    Check out Snooze for strongly typed, first-class URL objects:
    http://www.assembla.com/wiki/show/snooze

  • http://screencast.com/t/1BM4yCa8x Andrew Davey

    Also checkout this screencast about composite views
    http://screencast.com/t/1BM4yCa8x

    I think you’re on to something good here.

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Ryan

    You’re right. Sebastian’s been doing a lot of cool stuff and he’s way ahead of all of us on most of this stuff, lol. From what I understand, OpenRasta handles this problem slightly differently. I’m probably wrong, but it seems like it’s a slightly different flavor of this concept. I think there’s still a little room for exploration here.

    @Andrew: I’ll check out that screencast. Thanks! I looked at Snooze real quick and was turned off by the base classes. I’ll dig a little deeper, but I’m convinced that the URL/Action objects should be POCO to the max extent possible.

  • http://elegantcode.com Ryan Kelley

    This sure means a lot of rework! No, seriously I think if we move in this direction it will be much better for all of us in the long run.

  • http://www.aboutcode.net/ Andrew Davey

    No base class eh? Hmm sounds doable. Snooze is based on asp.net mvc, but I’m sure I can make a delegating controller action invoker…
    A layer super type is nice for convenience methods however…

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @Andrew

    If you need convenience methods, use extension methods. Don’t *require* a base class purely for convenience. Providing an optional one is cool, but it should not be required.

  • http://www.jameskovacs.com James Kovacs

    Just thinking out loud… If your request/response pipeline is going to centre around the action and is really about transforming an input request into an output response, wouldn’t a functional language like F# be more suitable for creating this style of front-controller framework rather than an OO language?

  • http://www.lostechies.com/members/chadmyers/default.aspx chadmyers

    @James: Is F# better at retrieving an array of ICommand‘s from the container than C# is? There’s really not that much to do, to be honest.

    It’s all in the configuration. I suppose F# or maybe even Boo or something might be better for that (since it’s really all DSL mucky-muck work).

    At this point, I don’t see a lot of benefit mixing up languages for this and complicating things. very few folks know F#, so it’d be placing an undue burden on the users of the framework for very little, if any, benefit.

  • http://www.jameskovacs.com James Kovacs

    I wasn’t thinking of retrieving an array of ICommand‘s. That can be done easily in many languages. I was thinking more of actually composing and writing the pipeline using F# functions. From my limited exposure to functional languages, they are very good at succinctly expressing transforms, which is essentially what we’re doing. I agree that most developers – myself included – aren’t sufficiently familiar with functional languages to make this a viable choice in the near-term. It was more a philosophical question of whether this style of front controller would be easier to write in a functional language than an OO one.

  • http://jeffreypalermo.com/blog/the-asp-net-mvc-actioncontroller-ndash-the-controllerless-action-or-actionless-controller/ Jeffrey Palermo
  • http://serialseb.blogspot.com Sebastien Lambla

    Hey there,

    yes it’s somehting that has been in OR for a while, the idea that resource types (what snooze calls strongly-typed URLs) are the things that drive URIs.

    That said, as you correctly point out, by default in OR the action semantics is based on the resoure type and the http verb, and from what I understand, your proposal carries the operation semantic as part of the model definition (your EditProduct).

    Laribee suggested the idea of using profiles in OR to let you define various programming models, and is something that i’m investigating. The latest version of OR includes a new way of defining / discovering / executing operations, and so this scenario, like a few others (around controllers with only one methods and public properties for resolution by binders and codecs) should be very easy to support.

    If there’s demand for it, it’d be easy to make such a profile to run fubu on top of OR instead of asp.net, and get the best of both worlds :)

    Seb

  • http://github.com/olsonjeffery Jeff Olson

    Well, everyone else is self-promoting in here, so what the heck. Here’s my take on the problems discussed in this post: http://github.com/olsonjeffery/mercury

    If you’re interested in another (drastically) different approach to the issues of controller/action composition and how endpoints are exposed from the server to the client (which is a big chunk of what the controller/action mapping convention that is so popular in the “non-stupid” ASP.NET frameworks these days is about), you should really check out the marvelous Ruby-based Sinatra (http://www.sinatrarb.com/) framework. The excellent stuff going on in that framework is what is driving my current experiments in ASP.NET.

    Try all you guys want to make MVC “prettier” and more intention-revealing in C#. The problem, though, is this: You’re stuck using a crappy, general-purpose language to try and elegantly express what is really better expressed in other ways. And I don’t think “But! But! Tooling!” is convincing enough of an argument, longterm, to justify this self-flagellation.

    If you look at what the current state-of-the-art is with regard to web apps (rich js client, rich domain), you can pretty much see that the job of the actual web framework (grossly over-simplified: map data to/from the client/server) is 1) narrowly-scoped and 2) highly optimizable.

    Years of pounding the ideas of loose-coupling, SRP, DRY, etc into our heads has given us web applications mappings that are, when you get down to it, pretty damn anemic. All the data-access, behavior, etc lives in the domain or is abstracted out into the app service layer. We’ve (hopefully) broken the cycle of abuse of using retarded server callbacks in rendered views in favor or much more easier testable js (javascript controllers/views, anyone?). We’re using view engines that don’t suck to compose tighter, less-entangled rendered views (that are becoming pretty anemic, themselves, as the js side of things gets more of a share of the the action). So what about what’s left over?

    What I’m saying this: The stuff we code at the web framework level (controllers, actions, behaviors, etc) is pretty damn rote, all in all. In other words: A perfect candidate for a DSL.

    Enter things like Sinatra (or my own solution, which is still incubating and thus not heavily pimped, here).

    You’re gonna be stuck with chestnuts like overloading constructors of a class to model actions as long as you remain in the BDSM box of C# as your only way to do this kind of thing (to get the tired Matrix cliche out of the way: it’s a prison for your mind).

    The domain requires a rich language to be expressed fully; use C# there. The client requires a rich language to be expressed; go ahead and use js or whatever for that, as well.

    But the web framework? Seriously. In statically typed .NET, the most complicated things it does is 1) deliver dependencies to 2) do query/command tasks to ultimately 3) map data to/from the client/server. period. Item 1 isn’t that big of a deal in Ruby because you can monkey-patch that stuff away and bait-and-switch dependencies when testing. Oh yeah, and the web framework probably manages your security and session baggage, as well.

    Anywho, I’ll get off my soapbox, now. I just think that the entire discussion up until this point is predicated on the assumption that the job that web frameworks do is something that really *requires* verbose, convoluted solutions like those that’re prevalent in the debate. We can do better, in my opinion.

  • http://sergiopereira.com/blog Sergio Pereira

    @James, you may want to take a look at Bistro (http://bistroframework.org/index.php?title=Bistro_Framework_Home), which is an F# MVC framework.

  • http://andrewpeters.net Andrew Peters

    “The limitations of our imaginations: That’s how we’ve always done MVC!”

    Not really true. In Java, this pattern has been around for donkeys years. For a good example, take a look at WebWork, which powers the Atlassian apps like Jira etc.

  • http://schotime.net/blog Adam

    I reallly like where this idea is headed Chad. Hope that some samples and code spikes come out so we can begin exploring it further.

    Even just having Controller’s as actions with a Get/Post method is really a great start.

  • http://russiantequila.com alex pedenko

    That’s actually one of the fundemental design principles in Bistro – (as sergio said – http://www.bistroframework.org). Aside from the f# piece (which isn’t a requirement), the major premise there is that you bind controllers to aspects of a url, and multiple controllers service a single request, without being tightly coupled with each other. that way, your url becomes the first-class citizen you describe.

  • Anonymous

    I realize I’m a bit late to this party, but this all sounds like old patterns being re-branded — coming from more of a Silverlight background, I believe this is similar to the “Command Pattern” (http://blogs.microsoft.co.il/blogs/gilf/archive/2008/06/23/command-pattern.aspx), although it seems to be referred to, more often, in MVC as the repository pattern. Would others agree? Or are these patterns vastly different to the extent that they deserve different names?

  • http://chadmyers.lostechies.com Chad Myers

    @SoundLogic: Read the Fowler link in the original post: “The Front Controller consolidates all request handling by channeling requests through a single handler object. This object can carry out common behavior, which can be modified at runtime with decorators. The handler then dispatches to command objects for behavior particular to a request.”

    So yes, Front Controller sits in front and dispatches a bunch of Command Pattern commands. Front Controller != Command, but uses commands.

    Repository is something different as it is intended primarily for database access (at leas the P of EAA version). Though in FubuMVC there is an element of repository-type searching through all model to match routes to actions to views. But that all happens at initialization-time, not at run-time in FubuMVC. In ASP.NET MVC, it happens at run-time (figuring out which controller to execute for a given route).

  • Anonymous

    @Chad: A comparable article was recently posted on LosTechies called “Single Action Controllers with ASP.Net MVC” (http://lostechies.com/derekgreer/2011/04/29/single-action-controllers-with-asp-net-mvc/). Following SRP, Derek creates controllers with single Actions and uses routing to map requests to controllers. I’d would like to hear your take on this approach.

  • http://chadmyers.lostechies.com Chad Myers

    @HoyaBaptiste Yeah, I saw that and commented on Derek’s post. FubuMVC was built to allow ultimate flexibility in defining actions and routes that way YOU want to. I think Joshua Flanagan explained it well in his post “FubuMVC: Define your actions your way” http://lostechies.com/joshuaflanagan/2010/01/18/fubumvc-define-your-actions-your-way/

    Here’s a REST-y kinda controller I did for “FubuDinner” a year ago when I was playing around with rewriting NerdDinner in Fubu:
    https://github.com/chadmyers/fubudinner/blob/master/src/FubuDinner.Web/Actions/Accounts/RegisterAction.cs

    Note that it has a “Query” and a “Command” method that corresponds to GET and POST respectively.

    Notice that Joshua’s post that I linked above is over a year old. And this post is even older. It was nearly impossible in ASP.NET MVC to do what we have been able to do naturally in FubuMVC since the beginning. It looks like only now (2+ years and 3 versions later), they’re able to talk about single-action controllers. I wonder if it’ll take another 2+ years and 3 versions before they can do even half of all the myriad of ways we can define actions in FubuMVC :)