2011-09-28 29 views
5

在我的服務外觀層中,我有一個服務類,其中包含一個接受DTO(數據合約)對象的方法/操作。 AutoMapper用於將此DTO映射到我的域對象的實例中以應用任何更改。該請求被傳遞到我的域服務上,該服務執行實際的工作。這裏的方法可能是什麼樣子:使用IoC驗證SOA應用程序中的DDD

public EntityContract AddEntity(EntityContract requestContract) 
{ 
    var entity = Mapper.Map<EntityContract, Entity>(requestContract); 

    var updatedEntity = Service.AddEntity(entity); 

    var responseContract = Mapper.Map<Entity, EntityContract>(updatedEntity); 

    return responseContract; 
} 

的服務和映射屬性是通過構造器注入與團結作爲IoC容器集。

在執行操作時,該域的服務進行改變的實體然後使用一個存儲庫,以堅持像的變化:

public Entity AddEntity(Entity entity) 
{ 
    // Make changes to entity 

    Repository.Add(entity); 

    // Prepare return value 
} 

存儲庫是使用構造器注入也被設置。

的問題是,一旦它已經堅持,所以我要確保沒有無效數據持久化數據變得立即提供給其他客戶。我讀過DDD(埃文斯)和Nilsson的「藍皮書」,我不清楚我應該採取什麼方法進行驗證。

如果我的目標是防止實體進入無效狀態,我應該驗證entityContract在我服務的方法,以確保所有的規則都滿足不斷請求傳遞到我的域名服務之前?我毫不猶豫地這樣做,因爲它好像我打破封裝在服務門面中定義這些規則。

我們使用薄層門面層委託給域服務的原因是我們在API中公開了粗粒度的接口,但是通過細粒度域服務的組合支持重用。請記住,多個Facade服務可能調用相同的域服務方法,可能將這些規則委託給域服務會更好,因此我們知道每個使用都經過驗證。或者我應該在兩個地方進行驗證?

我也可以把守衛在屬性設置器,以防止從不斷把實體爲無效狀態不可接受的值。這意味着AutoMapper在嘗試映射無效值時會失敗。但是,當沒有值映射時,它不起作用。

我仍然不能讓過去的思維,這些規則是實體的行爲的一部分,並確定該對象是否有效應該在實體內進行封裝。這是錯的嗎?

所以首先我需要確定何時何地執行這些驗證檢查。然後我需要弄清楚如何使用DI實現,從而使依賴關係解耦。

您可以提供哪些建議?

回答

4

我已經讀過DDD(埃文斯)以及尼爾森的「藍皮書」,我不清楚我應該採用什麼方法進行驗證。

藍皮書從不同的角度處理該問題。我認爲「驗證」一詞不被使用,因爲它是一個危險的overgeneralization。更好的方法是考慮對象不變量,而不是驗證。對象(不僅在DDD中)應該自己執行它們的內部不變量。它不是UI或服務或合同或映射器或「驗證框架」或對象外部的任何其他內容。不變量在內部執行。您可能會發現這些答案有幫助:1234

我也可以把守衛在屬性設置器,以防止從不斷把實體爲無效 狀態 不可接受的值。這意味着AutoMapper在嘗試映射 無效值時會失敗。

您可能不應該在乎AutoMapper失敗或使用AutoMapper。域對象應封裝並執行其內部不變量,並在嘗試破壞它時引發異常。這是非常簡單的,你不應該因爲某些基礎設施問題而損害域對象的簡單性和表現力。 DDD的目標不是滿足AutoMapper或任何其他框架的要求。如果框架不適用於您的域對象,請不要使用它。

+0

鏈接很棒。現在很明顯,允許對象進入無效狀態並提供錯誤列表(例如,通過IDataErrorInfo)的交互式驗證屬於UI /表示層(ViewModel)。而且我很擅長將守衛放入我的域對象中,以防止它們進入無效狀態。但是你是否主張將檢查放入服務和/或外觀層,除非它們跨越多個實體/聚合體? – SonOfPirate

+1

您可以根據需要將其他檢查放入服務和UI中。我的觀點是域對象不應該依賴這些檢查。 – Dmitry

+0

@SonOfPirate - 出於利益考慮,我使用CodeContracts在我的域對象中執行不變量。 – RobertMS

1

你有兩種類型的驗證:

  1. 對象的一致性:是實體的責任。實體不應該允許您將它們設置爲無效狀態,應該強制實施相關性,值應該在範圍內。你必須設計類的方法和屬性以及構造函數不允許無效狀態。

  2. 業務角色驗證:這種驗證類型需要服務器處理,如檢查ID可用性,電子郵件唯一性等。這些類型的驗證應在服務器中作爲驗證器或規格在持久性之前處理。

+3

我提供了第三個:UI驗證。這旨在爲用戶提供交互式反饋。我認爲這是更多的驗證框架(如數據註釋和企業庫)的目標,而不是實現其他兩種類型。 – SonOfPirate

+1

是的你是對的,我只專注於領域層的驗證,在UI中也有驗證,在視圖模型或演示模型中使用任何UI兼容的驗證框架來處理 –

+0

我同意你必須有自我驗證域。你是否在域對象中注入了一些驗證器以進行復雜(業務規則)驗證? 並且您是否在命令(DTO)的應用程序層中具有基本驗證? – danfromisrael