FubuMVC, Routing, and the Front Controller Pattern

Authors’s note:  I’ll be switching to using GistHub for code samples shortly, but bear with me just for now please.

In my last massive post I talked a little bit about how FubuMVC’s behavior model works.  In the interest of length I cut this section about how a FubuMVC application goes from receiving a request for a Url address to the correct behaviors to invoke.  Again, this isn’t something you would deal with while working with FubuMVC, but this is just meant to explain what’s going on under the covers.

For those of you non-Fowlbots who aren’t familiar with the term “Front Controller,” it just means that there’s a component that interrogates an http request, then decides what other class or component should handle the request and hands off the request.  Think of the Front Controller as a traffic cop. 

For FubuMVC we utilize the Routing module built into .Net* as part of our Front Controller strategy.  The connection between receiving a url request and invoking the proper chain of nested behaviors looks like this:

diagram_thumb

I’ll cover configuration at a later time, but for now let me just say that FubuMVC registers a unique Route object for every possible url endpoint in the entire application.  FubuMVC attaches a FubuRouteHandler object to each Route object.  The FubuRouteHandler is more or less just an adapter between the selected Route and the correct behavior chain.  Each FubuRouteHandler is created with a reference to the IBehaviorFactory for the application and the unique “behaviorId” of the top level behavior that handles the Route in question.

        public FubuRouteHandler(IBehaviorFactory factory, Guid behaviorId)
        {
            _factory = factory;
            _behaviorId = behaviorId;
        }

 

IBehaviorFactory is a lightweight abstraction over your IoC container of choice and “behaviorId” is unsurprisingly just the name of the IActionBehavior instance within your IoC container. 

Walking down the sequence diagram above, once a route is selected by routing:

  1. The selected Route calls into its FubuRouteHandler and asks it for an IHttpHandler
  2. FubuRouteHandler uses the HttpContext of the request to set up an AggregateDictionary object used as the lowest level abstraction to request data in the rest of the FubuMVC pipeline.
  3. The FubuRouteHandler calls into the IBehaviorFactory with the behaviorId and the AggregateDictory to retrieve the outermost IActionBehavior
  4. The IBehaviorFactory invokes the IoC container to build the outermost behavior with all its dependencies including all inner behaviors.  The AggregateDictionary is passed into the IoC container as an explicit argument.
  5. The FubuHttpHandler just has to invoke the outermost behavior and get out of the way.

 

Why didn’t we write our own routing engine?

Once in a while I do get challenged about why we use Routing as is instead of writing our own.  I even had one person claim that the necessary Xml configuration to run Routing was intolerable.  So here it is, we use Routing because it’s part of the BCL now, well tested, and it works quite well.  I even took a peek at it under Reflector one day to see if we could use it for something later outside of IIS and lo and behold, it’s relatively de-coupled from ASP.Net internals.  And now you know, I don’t have to reinvent every possible wheel (plus I’m allergic to regex’s).

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in FubuMVC. Bookmark the permalink. Follow any comments here with the RSS feed for this post.