ASP.NET is multi-threaded so access to the ISession must be thread safe. Assuming you're using session-per-request, the easiest way to do that is to use NHibernate's built-in handling of contextual sessions.
First configure NHibernate to use the web session context class:
sessionFactory = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2005.ConnectionString(p =>
p.FromConnectionStringWithKey("QoiSqlConnection")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<JobMapping>())
.ExposeConfiguration(x => x.SetProperty("current_session_context_class", "web")
.BuildSessionFactory();
Then use the ISessionFactory.GetCurrentSession()
to get an existing session, or bind a new session to the factory if none exists. Below I'm going to cut+paste my code for opening and closing a session.
public ISession GetContextSession()
{
var factory = GetFactory(); // GetFactory returns an ISessionFactory in my helper class
ISession session;
if (CurrentSessionContext.HasBind(factory))
{
session = factory.GetCurrentSession();
}
else
{
session = factory.OpenSession();
CurrentSessionContext.Bind(session);
}
return session;
}
public void EndContextSession()
{
var factory = GetFactory();
var session = CurrentSessionContext.Unbind(factory);
if (session != null && session.IsOpen)
{
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
throw new Exception("Rolling back uncommited NHibernate transaction.");
}
session.Flush();
}
catch (Exception ex)
{
log.Error("SessionKey.EndContextSession", ex);
throw;
}
finally
{
session.Close();
session.Dispose();
}
}
}