Getting up to speed with the Castle.MonoRail trunk

Over the last couple of months there have been a slew of great refactorings done on the castle monorail trunk. Some of these refactorings were inspired by ASP.Net MVC changes such as the new routing module. I have just now started to play with monorail trunk so I am by no means an expert on the changes that were done there. If you are interested in getting up to speed as well. The best thing to do is get a fresh copy of the monorail trunk and start looking through the source code specifically on Controller, EngineContext, ControllerContext and IController. After looking at the changes for only an hour or so and updating a project up to the monorail trunk, I can already get a good idea of where things logically should belong now.

General Changes

  • The controller class has been split up into Controller and ControllerContext. A good deal of Controller “metadata” has been moved to ControllerContext. In addition, an IController interface has been created that is now used within all the Castle services.

  • RailsEngineContext has been renamed to simply EngineContext.

  • The ExecuteEnum has been renamed to ExecuteWhen which makes more sense to me.

  • Certain services have been removed from the Controller

  • The EngineContextModule has ceased to exist

Routing Functionality

This is the coolest part of the refactorings. Instead of relying on ugly xml configuration for our routes, we can now configure them within our HttpApplication class using the PatternRoute class. This was the hardest portion to find documentation on. There are some postings on the castle project google group that helped me along. You can find the posting here. In addition to reading that, the best way to get familiar with the new routing functionality is to download the trunk and take a look at the Routing tests. They are pretty descriptive and allowed me to wrap my head around them. To outline some of the routing functionality I have an example of a route in one of my applications:

   1: rules.Add(new PatternRoute(“/<controller>/<action>”)
   2:     .DefaultForAction().Is(“index”));

The rules class is an instance of RoutingModuleEx.Engine that you can obtain in your global application. We then pass the Add method a new PatternRoute. This is where we define the route to match.

This route will match anything followed by anything, It will then map anything between <controller>, and pass it along as the controller parameter, and pass along <action> as the action parameter. If no action is passed, a default of “index” will be applied. Specifying a parameter as [something] makes it optional, while <something> is a required parameter. The thing that took me a minute to understand is, when constructing the route, anything you make as a parameter is passed along to the action at hand. This means that if you have a parameter to your action that is someThing, you can place it in your route and that part of the url will be passed along as that parameter. To display this I have another example:

   1: rules.Add(new PatternRoute(“/something/<parent>/<param2>/<param3>/”)
   2:     .DefaultForController().Is(“somecontroller”)
   3:     .DefaultForAction().Is(“view”));

This route is a little more complex. To get a better idea of how this works, take a look at the associated action signature:

   1: public void View(string parent, string param2, string param3);

As you can see from this example, you can name the parameters to pass along to the action. On that same note, you can specify parameters that aren’t included in the url like so:

   1: rules.Add(new PatternRoute(“/area/<param1>”)
   2:     .DefaultForController().Is(“someOthercontroller”)
   3:     .DefaultForAction().Is(“view”)
   4:     .DefaultFor(“someOtherParam”).Is(“someValue”));

In this example we are calling the view action on SomeOtherController that would take a signature as follows:

   1: public void View(string param1, string someOtherParam);

As you can see, the someOtherParam will always have a static value that we define. Not sure if this would be useful to most people but I have already had a use for it when constructing dynamic routes.

One of the more complex parts of the refactorings is definately the routing. There are quite a few posts on them on the Castle Project Users Group and the Development Group so do some searches there if you have more questions about the routes.

That’s it for now. Next time we can dive more into the refactorings and changes on the trunk. Feel free to ask any questions!

About Sean Chambers

I am a Senior software developer from Palm Coast, Florida. An advocate of Domain Driven Design, Behavior Driven Development, creator of FluentMigrator and community activist. I am married to my beautiful wife Erin and am the proud father of two wonderful children. I currently reside at ACI, a local insurance industry/mortgage software company that excels in creating solutions using Agile methodologies.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Where exactly did you place your routing rules in your HttpApplication class? I’ve used the code you provided for directing to a default action, but I continue to get errors like:

    Could not find action named on controller \home

    (The blank space is part of the original error message)

  • David, I should have mentioned that you need to place them in a static class like so:

    public static class RoutingRules
    public static void Register(IRoutingRuleContainer rules)

    then from your HttpApplication you have to pass the RoutingModule instance to your static class:


    It may be different now, been awhile since I used that code.

  • good site!