2011-12-26 122 views
0

我實現了每個請求在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工廠。 我還沒有想法什麼是錯的。我花了很多小時。

回答

0

這是奇怪的錯誤。當我從我的項目中刪除SessionManager的鏈接時,它會正常啓動。