我實現了每個請求在asp.net會話中的標準場景。 我的asp.net模塊:asp.net Nhibernate會話管理
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是線程安全的singletone:
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工廠。 我還沒有想法什麼是錯的。我花了很多小時。