4

我正試圖將我的應用程序從每個實體的存儲庫重構爲每個聚合根的存儲庫。獲取所有聚合根實體子實體?

一個基本的例子是我有一個Cars的實體根。汽車有租賃合同。據我所見,沒有汽車的合同不存在,因此汽車是合計的根源。

我想實現一個用戶視圖,它將顯示系統中的每個合約(根實體的所有子實體)。在重構之前,我可以去我的合同倉庫並獲取全部。由於合同存儲庫已被刪除(因爲它不是根目錄),我現在需要將所有汽車從我的存儲庫中取出,然後獲取所有合同。

我的庫具有接口

public interface ICarRepository 
{ 
    IQueryable<Car> All { get; } 
    IQueryable<Car> AllIncluding(params Expression<Func<Car, object>>[] includeProperties); 
    Car Find(long id); 
    void InsertOrUpdate(Car car); 
    void Delete(long id); 
    void Save(); 
} 

我想創建ICarManagementService和具有它具有GetAllContracts方法(或許與濾波器參數)的。這是否意味着獲得我需要的所有合同,將所有車輛實體與他們的合同一起取出,然後檢索每個實體相關的聘用合同並對其進行過濾?

然後,我可以將這些傳遞給控制器​​並像以前一樣自動映射合同。

這是最佳實踐嗎?

由於

格雷姆

回答

4

據我所見合同不存在沒有汽車因此汽車是 聚合根。

這不一定是正確的。 '不存在'對於一個實體成爲聚合根的一部分是不夠的。考慮傳統的訂單處理域。您的訂單是一個聚合根。您也有一個客戶是一個聚合根。如果沒有客戶,訂單就不能存在,但這並不意味着訂單是客戶彙總的一部分。在DDD中,一個Aggregate內的實體可以引用其他Aggregate Roots。從DDD book:聚集內

對象可以抱到其他聚合 根引用。

聚合是一個生命週期和數據交換單元。它本質上是一組強制執行不變量的對象。如果您有多個用戶同時更改域,則這是您想要鎖定的內容。

回到你的問題,我的理解是,該域名就像是租賃/租賃汽車/卡車/豪華轎車/推土機。我認爲HireContract可能不是Car聚合的一部分,因爲它們可能有不同的生命週期,而HireContract只有在沒有Car的情況下才有意義。它似乎更像是一種訂單 - 產品關係,它也是兩個不同集合之間相互引用的經典示例。企業需要看到「所有合同」這一事實也證實了這一理論。他們可能不認爲含有所有合同的汽車。如果這是真的,則需要保留ContractsRepository。

在不相關的說明中,您可能有興趣閱讀有關存儲庫接口設計的此answer

+0

我確實認爲我希望人們能夠鎖定「汽車」進行編輯。我可以看到僱傭合同是一個總計。我需要防止人們能夠增加重疊的聘用期。如果僱用是一個總計,我還能執行嗎? – GraemeMiller

+0

如果不能很好地理解你的域名,很難回答這個問題。但我可以給你一個提示。 Udi Dahan和/或Greg Young提到了一種方法,您應該設法想象如何在沒有計算機的情況下在「基於紙張的」業務中實施此功能。這可能會導致更多的異步方法(允許僱傭期臨時重疊,亞馬遜允許兩個客戶訂購該書,即使只有1個庫存,然後通過電子郵件通知您)。如果您刪除「所有內容應始終保持100%一致」的限制,可以實現很多功能。 – Dmitry

+0

稍後可能會發布更詳細的問題。我這本藍皮書的副本應該在本週到達,所以希望我能更好地掌握良好的DDD練習。謝謝您的幫助。 – GraemeMiller

2

單獨從寫/命令讀取/查詢的概念,通過CQRS作爲引導,優選通過分離讀取模型,其由只讀查詢和所述的來設計應用程序另一方面寫模型,它由在域模型上執行某些邏輯的命令組成。

因此查詢所有聚合根或創建自定義查詢來連接數據集不是域存儲庫的好候選,而是將這些查詢放入讀取存儲庫(或更好地命名的Finders)。

如果您發現自己想要查詢對象集合以執行某些域邏輯,那麼這是一個指示器,您必須將此集合抽象出來並將其放入聚合根目錄中以封裝它們並進行業務操作或方法對他們採取行動。

結帳(http://moh-abed.com/2011/09/13/pure-old-ddd-with-a-twist-from-cqrs/)和(http:// simon-says- architecture.com/2011/08/23/repository)

相關問題