We have an MVC project that constructs the NHibernate dependecies via StructureMap like this
var sessionFactory = ConnectionRegistry.CreateSessionFactory<
The problem is combination of a singleton:
For<INHibernateSessionManager>().Singleton().Use<NHibernateWebSessionManager>();
Having reference to an object from a different scope (webrequest context)
_currentSession = SessionFactory.GetCurrentSession();
This canot work properly in multithread environment (as mentioned in cases of two concurrent browsers accessing it). First request could already force to set the field _currentSession
, which is then (for a while) used even for the second one. The first Application_EndRequest
will close it ... and lasting one will recreate it...
When relying on NHibernate scopes, follow it fully:
return SessionFactory.GetCurrentSession(); // inside is the scope handled
SessionManager.Open()
public ISession OpenSession()
{
if(CurrentSessionContext.HasBind(SessionFactory))
{
return SessionFactory.GetCurrentSession();
}
// else
var session = SessionFactory.OpenSession();
NHibernate.Context.CurrentSessionContext.Bind(session);
return session;
}
Then even singleton returning correct instances should work. But for a SessionManager I would use HybridHttpOrThreadLocalScoped
anyway.
For<INHibernateSessionManager>()
.HybridHttpOrThreadLocalScoped()
.Use<NHibernateWebSessionManager>();