簡體   English   中英

如何在我的項目中實現強大的每個請求會話模式,同時專注於信息隱藏?

[英]How can I implement a robust session-per-request pattern in my project, while focusing on information hiding?

我目前正在構建一個ASP.NET MVC項目,NHibernate作為其持久層。

目前,已經實現了一些功能,但僅使用本地NHibernate會話:訪問數據庫(讀取或寫入)的每個方法都需要使用“using()”子句實例化其自己的NHibernate會話。

問題是我想利用NHibernate的延遲加載功能來提高項目的性能。

這意味着每個請求都會打開一個NHibernate會話,直到呈現視圖為止。 此外,必須支持同時請求(同時多個會話)。

我怎樣才能盡可能干凈地實現這一目標?

我在網上搜索了一下,了解了每個請求的會話模式。 我看到的大多數實現使用某種Http *(HttpContext等)對象來存儲會話。 此外,使用Application_BeginRequest / Application_EndRequest函數很復雜,因為當我只想為每個請求實例化一次會話時,它們會針對每個HTTP請求(aspx文件,css文件,js文件等)被觸發。

我擔心的是我不希望我的視圖或控制器能夠訪問NHibernate會話(或者更常見的是NHibernate命名空間和代碼)。 這意味着我不想在控制器級別處理會話,也不想在視圖級別處理會話。

我有幾個選擇。 哪一個看起來最好?

  • 使用在控制器操作之前和之后觸發的攔截器(如GRAILS)。 這些將打開和關閉會話/交易。 這可能在ASP.NET MVC世界中嗎?
  • 在Web上下文中使用NHibernate提供的CurrentSessionContext Singleton。 這個頁面為例,我認為這很有希望,但仍需要控制器級別的過濾器。
  • 使用HttpContext.Current.Items存儲請求會話。 這與Global.asax.cs中的幾行代碼相結合,可以輕松地為我提供請求級別的會話。 但是,這意味着將在NHibernate和我的視圖(HttpContext)之間注入依賴項。

非常感謝你!

好吧,經過幾天的工作,我終於決定使用HttpContext.Current.Items來加載會話。

它很棒!

這就是我做到的

import System.Web
class SessionManager {
    public static ISession GetSession()
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session == null) {
            session = ...; // Create session, like SessionFactory.createSession()...
            HttpContext.Current.Items.Add("NHibernateSession", session);
        }
        return session;
    }

    public static void CloseSession()
    {
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session != null) {
            if (session.IsOpen) {
                session.close();
            }
            HttpContext.Current.Items.Remove("NHibernateSession");
        }
    }
}

通過使用此類提供的靜態方法,可以獲得與當前HttpContext(當前Web請求)綁定的會話(例如,在Controller中)。 我們需要另一段代碼來在請求完成時調用CloseSession()方法。

在Global.asax.cs中:

protected void Application_EndRequest(object sender, EventArgs args)
{
    NHibernateSessionManager.CloseSession();
}

會話完成后會自動調用Application_EndRequest事件,因此可以正確關閉會話並將其處理掉。 這很有用,因為否則我們必須在每個Controller中執行此操作!

使用DI和IoC。 大多數IoC都帶有每請求實例化行為。

我的“解決方案”涉及使用Unity在控制器中為每個請求注入會話:

http://letsfollowtheyellowbrickroad.blogspot.com/2010/05/nhibernate-sessions-in-aspnet-mvc.html

看看S#arp架構 對於ASP.NET MVC和NHibernate來說,它是一個非常好的架構。

您可以添加一個可以管理NHibernate會話和事務的操作過濾器。 (這可以在動作或控制器級別完成。)以下是一個示例:

http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM