2

我想要抓住NHibernate,流利NHibernate和Spring。使用NHibernate和Spring.Net實現存儲庫

繼領域驅動設計的校長,我寫組成的標準分層的Web應用程序:

  • 一個表現層(ASP.Net)
  • 業務層,包括:
    • 一個應用程序層(基本上,一組方法對UI層可見)
    • 存儲庫接口和域組件(由應用程序層使用)
  • 持久層

我想幫助確定以這樣一種方式實例化的NHibernate的ISession的方式(基本上在業務層中定義的庫接口的實現),它可以由多個共享存儲庫在對業務層的單個請求的生命週期中。具體來說,我想:

  • 允許ISession實例和任何交易outwith庫實現控制

  • 允許ISession的(也許是由IOC框架,一個攔截器的某些方面?) (可能通過注入或通過某些共享的「上下文」抽象)

  • 避免任何不必要的事務被創建(即只有只讀操作已被執行時)

  • 讓我寫使用SQLLite

  • 允許我用流利的NHibernate的

  • 使倉庫實現保持無知主機環境的測試。我還不知道businese層是否將在表現層中運行,或者將在WCF(在IIS中)下單獨託管,所以我不想將我的代碼與HTTP上下文過於緊密地綁定在一起(例如)。

我第一次嘗試解決這個問題一直在使用註冊表模式;將ISession實例存儲在ThreadStatic屬性中。然而,後來的閱讀表明,這不是最好的解決方案(因爲ASP.Net可以在頁面生命週期內切換線程,我相信)。

任何想法,部分解決方案,模式名稱,指向最新樣本(NHibernate 2)的指針都將非常感激地收到。

回答

1

我還沒有使用Spring.NET,所以我不能對此發表評論。然而,其餘的聽起來很明顯(或者不那麼顯着,我們幾乎不是第一個實現這些東西的),這與我自己的經驗類似。我也很難找到一個真正的最佳實踐,所以我儘可能多地閱讀,並提出自己的解釋。

在我的情況下,我希望事務/會話管理在存儲庫的外部以及使存儲庫的問題不致從其中冒出來(即使用存儲庫的代碼不需要知道它在內部使用NHibernate並且不應該不需要知道關於NHibernate會話管理的任何事情)。在我的情況下,決定默認情況下會創建交易,以免開發人員忘記交易,所以我必須擁有隻讀轉義機制。我使用內部的NHibernate ISession實例存儲與工作單元模式。調用代碼(我還創建了一個UOW DSL接口)可能看起來像:

using (var uow = UoW.Start().ReadOnly().WithHttpContext() 
     .InNewScope().WithScopeContext(ScopeContextProvider.For<CRMModel>()) 
{ 
    // Repository access 
} 

在實踐中,這可能取決於很多方面是如何已經可以儘可能短UoW.Start()HttpContext部分指的是UoW的存儲位置,在這種情況下,不出意外的是HttpContext。正如您所提到的,對於ASP .NET應用程序,HttpContext是存儲事物最安全的地方。 ScopeContextProvider基本上確保爲UoW(適合的數據庫/服務器的ISession實例,其他設置)提供正確的數據上下文。 「ScopeContext」概念也使得插入「測試」範圍上下文變得容易。

執行此路由會使存儲庫明確依賴UoW接口。其實,你可能能夠抽象一些,但我不確定我看到了好處。我的意思是,每個存儲庫方法檢索當前的UoW實例,然後抽出ISession對象(或者簡單地爲那些不使用NHibernate的方法使用SqlConnection)來運行NHibernate查詢/操作。這對我很有用,因爲它似乎也是確保當前UoW對於可能需要運行CRUD的方法不是隻讀的理想時間。

總體來說,我認爲這是一個辦法可以解決所有的點:

  • 允許會話管理是外部存儲庫
  • 的Isession上下文可以在上下文提供一個測試嘲笑或尖環境
  • 避免了不必要的交易(當然,你必須倒置我做什麼,有一個.Transactional()來電或東西)
  • 我不明白爲什麼你不能使用SQLite測試,因爲這更多的NHibernate的關注
  • 我用流利的NHibernate的自己
  • 允許庫無知主機環境(即庫調用者控制UOW存儲上下文)

對於UOW執行,我部分地在我開始之前踢我自己不要更多地環顧四周。有一個名爲machine.uow的項目,據我瞭解,它相當流行,並且可以很好地與NHibernate配合使用。我沒有玩過很多,所以我不能說它是否像我自己寫的那樣整齊地解決了我的所有需求,但它也可能節省了開發時間。

也許我們會收到一些有關我出錯或如何改善事情的評論,但我希望這至少對某些方面有所幫助。

僅供參考,我使用的軟件棧:

  • ASP。NET MVC
  • 功能NHibernate NHibernate的
  • Ninject的頂部依賴注入
1

你所描述由Spring.NET框架支持幾乎開箱即用。只有FluentNHibernate,你需要在Spring.NET中添加一個自定義的SessionFactory(不是很多代碼,看這裏:Using Fluent NHibernate in Spring.NET)。

每個存儲庫都可以使用相同的ISession,只需在存儲庫中注入SessionFactory並使用Spring.NET的事務服務即可。

只要試一下,他們有非常全面的文件imho。

+0

關於FluentNhibernate,還有一個開放的jira:http://jira.springframework.org/browse/SPRNET-1232 沙地的其他資源可能是Documentation:http://www.springframework.net/doc- latest/reference/html/nh-quickstart.html 對於IntegrationTesting suppport,請查看http://www.springframework.net/doc-latest/reference/html/testing.html#unit-testing。 – tobsen 2009-12-03 23:07:30