Part II – How does Monorail Work?

There are obviously many things going on under the covers of Monorail. My goal here is not to get into the nitty gritty, but rather approach this from a high level view.

Here is an image (from the Castle website)

image

(this is first time trying to add an image…so we’ll see how this turns out!)

At the top of the diagram it shows a http request being sent to IIS. The ASP.NET engine takes that request and sends it to the corresponding handler. In this case we see that the extension of the file requested is “.rails” (home/index.rails). IIS has a mime type mapping for this extension, and the corresponding web.config must tell ASP.NET what component to call to handle this extension:

<httpHandlers>

     <add
         verb="*"
         path="*.rails"
         type="Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, Castle.MonoRail.Framework" />
   </httpHandlers>

Please note that if you use rails – you must tell IIS to map this extension. An alternative is to use .ashx (ie. if you have a web hosting environment where you can’t control the mime type mappings).

The key to the Monorail system is understanding http handlers. When a url is sent to the web server it processes the request by mapping the extension to a corresponding ‘handler’. In this case, when ASP.NET sees ‘rails’ it is handled by the MonoRailHttpHandlerFactory which is derived from IHttpHandler. IHttpHandler request implemenation of ProcessRequest(HttpContext context). (Learn more about this here.) So, basically the ‘ProcessRequest’ is called on the MonoRailHttpHandlerFactory that carries the HttpContext with it. That points out a key fact about Monorail in that it contains all the HttpContext of that request. When I say that Monorail ‘sits on top of ASP.NET’ that is one the key points, the context is carried with each request!

The job of Monorail is then to create the appropriate controller and invoke the corresponding action which can be seen in the image above.

    public class HomeController : SmartDispatcherController
    {
          public void Index(){}
    }

In this case the url is home/index.rails. Monorail find the matching controller (appending ‘Controller’ on the end), which is the ‘HomeController’. The method ‘Index’ is the Action. For every ‘page’ there is a corresponding action.

Following this action call, the view is created.

Monorail determines the view engine to utilize by a setting in the config files, in this case:

<monorail>
    <viewEngine
        viewPathRoot="Views"
        customEngine="Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine, 
        Castle.MonoRail.Framework.Views.NVelocity" />
  </monorail>

In this article, I’m going to just deal with NVelocity (user guide here). NVelocity is a template view engine. The engine takes a template and data and ‘binds’ the two together to create the output.

The data that is sent to the view from the controller is passed via a ‘propertybag’ (This propertybag is a IDictionary name/value).

ie.

    public class HomeController : SmartDispatcherController
    {
          public void Index()
         {
              PropertyBag["name"] = "Steve";
         }
    }

The view uses the extension .vm (ie. instead of .aspx). Which contains html, etc… this is the ‘template’. So in this case I would have a corresponding view file index.vm which could contain:

<P> $name </P>

When the template engine process the page it injects the key/pair value into the view. The html result would be:

<P> Steve </P>

If you would like the action to render a different view, at the end of the action you can use

RenderView('SomeOtherView')

Advertisements

2 thoughts on “Part II – How does Monorail Work?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s