The Struggle with Rhino Commons

by mheydt 6. August 2008 23:25 >
I've been doing quite a bit of messing around with Rhino Commons the last few days.  I really like the ability it has to let you use Castle ActiveRecord without needing to derive from a base class, to provide access to objects through the Repository<T> class, and to not have to use NHibernate XML configuration files (yuk).

However, one of my struggles with it is that the library assumes that you are in a web app, as you must derive your application class from the UnitOfWorkApplication class, which is itself derived from HttpModule.  Well, this is a problem if you are writing a console app, service, or other non-web application, as the UnitOfWorkApllication class does a lot of setup in its constructor that is needed to use all of the cool features of the library.

So, after much diving into the source code to figure out what's going on (there is almost no documentation on how this library actually works), I was able to write my own application class, appropriately called GenericUnitOfWorkApplication, which can be used in non-web apps (specifically, console apps).

As an example, here is my sample console application which show you how to use this class, while storing a new domain object in the database and then iterating across all of them:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Model;

using Rhino.Commons;
using _42Spikes.Rhino.Commons;

namespace TestConsole
{
    class Program : GenericUnitOfWorkApplication
    {
        static void Main(string[] args)
        {
            new Program().run();
        }

        private void run()
        {
            UnitOfWork.Start();

            Repository<User>.Save(new User("Mike Heydt"));
            
            With.Each<User>(
                Repository<User>.FindAll(), 
                t => Console.WriteLine(t.Name));

            UnitOfWork.Current.Dispose();
        }
    }

    public abstract class With
    {
        public delegate void operationdelegate<T>(T o);
        public static void Each<T>(
            IEnumerable<T> objects, 
            operationdelegate<T> f)
        {
            foreach (T i in objects) f(i);
        }
    }
}
You can download this entire solution (short of the database) here.

What's going on there is that the Program class derives from my GenericUnitOfWorkApplication class, and when its constructor is run it does all the initialization of the Castle and NHibernate stuff that the UnitOfWorkApplication class does, minus all of the web stuff (like setting up things to manage unit of work mapping to ASP.NET sessions).

The down side of this is that the unit of work is not set up automaticaly, and you need to do it yourself.  Oh well, a small price to pay I think for this great functionality.

And I really like the brevity of this code and now much functionality it has in just a few lines.  Also note my use of a custom With class to apply a lambda function to each element of the database, which I think is quite nice syntax.

Just thinking out loud here, I still think that there are a few things things that I still need to do with this code:
  1. I like that the original UnitOfWorkApplication would map units of work to the session automaticaly.  It's only a few lines of code up there, but it would be nice if this could somehow be automatic.  I think the solution to this is to use PostSharp to apply an aspect to specific methods that automatically create the UnitOfWork.  That would be cool.
  2. This class is still a problem in an application like WPF where your app object needs to derive from a framework class, so this class is not really of use in that situation.  However, there is nothing magic about this class as it does not have to be your base class, you can create a singleton instance of it in your app.  All that is needed is the initialization code run in the constructor.
Which leads me to wonder about the use of AoP.  It would seem to me that you should be able to automatically inject this functionality into your application class.  I'll have to look into how to do that with PostSharp.

Tags:

.Net | ActiveRecord | ALT.NET | AoP | C# | Castle | Rhino

Starting a project with Alt.Net

by mheydt 3. August 2008 18:21 >
I'm starting a new project at a client tomorrow, and I think I'm going to go with a lot of Alt.Net stuff on it.  Specifically, I'm looking into using:

  • Visual Studio 2008 SP1
  • .NET 3.5 SP1
  • PostSharp (for AoP)
  • Rhino Commons (for simplifying access to NHibernate and such)
  • Castle Windsor (IoC and DI)
  • Rhino Mocks (Test Mocks)
  • NHibernate (Database Access)
  • MbUnit (Unit Testing)
  • NLog (or log4net)
I actually would really have liked to try Linq, but I'm using an Oracle database so that goes right out the window.  I don't even want to try to use EF as I don't need that much of a hammer on this...

I've only got a nominal amount of database reading and writing, so I think I'm going to front this access with the Rhino Commons and Castle Active Record.  I really don't want to write any ADO.NET or NHibernate XML files, so this looks like a good way to go.  I also want to use DI to be able to inject either database mocks or actual data classes into tests.  I want to also be able to run this in disconnected mode, so some mock data would be great when provided through DI.

I've used MbUnit before, so I'm staying with that, although I'm going to move up to the new version which apears to have some more features.

The big thing I want to move into is the AoP model (as well as DI).  I just got the latest version of PostSharp installed and it worked great, at least with initial tests.  I'm big on logging in the applications, but I really have been wanting to do cross-cutting instead of explicitly coding it all over the place.  This looks like it will solve this nicely for me, as well as combined with some DI I should be able to inject null loggers into the system for optimization.

Tags:

.Net | ALT.NET | AoP | C# | PostSharp | Dependency Injection | MbUnit | NLog | Rhino | Castle | ActiveRecord

about the author

I'm a .NET, XAML, and iOS polyglot that loves playing with new things and making cool and innovative stuff.  I am also a Mac junkie.

I am Principal Technologist for SunGard Global Services in NYC, in their Advanced Technologies practice, and I work extensively with SunGard's energy and financial customers.

Note the the posting on this blog are my own and do not represent the position, strategies or opinions of SGS.

twitter

I can't stop thinking big!
Sunday 1:08AM via WindowsLive
Just watched Moneyball. That's my pick for best movie this year.
Saturday 3:51PM via WindowsLive
@vincebelpiede: Report: Skype For Windows Phone Beta Imminent http://t.co/KYNjgg1L#mhtnd
Wednesday 8:39AM via Twitter for Mac
@mashable: Kinect Fusion Will Turn Gaming (and More) Into a 3D Fun House - http://t.co/Ihrq2fY2#mhtnd
Wednesday 8:39AM via Twitter for Mac
New Kinect SDK: http://t.co/57MvA5L5 #mhtnd
Wednesday 8:39AM via Twitter for Mac
Follow me on Twitter

recent comments

None

month list