[this post is outdated – too much has happened since the first CTP]
In this part of the ASP.NET MVC tutorial we will create our own controller factory which will use Windsor to resolve dependencies and supply each controller with a NHaml view factory. Then we will create some simple views and watch the whole thing in the web browser.
Step 1: Setting up the controller factory and automagic dependency injection.
We want to use NHaml instead af that annoying ASPX thing to render our views. If you are unfamiliar with NHaml, I can tell you that it is a .NET port of Haml, Hampton Catlin’s markup haiku project. Actually, it is just a simple, yet incredibly powerful, way of generating XHTML.
Moreover, we want to use dependency injection to bind it all together.
To accomplish those two things, create a new IControllerFactory, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
namespace OnCodeBlog { public class OnCodeControllerFactory : IControllerFactory { static readonly WindsorContainer globalContainer = GetContainer(); private static WindsorContainer GetContainer() { var container = new WindsorContainer(); container.AddComponent("controllers.HomeController", typeof(HomeController)); return container; } public IController CreateController(RequestContext context, Type controllerType) { var controller = (Controller) globalContainer.Resolve(controllerType); controller.ViewFactory = new NHamlViewFactory(); return controller; } } } |
The controller factory is where MVC will go every time a request comes in and needs to be resolved. Usually – depending on whether you have configured alternate routes – an url on the form /[Something]/[SomethingMore] will result in a CreateController call requesting the type SomethingController followed by a call to the function SomethingMore on that controller.
As you can see, this controller factory will use the singleton WindsorContainer to resolve controllers whenever a controller type is requested. That’s cool, because then we just need to register our controllers in the GetContainer method along with any services they may need. You may also configure the container with an XML file, but we keep things simple for now.
Notice how every new controller gets assigned an implementation of the IViewFactory interface – in this case we want to let the controller use NHamlViewFactory, but this suggests that this is the place to go if you want modify which templates you use and which output gets rendered.
Now we just need to make MVC actually use our controller factory. We do that by editing the file Global.asax ( Global.asax.cs actually), inserting the following line in the Application_Start method:
1 |
ControllerBuilder.Current.SetDefaultControllerFactory(typeof (OnCodeControllerFactory)); |
This tells MVC that it should make an instance of our OnCodeControllerFactory when the application starts up.
Step 2: Replacing the existing ASPX views with our fantastic NHaml views.
Now we need to get rid of the .ASPX files in the Views folder in your MVC project. Instead of deleting those files, let’s just rename them to About.haml and Index.haml instead. Say yes to that warning Visual Studio will give you about “the file becoming unusable” or something. Then delete that Site.Master file and create a new text file called Application.haml instead.
Try punching in the following in the Application.haml file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
!!! %html{xmlns="http://www.w3.org/1999/xhtml"} %head %title On Code with MVC %link{href="../../Content/Site.css", rel="stylesheet", type="text/css"} %body #inner #header %h1 A blog .menu %ul %li %a{href="/"} Home %li = Html.ActionLink("About me", "About", "Home") #maincontent _ #footer %p This is the footer of every single plage unless they ask for another layout. |
This is what Microsoft calls a master page, but everybody else call them layouts. This one is written in Haml. Short Haml tutorial: % means make a tag, # means use this id, . means use this class. Div is implied when no tag i specified. So %table.funky#productsTable will generate <table class="funky" id="productsTable"></table>. Indentation actually means something, as it’s how tags are ended. Notice the “_” – it’s where the Haml of your views will be inserted every time a view gets rendered.
Remove the original content from Home.haml and About.haml and punch in something else. My Home.haml looks like this:
1 2 |
%p This is the main content of this site. Here we will put a list of posts. |
– and my About.haml looks like this:
1 2 |
%p My name is Mogens Heller Grabe and I like to code. |
And to spice things up I modified Site.css with styles for some of my tags and ids:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
body { background: white; font-size: medium; font-family: "trebuchet ms", helvetica, sans-serif; color: #000000; margin: 0px; } #header { background-color: #eee; border-bottom: solid 10px #888; padding: 12px; } #maincontent { padding: 20px; } #footer { background-color: #eee; border-top: solid 10px #888; padding: 12px; } |
Step 3: Web site in action.
Now try hitting F5 to open your web site in your default browser (say yes when asked if you want to modify your
web.config file to allow debugging). It should look similar to this:
Try the links – it should work. Try setting breakpoints on the RenderView lines in the Index and About methods in HomeController and try the links again. It should be clear that whenever a request is made from the web browser a resulting controller function call will be made. Which controller and which method is determined by the routes set up in Global.asax.cs.
Next time we will start looking at how to model a blog post.