FubuMVC

by Mark Nijhof, in SOLID FubuMVC | Sunday, May 31, 2009 | 0 comments
I held a presentation about FubuMVC for NNUG and decided to write down an abstract of it just like I did for my SOLID presentation "Software Development is not a Jenga game" for those who don’t want to listen my almost 2 hour E-VAN talk (I can’t blame you).

FubuMVC


FubuMVC
The Front Controller Style pattern is a pattern described in Martin Fowlers P of EAA book, read more about it here.

FubuMVC
FubuMVC is not build or based upon ASP.NET MVC, it is inspired by it, but it might actually be even more inspired by Ruby on Rails. The one thing that is shared between ASP.NET MVC and FubuMVC is the System.Web.Routing library, which is used for Url rewriting.

FubuMVC
The guys at Dovetail have been extending ASP.NET MVC Beta 3 since they started using it, changing it more and more. Internally this extended version of ASP.NET MVC Beta 3 was called OpinionatedMVC. After a while Chad Myers thought that the ideas and principles behind OpinionatedMVC would be something others could benefit from as well and he started an Open Source project called OpinionatedMVC. This version of OpinionatedMVC was completely rebuild from the ground up not using ASP.NET MVC at all. OpinionatedMVC was later renamed into FubuMVC and continues to grow into a framework with better ideas and principles behind it.

FubuMVC


FubuMVC
Yeah as you can see this blog is created using FubuMVC you can also see the code which is located in the FubuMVC Contrib project. I created/copied it to learn the FubuMVC framework and is mostly based on an other example AltOxite which is also in the Contrib. After some changes in the framework I will be rebuilding it using proper BDD.

So why would you want to use FubuMVC instead of ASP.NET MVC? Well lets look at how this website is build up. What are the different responsibilities?

FubuMVC
First the main reason for the page to exist, the main content. This is what is important for the user browsing the the web page, if this fails all fails.

FubuMVC
Second is the menu, this can be used to navigate the website, here different options may be visible for different user.

FubuMVC
Third is a list of links to my last ten posts that I have published.

FubuMVC
And fourth we have a second list that contains several blog posts from other people that I have read.

FubuMVC
As you can see on this very simple web page there are already minimal 4 different responsibilities that have nothing to do with each other. So instead of putting these different things in one controller (The C in the MVC pattern, to read more about MVC go here) FubuMVC gives us a different approach to deal with these different responsibilities. Lets take a look at how a request is being handled by FubuMVC.

FubuMVC
After the URL has been processed by the Routing engine of the .Net framework a Action Invoker is being called. Depending on the configuration this can be a One Model In One Model Out (OMIOMO), One Model In Zero Model Out (OMIZMO), Zero Model In One Model Out (ZMIOMO) or a Zero Model In Zero Model Out (ZMIZMO) action invoker. The Model is obviously the M in the MVC pattern.

FubuMVC
Here is some dirty work being done for the user of the framework so you don’t have to worry about it. Here FubuMVC is processing the POST / GET data submitted to the web page. Something that normally involves parsing a dictionary using string keys, FubuMVC uses reflection to map these dictionary keys on provided model properties. This enables type safety for using these variables.

FubuMVC
Here is one of the key features of FubuMVC, Behaviors. Behaviors is a decorator around the Model. It can place data in the model or process data provided by the model, or in some cases do something unrelated to the model.

FubuMVC
But look, multiple Models can be placed inside each other, creating a chain of behaviors that are all wrapping the model and each other. Each behavior can do its own thing, do you see where we are going at with these behaviors?

FubuMVC
Then finally after all the behaviors we get to the Controller, you can see there is a prepare input and modify output on each behavior, so you can do something before and after the controller. And for that matter any inline behavior as well.

FubuMVC
Then when the whole behavior chain including the controller have been executed the output is generated. Well generating the output is a behavior in itself.

FubuMVC
But hey the chain is in control of the whole request pipeline so if certain conditions apply a behavior can decide not to continue executing the chain but instead render a different result to the browser.

FubuMVC
But why should I use behaviors, well they are our answer to the previously proposed problem of having to many responsibilities in the controller. Each behavior will have one and only one responsibility and because you can chain them all together you are able to provide the same functionality and still adhere to the Single Responsibility Principle. This also makes re-use much more feasable.

FubuMVC
Here is a very common behavior, this one loads the latest ten blog posts and puts the results in the model. As you can see the behavior is very compact and easy to understand. The behavior_base_for_convenience is a convenience base class that provides the prepare input and modify output functionality.

FubuMVC
This behavior has a different structure as the previous one. This is one of those cool features of a behavior chain, because of how behaviors are all wrapping each other they give you the ability to wrap a whole request in a try catch statement. In this example I am showing you an UnitOfWork implementation. When something in the chain throws an error the whole transaction is reverted. This together with StructureMap makes for a very powerful implementation. StructureMap has the ability to cache an object for the duration of a web request so anywhere where the UnitOfWork is needed you will get the same one. Thus basically ensuring that the whole request is running in the same transaction.

FubuMVC
Convention over Configuration is an other very good reason why you may want to try FubuMVC, it means that whenever there is something that will be repeated you want to tell the framework how to deal with these situation. You don’t want to specify everything, you just want to specify the rule.

FubuMVC
The top example is a rule where FubuMVC can find the controllers in your system, and also how to discover the action methods. Below that is specified what default behaviors should be attached for each discovered action method.

FubuMVC
The top example shows us how we tell FubuMVC where to find the views and partial views when it needs them. And below that we define how FubuMVC will create the URL’s for the action methods it discovered.

FubuMVC
As you can see FubuMVC wants to limit repetition as much as possible, whenever there is something that should be able to be configured using a convention you can trust the framework to try to do so. But what is important is to know that these will be your conventions, not ours. So you can work with the framework how you like to work.

FubuMVC
We don’t want you to burn yourself when dealing with all kinds of magic strings, so we strive to have everything benefit from compiler checking. As I mentioned before processing POST / GET variables is done in such a way, but this comes back everywhere else as well.

FubuMVC
Just take a look at the view displayed above you may notice that there are no magic strings involved. Below is the model that will be provided to the view, as you can see Model.Body is mapped straight from in the view, but take a look at RenderPartial().Using()...ForEachOf(Model.Tags) this will render a partial view of type TagLink for each item in the Model.Tags collection. There is some more pretty stuff in there which I am sure you can figure out as well.

FubuMVC
Well you may have noticed it already but FubuMVC is build keeping in mind all the proper principles like SOLID and DRY. Especially the Single Responsibility Principle, Interface Segregation Principle and the Dependency Inversion Principle are found everywhere in the code. For example an IoC container is used to make DIP easier, by default this is StructureMap, but internally everything uses the Common Service Locator so you can use other IoC containers as well.

FubuMVC
Testability is an important topic as well and a very welcome side affect of adhering all the proper principles is that your code becomes very testable. You have seen the examples and all of them are easily testable, this goes for everything you would create using the framework. And also the FubuMVC code is properly tested.

FubuMVC
But we couldn’t test it all. Yes Chad is also working on an implementation of Spark for FubuMVC so you don’t have to use the ASP.NET render anymore.

FubuMVC
Yes if you have questions or comments, please let me know, I will be happy to hear them, especially the confronting ones.

No comments yet!

Mark is reading

 
Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.