Mixing NHibernate, Fluent NHibernate, and SQLite on .NET 4.0 RC will lead to some major headaches.  There’s an easy fix, but it doesn’t work if you are using Resharper’s test runner.  If you’re using my personal favorite test runner, TestDriven.NET though, the fix is actually quite easy. 

We decided to use .NET 4.0 for the new super secret social networking site we’re working on, and since we’re starting out with a relational DB under the hood (that we fully plan to swap out for a NoSQL alternative later), we’re using NHibernate.  I hate NHibernate’s XML maps, so we’re also using FluentNHibernate.  When I’m using NHibernate, I like to use SQLite’s in-memory database for my unit tests, so now we’re looking at making three pieces of OSS play nice together on a not-quite-finished version of the .NET Framework.  Oh, and I’m also using Resharper 5.0 EAP.  🙂

Getting things started is easy enough.  I grabbed the latest production release of NHibernate along with a compatible version of Fluent NHibernate.  I also grabbed the latest SQLite .NET assembly.  After adding references to the required bits, here’s my NHibernate bootstrapper:

public static class NHibernateBootstrapper
{
    private static Configuration _currentConfig;

    private static FluentConfiguration ConfigureMappings()
    {
        return Fluently.Configure()
            .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
            .ExposeConfiguration(c => _currentConfig = c);
    }

    public static ISessionFactory CreateSessionFactoryForTests()
    {
        return ConfigureMappings()
            .Database(SQLiteConfiguration.Standard.ShowSql().InMemory())
            .BuildSessionFactory();
    }

    public static ISessionFactory CreateSessionFactoryForProduction()
    {
        return ConfigureMappings()
            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("RageFeedData")))
            .BuildSessionFactory();
    }

    public static void CreateSchema(ISession session)
    {
        var exporter = new SchemaExport(_currentConfig);
        exporter.Execute(true, true, false, session.Connection, null);
    }

    public static void UpdateSchema()
    {
        var updater = new SchemaUpdate(_currentConfig);

        updater.Execute(true, true);
    }
}

And here’s my unit tests:

public abstract class InMemoryDatabaseFixture
{
    public ISession Session { get; private set; }

    [SetUp]
    public virtual void Prepare()
    {
        var factory = NHibernateBootstrapper.CreateSessionFactoryForTests();
        Session = factory.OpenSession();
        NHibernateBootstrapper.CreateSchema(Session);
    }

    [TearDown]
    public virtual void Cleanup()
    {
        Session.Dispose();
    }
}

[TestFixture]
public class RageletPersistanceTests : InMemoryDatabaseFixture
{
    [Test]
    public void CanCorrectlyPersistRagelet()
    {
        new PersistenceSpecification<Ragelet>(Session)
            .CheckProperty(r => r.Content, "Test content")
            .VerifyTheMappings();
    }
}

Simple enough, right? 

boom

Sadly, this fails gloriously when run with ReSharper’s test runner:

Mixed mode assembly is built against version ‘v2.0.50727’ of the runtime

and cannot be loaded in the 4.0 runtime without additional configuration information.

I found a solution, but it doesn’t work with Resharper 5.0 EAP.  I’m thinking that Resharper isn’t using the app.config file, but perhaps it’s something else.  Fortunately, running the tests with TestDriven.NET (my favorite test runner) worked perfectly.

Unfortunately, I wasted the better part of two weeks of “free time” trying to get things recompiled so that they would work without the app.config entry.  There are several breaking changes in .NET 4.0 apparently, and nothing that I tried worked.  Hopefully this isn’t a sign of pains to come.