NHibernate的Session管理策略和NHibernateHelper


聲明

本篇中提到的Session,並非是Asp.NET中的Session,而是NHibernate中ISession。

本篇假設讀者已經對NHibernate的有一定的了解,已經成功持久化過領域模型。

你不需要親自用復制本篇的代碼去調試,因為本篇的代碼並不全,最后也有提供下載。

本篇中的單元測試用到了NUnit,如果你使用其他框架也並不影響理解。

 

正文 開門見山

在ASP.NET中,如果我們希望每一個HTTP的請求只打開一個Session,在請求結束時關閉這個Session。

也就是在請求期間,只用到這一個Session。或許我們可以稱他為“one session per request”。

這樣做得好處是,你可以更容易地使用延遲加載,因為當領域模型傳到表示層時,ISession在表示層仍然是打開的,並再請求結束后自動銷毀。

另外在單元測試時,並不一定有HTTP的請求,所以需要用另一種策略代替。

 

作法:

我們會在ASP.NET應用程序中這樣使用

HttpContext context = HttpContext.Current;
if (context.Items["nhsession"] == null)
{
        context.Items["nhsession"] = sessionFactory.OpenSession();
}
return context.Items["nhsession"] as ISession;


以上代碼意思是:我們需要Session時,就從web的上下文中取,一個請求中第一次會打開一個Session並保存再web上下文,以后就不再新打開了。

 

但是有了這樣的一個GetSession方法后,並不代表萬事大吉了。

下面來看一下單元測試:

[Test]
public void GetSessionTest()
{
    ISession session=  NHibernateHelper.GetSession();
}

報錯了,未將對象引用到實例,是哪個對象呢?HttpContext.Currtent為null。

因為建立的是類庫,這里並沒有web的上下文。那怎么辦呢?

所以在這里我使用兩套Session策略

1、在Web應用程序中,就使用剛才提到的策略。

2、在WinForm或單元測試中,使用另一種策略,每個線程用一個Session。

 

其實在NHibernate文檔中也有提到,在1.2以后的版本中,增加了一個GetCurrentSession()的方法,用於獲取當前Session,這個上下文只支持一個ISessionFactory。你必須自己通過CurrentSessionContext類中的靜態方法手動的把ISession實例綁定或者取消綁定到當前上下文。

修改代碼

        private static void BindContext()
        {
            if (!CurrentSessionContext.HasBind(sessionFactory))
            {
                CurrentSessionContext.Bind(sessionFactory.OpenSession());
            }
        }

        private static void UnBindContext()
        {
            if (CurrentSessionContext.HasBind(sessionFactory))
            {
                CurrentSessionContext.Unbind(sessionFactory);
            }
        }

        public static ISession GetCurrentSession()
        {
            BindContext();
            return sessionFactory.GetCurrentSession();
        } 


這樣做可以避免在代碼中自己實現策略模式與IOC,NHibernate已經幫我們做好了。

修改hibernate.cfg.xml配置文件,加入一個屬性<property name="current_session_context_class">web</property>,修改這個屬性就可以修改Session策略。

也可以定義在代碼中。

sessionFactory = new Configuration().Configure()
                .SetProperty("current_session_context_class", currentSessionContextClass.ToString())
                .BuildSessionFactory();



    /// <summary>
    /// 當前Session上下文模式
    /// 特定環境下,當前Session保存在特定的上下文中
    /// </summary>
    public enum CurrentSessionContextClass
    {
        managed_web,
        call,
        thread_static,
        web
    }


現在,我們就可以在web應用程序中將參數設置為web,而單元測試中將參數設置為thread_static。

        void Application_Start(object sender, EventArgs e)
        {
            // 在應用程序啟動時運行的代碼
            NHibernateHelper.Instance(CurrentSessionContextClass.web);
        }

 

        ISession session;
        [SetUp]
        public void Setup()
        {
            NHibernateHelper.Instance(CurrentSessionContextClass.thread_static);
            session = NHibernateHelper.GetCurrentSession();
        }

 

下載:

 最后分享一個相關的NHibernateHelper文件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM