Los Techies : Blogs about software and anything tech!

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!

Kick It on DotNetKicks.com
Posted Jun 06 2008, 07:40 AM by schambers

Comments

DotNetKicks.com wrote Getting up to speed with the Castle.MonoRail trunk
on 06-07-2008 2:18 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

David Brown wrote re: Getting up to speed with the Castle.MonoRail trunk
on 11-11-2008 4:22 PM

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)

schambers wrote re: Getting up to speed with the Castle.MonoRail trunk
on 11-16-2008 11:30 PM

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:

RoutingRules.Register(RoutingModuleEx.Engine);

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

... wrote re: Getting up to speed with the Castle.MonoRail trunk
on 02-07-2009 4:33 PM

good site!

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems