一種策略是實施可以驗證約束的服務。
public interface IWebsiteUniquenessValidator
{
bool IsWebsiteUnique(string websiteUrl);
}
這樣您就可以實現它,你怎麼做,這將取決於多種因素,我不知道,但我建議不要擔心通過域去。簡單一點,它只是一個查詢(* - 我會在底部添加)。
public class WebsiteUniquenessValidator : IWebsiteUniquenessValidator
{
//.....
}
然後,「注入」到需要它的方法中。我說「注入」是因爲我們將它從域外提供給域對象,但是..我們將使用方法參數而不是構造函數參數來實現(爲了避免要求我們的實體被我們的IoC容器實例化)。
public class User
{
public void AddWebsite(string websiteUrl, IWebsiteUniquenessValidator uniquenessValidator)
{
if (!uniquenessValidator.IsWebsiteUnique(websiteUrl) {
throw new ValidationException(...);
}
//....
}
}
無論你的用戶和信息庫的消費者 - 如果這是一個服務類或CommandHandler - 可以提供獨特的驗證依賴。該消費者應該已經通過國際奧委會有線了,因爲它會消耗UserRepository:
public class UserService
{
private readonly IUserRepository _repo;
private readonly IWebsiteUniquenessValidator _validator;
public UserService(IUserRepository repo, IWebsiteUniquenessValidator validator)
{
_repo = repo;
_validator = validator;
}
public Result AddWebsiteToUser(Guid userId, string websiteUrl)
{
try {
var user = _repo.Get(userId);
user.AddWebsite(websiteUrl, _validator);
}
catch (AggregateNotFoundException ex) {
//....
}
catch (ValidationException ex) {
//....
}
}
}
*我提到做驗證簡單,避免域。
我們構建域來封裝與修改數據有關的常常複雜的行爲。
什麼經驗表明,關於數據變化的要求與查詢數據的要求有很大不同。
這似乎是你遇到的一個痛點,因爲你試圖強制讀取通過寫入系統。
爲了減輕這些痛點,可以從寫入端分離數據從域中讀取數據。
CQRS是該技術的名稱。我只是說,一旦我在CQRS的上下文中查看DDD,就會點擊一大堆燈泡。我強烈建議試着理解CQRS的概念。
是的,但是當一個網站無法在沒有用戶的情況下存在(一對多)時,我將如何搜索與具有特定URL的網站相關聯的用戶? – ebb 2011-02-10 22:24:47
@ebb,最終,我只是提出了一些簡單的選擇:從用戶u選擇u.UserId加入w.UserId = u.UserId的網站w其中w.Url = @ url`(但由您的存儲庫的成語指定標準)。 – 2011-02-11 01:54:36