Fluent NHibernate, Counting Entries In A Related Table

I have a simple Fluent NHibernate mapping setup where a parent table has a ‘HasMany’ relationship to the child table.

As part of the parent table, I want to include a property that indicates how many child entries there are, without having to map the child relationship. This is mainly because I don’t want the additional overhead of bringing back each child record, but is also useful for being able to sort by the count.

Turns out this can be achieved quite easily by using the ‘Formula’ function on a mapped property:

Map(c => c.ChildCount).Formula("(select count(*) from childTable where childTable.parentId = id)");

Simple when you know how!

System.Data.SQLite And 64 Bit Operating Systems

An old customer surfaced recently, wondering why a new installation of an old .Net WinForms application I wrote wouldn’t work on their shiny new 64 bit system.

As it turns out, I used SQLite for this particular project as the data storage engine. Because this is a managed .Net wrapper around the native sqlite library, it was causing problems when trying to load the 32 bit version of the library on a 64 bit system.

A Quick Fix

Fortunately it’s quite straight forward to force an assembly to run in a 32 bit version of .Net, regardless of the host platform as there is a flag in the assembly that will define this.

In Visual Studio this can be found on the project properties page under the ‘Build’ tab.

Platform Target

Setting ‘Platform Target’ to x86 will force the assembly to be run under the 32 bit .Net framework.

This can also be set using the command line corflags utility:

corflags /32BIT+ dotnetapp.exe

The Correct Fix

Obviously the correct thing to do would be to detect the OS version on install and use the correct version of the SQLite wrapper, but the above serves as a quick fix to get them up and running.

Unit Testing With NHibernate And SQLite

Good unit tests should, among other things, be easily repeatable and independent. If you’re testing against a full blown MySQL or MSSQL server it can become difficult to easily repeat a test if you rely on certain records holding certain Ids, and the independent nature of the test is impacted as it’s not well isolated from a specific server.

Testing against an SQLite database can help alleviate these issues as the flatfile database can be created and thrown away after each test, making it easy to repeat a test on fresh data each time.

So let’s look at how to go about setting this up.

The Standard SessionFactory

In order to get an NHibernate session normally in my application, I use a provider class to provide access to a SessionFactory:

  public static class SessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static Object lockObj = new Object();

    private static void BuildSessionFactory()
    {
      string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

      sessionFactory = Fluently.Configure().
        Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null)
        lock(lockObj)
          if (sessionFactory == null)
            BuildSessionFactory();

      return sessionFactory.OpenSession();
    }
  }

This will normally live in the assembly that contains all the data access logic, and will used through dependency injection.

The Test SessionFactory

To get an SQLite database for testing, we need to create it in a slightly different way, specifying a filename for SQLite to use, and providing a way to tear it down after use:

namespace DITests
{
  public static class TestSessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static string dbFile;

    private static string GetDbFileName()
    {
      var path = Path.GetFullPath(Path.GetRandomFileName() + ".Test.db");
      if (File.Exists(path))
      {
        File.Delete(path);
      }
      return path;
    }

    private static void BuildSessionFactory()
    {
      dbFile = GetDbFileName();

      sessionFactory = Fluently.Configure().
        Database(SQLiteConfiguration.Standard.UsingFile(dbFile).ShowSql()).
        ExposeConfiguration(c =>
        {
          c.Properties.Add("hbm2ddl.keywords", "none");
          c.Properties.Add("hbm2ddl.auto", "create");
        }).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null) BuildSessionFactory();
      return sessionFactory.OpenSession();
    }

    public static void Teardown()
    {
      if (sessionFactory != null)
      {
        sessionFactory.Dispose();
        sessionFactory = null;
      }

      if (File.Exists(dbFile))
      {
        File.Delete(dbFile);
      }
    }
  }
}

Something To Test

Now that the test session factory is setup, we need something to test, so here’s a very simple user class, mapping and repository:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
using NHibernate.Linq;

namespace MVC3DI.Models
{
  public class User
  {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
  }

  public class UserMap : ClassMap<User>
  {
    public UserMap()
    {
      Id(c => c.Id);
      Map(c => c.Name);
      Map(c => c.Age);
    }
  }
  public class UserRepository
  {
    ISession session;
    private IQueryable<User> Users
    {
      get { return session.Query<User>(); }
    }

    public UserRepository(ISession session)
    {
      this.session = session;
    }

    public IList<User> GetUsers()
    {
      using (session.BeginTransaction())
      {
        var query = from c in Users select c;
        return query.ToList();
      }
    }

    public void Save(User user)
    {
      using (ITransaction t = session.BeginTransaction())
      {
        session.Save(user);
        t.Commit();
      }
    }
  }
}

The Test

And finally, we can setup some tests to run. Because the user repository takes an ISession in its constructor, we can easily change which SessionProviderFactory we’re using, allowing us to drop in our test one in order to test against SQLite:

using System;
using System.Collections.Generic;
using NUnit.Framework;
using MVC3DI.Models;

namespace DITests
{
  [TestFixture]
  public class HireContractDALTests
  {
    UserRepository repo;

    [SetUp]
    public void Setup()
    {
      repo = new UserRepository(TestSessionFactoryProvider.OpenSession());

      //insert some test checks
      var users = new List<User>(){
        new User(){ Name = "Frank", Age = 24 },
        new User(){ Name = "Bob", Age = 22 },
        new User(){ Name = "Bert", Age = 30 },
      };
      users.ForEach(p => repo.Save(p));
    }

    [TearDown]
    public void TearDown()
    {
      TestSessionFactoryProvider.Teardown();
    }

    [Test]
    public void TestTryLoadUsers()
    {
      var users = repo.GetUsers();
      Assert.AreEqual(3, users.Count);
      Assert.AreEqual("Frank", users[0].Name);
      Assert.AreEqual("Bob", users[1].Name);
      Assert.AreEqual("Bert", users[2].Name);
    }
  }
}

This is a pretty straight forward test which fires up the database, creates a few records, and then reads them back in order to verify that they were saved correctly.

Limitations

The big limitation with this method is that you can only test code that is database agnostic. This should be fine if you’re only strictly accessing records through NHibernate as that will take care of creating the correct SQL for you, but if you write any SQL yourself with keywords specific to a certain provider, it will quickly fall over when run against SQLite.

There’s not a whole lot that can be done about this; you could extract the database specific functions to a more specific implementation, but then that would need testing too, which you can only do against the database it’s targeted at, so that seems a little pointless. Which leaves you with either not testing that code or not writing it in the first place!

Summary

There is some debate as to the value of testing at the database level, especially when you’re not testing against the database that will be used in production, but personally I think it can still be useful in verifying that mappings are working correctly and to test any basic logic that may live down at that level.

Using SQLite as a replacement during testing ensures your tests will run quickly and be independant of any outside requirements. Whilst the downside to this is that you can’t test vendor specific SQL with this method, it’s generally best to avoid this anyway when using an ORM such as NHibernate.

Ninject, MVC3 And Web Requests

Continuing to play with Ninject and MVC3, I wanted to explore further how Ninject can help manage objects over the life of a web request. One of the great things about Ninject is that it allows you to easily change the scope in which objects live through use of Activation Behaviours.

Behave Yourself!

Using Ninject, you can control when new instances of objects are created with Activation Behaviours (although this documentation appears to be out of date at the time of writing).

To set the activation behaviour of a binding, you append a call like so:

Bind<ITestInterface>().To<TestClass>().InTransientScope();

Ninject has the following scopes built in:

  • TransientScope: A new instance is created for each request.
  • SingletonScope: Only a single instance of an object is created, and the same instance is returned every time.
  • ThreadScope: A new instance is created for each thread.
  • RequestScope: A new instance is created for each web request.

RequestScope and MVC

What I was interested in was whether the RequestScope would create a new instance of something at the start of a web request, and then immediately clean said object up at the end of the request, so that objects wouldn’t be kept around longer than they were needed.

A simple test ensued:

  public class MvcApplication : NinjectHttpApplication
  {
    private static ILog logger = log4net.LogManager.GetLogger("default");

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
      );

    }

    protected override Ninject.IKernel CreateKernel()
    {
      return new StandardKernel(new MyModule());
    }

    protected override void OnApplicationStarted()
    {
      base.OnApplicationStarted();

      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }
  }

  public class MyModule : Ninject.Modules.NinjectModule
  {
    public override void Load()
    {
      Bind<ITestInterface>().To<TestClass>().InRequestScope();
    }
  }

  public interface ITestInterface { }

  public class TestClass : ITestInterface, IDisposable
  {
    public void Dispose()
    {
      System.Console.WriteLine("Disposing");
    }
  }
  public class HomeController : Controller
  {
    ITestInterface test;
    public HomeController(ITestInterface test)
    {
      this.test = test;
    }

    public ActionResult Index()
    {
      return View();
    }
  }

All I did here was setup a controller that would take an instance of a disposable test class. We know it gets created and passed to the controller, so all I wanted to see was that it was disposed at the end of the request. I did this by setting a breakpoint in the dispose method of the class and debugging through Visual Studio.

If you run up the project, you’ll see that the breakpoint gets hit after the request has been served, nice and promptly; exactly what I was hoping for.

Making NHibernate Behave

The recommended way or using NHibernate with MVC is to have a single session created per request. That is each time a client makes a request for a page, a new session is opened and kept open until the request is complete and data is returned to the client.

Sounds a little like the RequestBehaviour activation type fits perfectly here doesn’t it?

To test this, we need to setup NHibernate and create a simple user class and repository. So to start, here’s how I like to get my session factory:

namespace DITest
{
  public static class SessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static Object lockObj = new Object();

    private static void BuildSessionFactory()
    {
      string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

      sessionFactory = Fluently.Configure().
        Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
        ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none")).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null)
        lock(lockObj)
          if (sessionFactory == null)
            BuildSessionFactory();

      return sessionFactory.OpenSession();
    }
  }
}

And this is registered with Ninject like so:

Bind<ISession>().ToMethod(x => SessionFactoryProvider.OpenSession()).InRequestScope();

Next, a simple user class, mapping (I’m using FluentNhibernate here to do the mapping) and repository (all in one place for brevity):

namespace DITest
{
  public class User
  {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
  }

  public class UserMap : ClassMap<User>
  {
    public UserMap()
    {
      Id(c => c.Id);
      Map(c => c.Name);
      Map(c => c.Age);
    }
  }

  public class UserRepository
  {
    ISession session;
    private IQueryable<User> Users
    {
      get { return session.Query<User>(); }
    }

    public UserRepository(ISession session)
    {
      this.session = session;
    }

    public IList<User> GetUsers()
    {
      using (session.BeginTransaction())
      {
        var query = from c in Users select c;
        return query.ToList();
      }
    }
  }
}

Finally, updated the controller to pull some information from the database:

  public class HomeController : Controller
  {
    UserRepository repo;
    public HomeController(UserRepository userRepo)
    {
      repo = userRepo;
    }

    public ActionResult Index()
    {
      ViewBag.Users = repo.GetUsers();
      return View();
    }
  }

To verify this was all working correctly and the session is being closed properly, I setup logging to log debug information, which churns out tons of useful information:

<logger name="NHibernate" additivity="false">
  <level value="DEBUG"/>
  <appender-ref ref="rollingFile" />
</logger>

<logger name="NHibernate.SQL" additivity="false">
  <level value="DEBUG"/>
  <appender-ref ref="rollingFile" />
</logger>

Then after running up the page and doing a request, we can look at the generated log and see what’s been happening:

14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] opened session at timestamp: 634462405708, for session factory: [/b9e13234ae244e18b7f2ce1923c58e48]
14/07/11 12:42:50 DEBUG Begin (Unspecified)
14/07/11 12:42:50 DEBUG Obtaining IDbConnection from Driver
...//edited for brevity
14/07/11 12:42:50 DEBUG IDbTransaction disposed.
14/07/11 12:42:50 DEBUG transaction completion
14/07/11 12:42:50 DEBUG aggressively releasing database connection
14/07/11 12:42:50 DEBUG Closing connection
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] running ISession.Dispose()
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] executing real Dispose(True)
14/07/11 12:42:50 DEBUG closing session
14/07/11 12:42:50 DEBUG running BatcherImpl.Dispose(true)

I’ve cut out a lot of the logging that just details queries are happening so that we can see what we care about; that the session is being closed properly after the requests have happened, and not before!

Summary

We looked at the various types of activation behaviour that Ninject supports, delved deeper into RequestBehaviour and verified that it is in fact doing what it says on the tin, and then saw how this is useful when working with MVC and NHibernate.

So now we have an NHibernate session that will last for the duration of a request. What would be really useful now is some concept of a unit of work, to allow multiple Nhibernate requests to be batched into a single transaction. Stay tuned!

Ninject And ASP .Net MVC3

I’ve mentioned Ninject before, it’s an excellent dependancy injection framework that lets you keep your code loosely coupled.

I’ve also mentioned that I’ve been working with the MVC Framework quite a lot of late, and what’s neat is that hooks are provided that make it easy to use your own dependancy injection framework. To that end, this post will be looking at how Ninject can be integrated with MVC3, and why that’s awesome!

I’ll be working with a clean MVC3 project created in Visual Studio 2010. There are a couple of ways of integrating Ninject; using the IDependancyResolver interface, or inheriting from NinjectHttpApplication.

Option 1: IDependancyResolver

All we need to do here is implement IDependancyResolver and then register an instance of it on application startup.

So a simple implementation for Ninject will look something like this:

using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Ninject;
using Ninject.Modules;

public class NinjectResolver : IDependencyResolver
{
  IKernel kernel;

  public NinjectResolver(INinjectModule[] modules)
  {
    kernel = new StandardKernel(modules);
  }

  public object GetService(Type serviceType)
  {
    return kernel.Get(serviceType);
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return kernel.GetAll(serviceType);
  }
}

And we register this in Application_Start with a simple call like so:

var resolver = new NinjectResolver(new MyModule());
DependencyResolver.SetResolver(resolver);

MVC3 will then use this object when trying to instantiate an instance of a class, but will fall back to it’s built in methods for locating objects if this fails. What this means in practice is that you don’t need to worry about registering all of the default objects MVC3 uses such as the controller factory, leaving you free to just deal with the stuff you care about.

Option 2: NinjectHttpApplication

The second option is to make use of Ninject’s MVC3 extension which can be found here.

In this case, all we need to do is change our MvcApplication class (found in Global.asax) to inherit from NinjectHttpApplication instead of MvcApplication, and then implement CreateKernel to register the modules we’ve created.

public class MvcApplication : NinjectHttpApplication
  {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
      );

    }

    protected override void OnApplicationStarted()
    {
      base.OnApplicationStarted();
      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }

    public override IKernel CreateKernel()
    {
      return new StandardKernel(new MyModule());
    }
  }

And that’s it; now Ninject will be used to resolve any dependencies that are requested when the object model is being built.

Which Approach?

But which of the two approaches should you use? It doesn’t matter hugely, the first option allows for a very quick integration, you could even register a dependency resolver in a much more concise fashion making use of lambdas like so:

var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(
    t => {
        try { return kernel.Get(t); }
        catch { return null; }
    },
    t => kernel.GetAll(t)
);

However, using Ninject’s MVC3 extension is marginally more self contained, so I tend to prefer making use of NinjectHttpApplication instead. Note that Ninject will still find the right controllers without registering them, so there is no need to register all your controllers unless you want to add additional configuration to them.

If you think you’re likely to want to change your DI framework, then it would make more sense to make use of the IDependancyResolver interface so that you can drop in a quick replacement, although personally I think that scenario is somewhat unlikely.

Now you’re loosely coupled

So that’s a couple of simple ways to integrate Ninject with MVC3; not too hard to achieve and provides a lot of power and flexibility.

Writing A Simple Jquery Plugin

Jquery is a fantastic Javascript library that makes manipulating the DOM a breeze. Its usefulness lies in the powerful selectors which make it easy to pick which part of the DOM you want to work with, and many functions with which to manipulate the selected objects.

Jquery provides a lot of functionality, but like any good library, also provides the ability to easily extend its capabilities. I recently found it useful to do this, so here’s a quick run down on how to do just that.

The Barebones

To start with we’ll just put together a bare plugin so that we can see the structure:

(function($) {
  $.fn.mask = function() {
  //body goes here
  };
})(jQuery);

This adds a new function, mask, to the jquery object. You could use it like so:

  $('#objectToMask').mask();

An Overlay

The reason I started to look into this was that I wanted to encapsulate a piece of functionality that would allow an overlay mask to be applied to an arbitrary element. This is useful when loading something asynchronously to let the user have some visual feedback.

Firstly the mask function:

(function($) {
  $.fn.mask = function() {
    if ($("#overlay").length == 0) {
      var $overlay = $('<div id="overlay"><img src="images/loader.gif" id="img-load" /></div>');
      $("body").append($overlay);
    }

    $("#overlay").css({
      opacity: 0.5,
      top: this.offset().top,
      left: this.offset().left,
      width: this.outerWidth(),
      height: this.outerHeight()
    });

    $("#img-load").css({
      top: (this.height() / 2),
      left: (this.width() / 2)
    });

    $("#overlay").fadeIn();
  };
})(jQuery);

This is pretty straight forward; We create the overlay element if it doesn’t exist, set its position along with the loading image position, and then fade it in.

The unmask function, is shorter, as it just needs to hide the element:

(function($) {
  $.fn.unmask = function() {
    $("#overlay").fadeOut();
  };
})(jQuery);

Summary

And that’s all there is to it. Extending Jquery is a relatively simple and straightforward process that’s well worth investigating when you want to encapsulate a piece of functionality to make it easily reusable.