靜態儲存庫是使用 NHibernate 的正確方法嗎?
晚上剩下的時間我都在閱讀 StackOverflow 問題以及一些關於該主題的部落格條目和連結。結果他們都非常有幫助,但我仍然覺得他們並沒有真正回答我的問題。
所以,我正在開發一個簡單的 Web 應用程序。我想創建一個可重用的數據訪問層,以後可以在其他解決方案中重用。其中 99% 將是 Web 應用程序。這似乎是我學習 NHibernate 和它周圍的一些模式的一個很好的藉口。
我的目標如下:
- 我不想讓業務邏輯層知道任何關於數據庫內部運作的資訊,也不想知道 NHibernate 本身。
- 我希望業務邏輯層對數據訪問層有盡可能少的假設。
- 我希望數據訪問層盡可能簡單易用。這將是一個簡單的項目,所以我不想讓任何事情變得過於復雜。
- 我希望數據訪問層盡可能不具有侵入性。
將這一切銘記於心,我決定使用流行的儲存庫模式。我在這個網站和各種開發部落格上讀到了這個主題,我聽到了一些關於工作單元模式的東西。
我還環顧四周並檢查了各種實現。(包括 FubuMVC contrib 和 SharpArchitecture 以及一些部落格上的東西。)我發現它們中的大多數都遵循相同的原則:它們創建一個“工作單元”,在實例化儲存庫時實例化,它們啟動事務,做事,送出,然後重新開始。
ISession所以,每個人只有一個Repository,就是這樣。然後客戶端程式碼需要實例化一個儲存庫,用它做一些事情,然後處置。這種使用模式不能滿足我盡可能簡單的需求,所以我開始考慮別的東西。
我發現 NHibernate 已經有一些東西使自定義“工作單元”實現變得不必要,那就是
CurrentSessionContext類。如果我正確配置了會話上下文,並在必要時進行了清理,我就可以開始了。所以,我想出了這個:
我有一個名為
NHibernateHelper. 首先,它有一個名為 的靜態屬性CurrentSessionFactory,在第一次呼叫時,它會實例化一個會話工廠並將其儲存在一個靜態欄位中。(一個ISessionFactory一個AppDomain就足夠了。)然後,更重要的是,它有一個CurrentSession靜態屬性,它檢查是否存在ISession與目前會話上下文的綁定,如果沒有,則創建一個並綁定它,然後返回ISession綁定到目前會話上下文。因為它將主要用於
WebSessionContext(所以,一個ISessionperHttpRequest,儘管對於單元測試,我配置了ThreadStaticSessionContext),它應該可以無縫地工作。在創建和綁定 an 之後ISession,它會將事件處理程序掛鉤到事件,該處理程序負責在請求結束後HttpContext.Current.ApplicationInstance.EndRequest清理。ISession(當然,只有當它真的在 Web 環境中執行時才會這樣做。)因此,通過所有這些設置,
NHibernateHelper將始終能夠返回有效的ISession,因此無需實例化 Repository 實例以使“工作單元”正常執行。相反, theRepository是一個靜態類,它使用ISessionfromNHibernateHelper.CurrentSession屬性操作,並通過泛型方法通過它公開功能。所以,基本上,我最終得到了兩個非常懶惰的單身人士。
我很好奇,你怎麼看這件事?這是一種有效的思維方式,還是我完全偏離了軌道?
編輯:
我必須指出 NHibernateHelper 類是內部的,所以對於儲存庫的消費者來說幾乎是不可見的。
另一個想法是,為了將依賴注入引入解決方案,是創建一個名為 的介面
IDataProvider,並在第一次呼叫該類時實例化該介面的一個實例Repository。(但是,實現程式碼也應該能夠處理上下文的概念。)編輯2:
似乎很多人喜歡我的想法,但答案中關於它的意見仍然太少。
我可以假設這是使用 NHibernate 的正確方法嗎?:P
就其價值而言,夏普架構或多或少地按照您的建議行事。它最終為每個 HTTP 請求提供一個會話(更準確地說,每個 HTTP 請求每個數據庫一個會話)。您的方法當然是有效的,並且每個請求還提供一個會話。我更喜歡 SharpArch 通過 DI 提供的更簡潔的 OO 方法,而不是使用靜態儲存庫和輔助類。
我們混合了 ASP.NET/Windows 窗體應用程序,我發現的最佳解決方案是通過儲存庫建構子進行手動依賴注入。也就是說,每個儲存庫類都有一個需要 ISession 的公共建構子。這允許應用程序完全控制工作單元和事務邊界。它簡單有效。我還有一個非常小的 NHibernate 輔助程序集,它配置會話工廠並提供打開正常或上下文會話的方法。
S#arp Architecture 有很多我喜歡的地方,我認為值得研究它的工作原理,但我發現它的架構過於適合我的口味。