[英]How to implement session-per-request pattern in asp.net mvc with Nhibernate
[英]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命名空間和代碼)。 這意味着我不想在控制器級別處理會話,也不想在視圖級別處理會話。
我有幾個選擇。 哪一個看起來最好?
非常感謝你!
好吧,經過幾天的工作,我終於決定使用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會話和事務的操作過濾器。 (這可以在動作或控制器級別完成。)以下是一個示例:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.