FubuMVC, Routing, and the Front Controller Pattern | Jeremy D. Miller
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:
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:
- The selected Route calls into its FubuRouteHandler and asks it for an IHttpHandler
- 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.
- The FubuRouteHandler calls into the IBehaviorFactory with the behaviorId and the AggregateDictory to retrieve the outermost IActionBehavior
- 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.
- The FubuHttpHandler just has to invoke the outermost behavior and get out of the way.
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).