12

我有一個asp.net.net MVC應用程序,最近開始實施與服務驗證層的存儲庫模式,很像thisMVC存儲庫模式設計決策

我一直在爲每個創建的模型創建一個存儲庫/服務。這是否過分矯枉過正?相反,我應該爲每個爲許多不同模型提供CRUD的邏輯業務區域創建一個存儲庫/服務嗎?

對我來說,好像我要麼用許多文件混淆項目樹,要麼用許多方法混淆一個類。 6方向打另一半。你能以任何方式想到任何好的論點嗎?

回答

16

通常,如果您使用的是「真實」存儲庫模式,而不是其他持久層(例如ActiveRecord或DAO),則應該着眼於識別您的域聚合,併爲每個聚合創建一個存儲庫。

這是什麼意思?嗯,這取決於你的應用程序,但通常有些對象自然是其他對象的「父母」,或者是相關事務的一部分。

我認爲典型的例子是一個電子商務系統,其中您有一個訂單的概念,並且在訂單中您有訂單行,每個訂單行都是一些產品和數量,依此類推。

在這種情況下,Order對象是系統的聚合根之一,並且創建了OrderRepository。

在這種情況下要記住的是,訂單和訂單行之間存在某種關係(暗示或其他方式)等等。因此,Repository上的「CRUD」的C-UD部分通常應該只是每個方法的一個方法,並且通常應該只接受該聚合根對象的一個​​實例並對其進行操作(例如.e.g。repo.Save(order))。其他可能的參數可能在那裏,但這取決於你的impl。事實上,你通常可以解決絕大多數具有繼承性的C-UD部分(即,使用一些已知邏輯來製作一個RepositoryBase,這個邏輯關於你的特定持久化方案會發生什麼)。

這樣就給我們留下了CRUD的R部分。在這種情況下,如果您選擇執行查詢方法路由,您可能會得到大量查詢方法(GetById; GetByName; GetByCustomerName等)。有些人喜歡,尤其是簡單的應用程序,暴露一個基於linq的接口(例如IQueryable GetAll()),然後可以應用Where子句。YMMV取決於你的潛在持久性,但它對於簡單的應用程序來說是一個穩固的鏡頭,如果你期望持久化提供者直接支持linq。

最後,許多人通過命令查詢責任分離模式的一個實現或另一個實際分離出查詢部分,該模式表示用於持久化和查詢的接口應該是不同的。在這種情況下,您將擁有一個只有基本CRUD(GetById,GetAll,Save,Delete)操作的回購,以及另一類根據您的應用意圖查詢事物的類。

希望有所幫助。

Paul

+0

Paul感謝您的詳細解答。經過深思熟慮和閱讀後,我覺得你發現每個聚合根目錄有一個存儲庫/服務。您對CRUD也是正確的,每種方法都有C_UD和R的許多方法。在您的Order例子中,OrderRepository是否也會爲OrderLines和OrderSubLines放置R方法? – bradjive 2010-03-17 13:26:28

+0

這是一個很好的問題,這取決於。訂單和子行實際上是否意味着任何有用的W/O相關訂單?如果是這樣,那麼是的,如果沒有,那麼你所有的查詢都必須做w/Orders,你可以使用常規的LINQ表達式在IEnumerables上過濾子集合。 – Paul 2010-03-17 15:41:13

3

這是我最近問的一個問題,儘管得到了好幾個很好的答案,但我終於得出了我自己的結論 - 沒有正確的答案。這並不意味着沒有錯誤的答案,事實上有很多錯誤的答案,但正確的答案總是取決於你自己的個案。

我最終得到了四個存儲庫,還有我的EF4實體模型的部分類擴展,用於子實體(地址,電話號碼,狀態代碼等)的標準CRUD操作,因此它們實現了一次並可用於所有庫。但是,我仍在繼續細化,所以或許我還沒有遇到最好的解決方案。

我的建議是嘗試一下,看看它是否合適,看看它是否正確。通常,如果它不對感覺正確,反正它錯了。

如果你真的害怕混亂你的源代碼樹,你總是可以將模型部分分解到它自己的庫中,並將它作爲依賴包含進來。