We’ve downloaded and installed Monorail and had a look at the solution that the wizard generated for us. Now we are going to add a new controller.

In this series of posts we will start to build an application but for now I just want to see what is involved with adding a new controller and associated views and maybe lean on the Windsor integration a bit. As we move towards building our application we will move over to a test first driven approach and explore how testable Monorail is.

So for now, without further ado, let’s add a new controller.

The application I want to build through this series is going to be a book lending service. I have a load of development focused books that I recommend and lend to colleagues at the contracts I work at but I occasionally forget who I’ve lent books too so this application will help relieve this burden (and we’ll see if we can add some real value to the app as we progress).

So for now I would like a way of just taking in a list of Books (our model) and show them in the view, all the while coordinating this activity through the controller.

So first up, we’ll create a BookController and we’ll inherit from BaseController for now. We’ll then add an Index method. You should now have this very empty controller:

   1: namespace BookLendingService.Controllers
   2: {
   3:     public class BookController : BaseController
   4:     {
   5:         public void Index()
   6:         {
   8:         }
   9:     }
  10: }

We now need to add the associated view by adding a new folder under Views called Book and then we need to add an Index.vm file. Add it as a text file so it is empty.

Now we’ll build it and view the site by navigating to /book/index.castle. We should expect to see a page with just the existing layout applied to it as we are inheriting from BaseController. Instead, we get an error page.

Controller not found. Area  Controller Name book - Windows Internet Explorer

The reason for this is that because we enabled the Windsor integration we now need to register our controllers into the container. Castle Windsor is an Inversion of Control container for enabling us to use Dependency Injection. This will help resolve our dependencies but for now we have introduced a slight bit of pain (for long term gain) by adding an extra step to the process.

The Windsor configuration is held under the config folder. The one we need to add to is the controllers.config file. Open it up and add the following line:

<component id="book.controller" type="BookLendingService.Controllers.BookController, BookLendingService" />

You’ll need to change BookLendingService to whatever you’ve called your application but apart from that you should now be able to build the app again and view the page.


Now we’ll extend this to get a list of books, so we need to introduce our Book model. For now our book will have a title and description. This new Book class will be added to the Models folder:

   1: namespace BookLendingService.Models
   2: {
   3:     public class Book
   4:     {
   5:         private string title;
   6:         private string description;
   8:         public Book()
   9:         {
  10:         }
  12:         public Book(string title, string description)
  13:         {
  14:             this.title = title;
  15:             this.description = description;
  16:         }
  18:         public string Title
  19:         {
  20:             get { return title; }
  21:             set { title = value; }
  22:         }
  24:         public string Description
  25:         {
  26:             get { return description; }
  27:             set { description = value; }
  28:         }
  29:     }
  30: }

In our controller we’ll just create a dummy list of books within the index method and assign it to a books property bag item.

   1: using System.Collections.Generic;
   2: using BookLendingService.Models;
   4: namespace BookLendingService.Controllers
   5: {
   6:     public class BookController : BaseController
   7:     {
   8:         public void Index()
   9:         {
  10:             List<Book> books = new List<Book>();
  11:             books.Add(new Book("Our First Development Book", "This is our first development book to go into our list of books"));
  12:             books.Add(new Book("The Pragmatic Programmer", "A fantastic book that is as relevant today as it was yesterday. Highly recommended."));
  13:             books.Add(new Book("Working Effectively with Legacy Code", "Another fantastic book which now applies to this application as we aren't writing tests."));
  14:             PropertyBag["books"] = books;
  15:         }
  16:     }
  17: }

And in our view (book/index.vm) we can now iterate over our collection of books and display them in the view.

   1: <h1>Our Book Listing</h1>
   3: <ul>
   4: #foreach ($book in $books)
   5:     <li>$book.Title</li>
   6: #end
   7: </ul>

And a quick build and refresh of our page gives us our listing of books by title.


And that’s it. We’ve now added our first controller, an initial view for listing out our books, and a starting book model. At the moment it is very raw but we have something we can expand upon.

I think the next post (it’s running late and I’m not working to a set plan here – so is likely to change) will be looking at moving out how we get our list of books in the controller into a BookRepository, wiring that up via Windsor, and maybe seeing if we can get rid of some of the configuration pain by using auto registration of our controllers.