Я реализую стандартный сценарий в сеансе asp.net на запрос.
Мой модуль asp.net:
public class NHibernateSessionModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
}
void context_BeginRequest(object sender, EventArgs e)
{
var session = SessionManager.SessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
void context_EndRequest(object sender, EventArgs e)
{
var session = SessionManager.CurrentSession;
if (session != null)
{
try
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Commit();
}
catch (Exception ex)
{
session.Transaction.Rollback();
throw new ApplicationException("Error committing database transaction", ex);
}
finally
{
session.Close();
}
}
CurrentSessionContext.Unbind(SessionManager.SessionFactory);
}
}
Мой sessionManager является поточно-ориентированным синглетом:
public class SessionManager
{
private readonly ISessionFactory sessionFactory;
public static ISessionFactory SessionFactory
{
get { return Instance.sessionFactory; }
}
private ISessionFactory GetSessionFactory()
{
return sessionFactory;
}
public static ISession OpenSession()
{
return Instance.GetSessionFactory().OpenSession();
}
public static ISession CurrentSession
{
get
{
if (!CurrentSessionContext.HasBind(Instance.GetSessionFactory()))
return null;
return Instance.GetSessionFactory().GetCurrentSession();
}
}
public static SessionManager Instance
{
get
{
return NestedSessionManager.sessionManager;
}
}
private SessionManager()
{
Configuration configuration = new Configuration().Configure();
sessionFactory = configuration.BuildSessionFactory();
}
class NestedSessionManager
{
internal static readonly SessionManager sessionManager =
new SessionManager();
}
}
Основная идея - открыть сеанс в начале запроса, а затем использовать сеанс через SessionManager.CurrentSession;
Сессия хранится в настроенном контексте:
<property name="current_session_context_class">web</property>
Мой репозиторий:
public class RepositoryNew<T> : BaseRepository<T>, IDisposable
{
public RepositoryNew()
{
if (NHibernateSession == null)
//Start session for not web version
}
public void Dispose()
{
//flush session for not web version
}
protected override sealed ISession NHibernateSession
{
get
{
return SessionManager.CurrentSession;
}
}
}
Использование
protected void Page_Load(object sender, EventArgs e)
{
var repo = new RepositoryNew<Client>()
clients = repo.GetAll();
}
По какой-то причине этот репозиторий не использует открытый сеанс в модуле.
CurrentSessionContext.HasBind(Instance.GetSessionFactory())
возвращает false, поэтому мой код запускает второй сеанс в запросе.
В отладчике я вижу, что я дважды создал экземпляр SessionManager.
У меня есть две разные фабрики ISesssion.
У меня пока нет идей, что не так. Я потратил на это много часов.