我還沒有使用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的頂部依賴注入
關於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