I'm profiling out unit & integration tests, and I find the a lot of the time is spent on the finalizer of NHibernate.Transaction.AdoTransaction - this means it is not getting disposed properly.
I am not using AdoTransaction directly in the code, so it's probably used by some other object inside NHibernate. Any idea what I'm forgetting to Dispose?
Here is my text fixture:
public abstract class AbstractInMemoryFixture
{
protected ISessionFactory sessionFactory;
protected ILogger Logger { get; private set; }
static readonly Configuration config;
private static readonly ISessionFactory internalSessionFactory;
static AbstractInMemoryFixture()
{
config = new NHibernateConfigurator().Configure(NHibernateConfigurators.SQLiteInMemory());
internalSessionFactory = config.BuildSessionFactory();
}
[SetUp]
public void SetUp()
{
const string sqliteInMemoryConnectionString = "Data Source=:memory:;Version=3;Pooling=False;Max Pool Size=1;";
var con = new SQLiteConnection(sqliteInMemoryConnectionString);
con.Open();
new SchemaExport(config).Execute(false, true, false, true, con, System.Console.Out);
var proxyGenerator = new ProxyGenerator();
sessionFactory = proxyGenerator.CreateInterfaceProxyWithTarget(internalSessionFactory, new UseExistingConnectionInterceptor(con));
Logger = new NullLogger();
ExtraSetup();
}
[TearDown]
public void TearDown()
{
var con = sessionFactory.OpenSession().Connection;
if (con != null)
{
if (con.State == ConnectionState.Open)
con.Close();
con.Dispose();
}
}
private class UseExistingConnectionInterceptor :IInterceptor
{
private readonly SQLiteConnection connection;
public UseExistingConnectionInterceptor(SQLiteConnection connection)
{
this.connection = connection;
}
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name != "OpenSession" || invocation.Method.GetParameters().Length > 0)
{
invocation.Proceed();
return;
}
var factory = (ISessionFactory) invocation.InvocationTarget;
invocation.ReturnValue = factory.OpenSession(connection);
}
}
protected virtual void ExtraSetup() { }
}