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')

Intellisense for NVelocity – Monorail

Jonathon Rossi has release an updated version of CVSI (Castle Visual Studio Integration) here – more here.

I’ll be trying it out tonight and will give some input.

Thanks Jonathon!

update: some instructions on installation:

This release is like all the update releases I have made and it only comes with the assemblies, you will need to install CVSI 0.1.0 using the MSI and unzip the files into the installation directory. This allows you to go back to an older build if there are problems.

Part I – Why Use Monorail?

Monorail is a MVC implementation that sits on top of ASP.NET . It is an alternative to Webforms.

“Monorail is a simplification of the standard Webforms paradigm” sums it up quite well. There is no complex ‘page lifecycle’ in Monorail. No ‘postback’ or ‘viewstate’. Instead, it’s a return to the Http protocol of POST/GET and Response/Request

From the W3 on the Http

“It is a generic, stateless, protocol which can be used for many tasks beyond its use for hypertext, such as name servers and distributed object management systems, through extension of its request methods, error codes and headers [47]. A feature of HTTP is the typing and negotiation of data representation, allowing systems to be built independently of the data being transferred.”

Webforms attempts to abstract this away from the developer by giving the illusion of state in a stateless protocol. Whereas Monorail builds on this, there is no attempt to abstract this away. The end result is that it’s easier to work with. With Monorail separating out the controller (the ‘real code’) from the view, which is a template engine with FormHelpers to make developing a rich UI quite easily. (Note: there are several views, but I’m just concentrating on NVelocity, a template engine that was ported from Java and originally written in C)

  • Monorail is extensible and can be used with existing API’s, such as javascript libraries, quite easily. For example, with Monorail I was able to grab the Tab component from the Yahoo UI and have it running on my Monorail page in 10 minutes. With Webforms, you have to fight the page lifecycle, etc… One of the negatives I hear (and I thought myself), was that I’d be out of luck with Monorail because I wouldn’t have my nice friendly controls. What I’ve learned is that I’ve been limited to the complex controls created by others or spent hours coding up my own controls whereas there tons of prebuilt UI components for the web out there outside of Webforms! The key here is how easy it is to integrate these into your solution. Additionally, Castle creates other API’s that co-exist quite easily with Monorail, including Castle Windsor Container (IoC) and Active Record (ORM – sits on top of NHibernate).
  • Monorail helps to enforce the concepts of the ‘Single Responsibility Principle’ and Separation of Concerns by utilizing the Model View Controller architecture. In turn, this allows for a loosely coupled and cohesive design.
  • Monorail supports test-driven development. Controller and the interfaces used in Monorail make it easy to test your code. It includes test harnesses to make it easy to create the controller. A base class is provided, “BaseControllerTest”:

[Test]
public void SimpleControllerAction()
{
     SimpleController simpleController = new SimpleController();
     PrepareController(simpleController, "areaName", "simplecontroller", "index");

     simpleController.Index();

     // Some Assertions here
}

The Castle website includes more examples on NUnit testing: Learn more on testing.

Controllers just handle application flow, models represent the data, and the view is just concerned about presentation logic. Consequently, you write less code and end up with a more maintainable application.

Part II – How Monorail Works

Script#, Ext# – Write ExtJS code in C#

That is quite a title I know – where did all this come from?

1. Chocolate: Nikhil, a programmer for the asp.net team has a blog here that covers Script# Script# is basically the equivalent of the GWT for Java. It allows a C# developer to write C# which in turns creates the corresponding javascript.

2. Peanut Butter: ExtJS library – is a powerful javascript library – very rich!

So, yes, the chocolate in the peanut butter results in ‘Ext#’

Here is a sample result

Let’s just say, there are some very smart people out there 🙂

Pragmatic Unit Testing in C# with NUnit, 2nd Ed., 2nd Edition

I was out on the The Pragmatic Programmers website and saw this title on Unit testing that uses NUnit

New for the Second Edition:

  • Updated for NUnit 2.4 (C#, .NET 2.0, Visual Studio 2005, and Mono)
  • More NUnit assert methods
  • New String and Collection assertion support
  • Better support for multiple-platform development (Mono and .NET)
  • Higher-level setup and teardown fixtures
  • …and more!

I will probably grab this book after reading the chapter on ‘Using Mock Objects’. Using Mock Objects is something I’m getting into and it helps to have some guidance on their usage.