Using Rhino Igloo

You have probably never heard of Rhino Igloo it wouldn’t surprise me my knowledge of it was born out of curiosity while browsing the Rhino svn trunk. What Rhino Igloo is I would describe as an in the middle framework for web applications with web forms on one side and a full MVC solution (ASP.NET MVC, Monorail) on the other.

Why would i use this instead of webforms…

…the answer lies in why we have MVC frameworks in the first place… Separation of Concerns Rhino Igloo makes it easy to do the right thing and by that I mean structuring your web app so that your View (this includes Code Behind as that class inherits from Page!) is not responsible for everything, only in presention concerns.

Why would i use this instead of a full MVC framework…

…easy you wouldn’t, Ayende makes it very clear that if you can go down the MVC route then do so this framework was built out of a constraint having to use webforms so if this constraint is not present go and use a full MVC framework.

What makes it useful

Opinionated

This framework has strong opinons about how things should be structured and this good as it allows it to make decisions itself which leaves us to concentrate on getting business concerns instead of plumbing.

Let me give you and example, in Rhino Igloo IoC is built in out of the box, it uses Castle Windsor to accomplish IoC so given you have configured Castle Windsor (Binsor is great for this!) your dependencies will be in place at the time a request is made, so if you have a controller class with a dependency on an IRepository<Foo> this will be set for you without any code.

And another, Rhino Igloo gives you base classes to inherit from to plug the IoC into, most notable are BasePage & BaseController (there are others that map to other view artifacts such as BaseControl, BaseWebService) one of the other opinions is that given that you have a page that has a public set property of a class that inherits from BaseController it will be automatically injected via the Rhino Igloo Facility.

Communication between layers

In Rhino Igloo there is a Scope object this object is what makes the layers communicate with each other easier it holds data from the Request either from session, querystring, form values etc… this means that your controller can use this object to quickly get at data sent through. The scope object also allows error details to be set that the view can use to display.

Easier unit testing

Because you have Separation of Concerns testing is made easier, and as an added bonus there is a IContext that is used instead of the HttpContext directly this means you can use the provided FakeContext to aid unit testing.

Binding attributes

One really neat feature Rhino Igloo provides is attributes to enable binding to data provided in the Scope object this inludes the [Inject] and [InjectEntity] attributes, the first one will automatically set the value of a property to what is stored in the Scope object for instance:

// in view


// in controller
[Inject]
public property SomeValue
{
    set {someValue = value;}
}

Assuming that I set the text in SomeValue textbox to ‘Foo’ this would now be placed in the someValue field in controller, also note that these attributes can deal with the is mangling that asp.net does for master pages.

But that’s nothing let’s say we have an edit screen for an entity say Project:

// in view: various inputs

// in controller
[InjectEntity(Name="id")]
public property Project
{
    set {project = value;}
}

Now what this will do is take the “id” from the scope object (you can also specify if the value is in session instead) and then make a call to Castle ActiveRecord to retrieve the entity from the database matching the id provided in the Name property, now that is very neat (eager load can also be set).

How to structure

You would usually end up with 3 projects:

  1. A standard ASP.NET web application or website to contain the screens, presentation logic and other presentation concerns
  2. A Controller class library which would house your controllers that would perform orchestration between the Model objects it would probably contain your Repositories if your using that pattern instead of Active Record.
  3. A Model class library which would contain your domain objects, Rhino Igloo makes a lot of user of Castle ActiveRecord so they should be decorated as ActiveRecord classes.

 A note about Castle ActiveRecord

Some may be put off by the use of Castle Active Record as you would suspect that your domain objects would be not testable I can assure that this isn’t the case this framework has been designed in such a way that you can new up an object without having to supply persistence knowledge (connection strings, db connections, config etc…) so you can test your objects as you would normally.

What your then going to say is “ok, so I can test the domain classes but how can I test retrieving, saving, udpating etc… as these are static methods on the domain objects” this is a valid point and here is how I have dealt with it, I use a hybrid approach:

My domain objects inherit from the ActiveRecordBase<> my own entity base class and have there mappings applied via attributes, my controllers use the Rhino Commons IRepository <> classes for persistence this enables me to mock out the repositories and allow easy unit testing.

Summary

I really like this framework it’s like webforms on steroids, it’s value lies in it’s ability to deal with 99% of the plumbing so you can get real work done! I’m working on a sample issue tracking web application using this framework and was able to get a edit screen up and working within a couple of hours with just webforms it would be a lot, lot longer!!

The only thing lacking is documentation it’s one where your probably going to want to crack open the code to see what’s going on, but one great thing is the detailed exception messages you get which usually give you enough to get it sorted straight away, if only the BCL exceptions were this easry to understand :-)

Where can I find out more