2014-06-24 26 views
2

創建的彙集根從here看這段代碼:的GUID CQRS

[Serializable] 
public class CreateClientCommand : Command 
{ 
    public string ClientName { get; private set; } 
    public string Street { get; private set; } 
    public string StreetNumber { get; private set; } 
    public string PostalCode { get; private set; } 
    public string City { get; private set; } 
    public string PhoneNumber { get; private set; } 

    public CreateClientCommand(Guid id, string clientName, string street, string streetNumber, string postalCode, string city, string phoneNumber) : base(id) 
    { 
     ClientName = clientName; 
     Street = street; 
     StreetNumber = streetNumber; 
     PostalCode = postalCode; 
     City = city; 
     PhoneNumber = phoneNumber; 
    } 
} 

的GUID這裏是命令只是有關。它不是(可能)創建的聚合根的Guid。獲得Guid的最佳做法是什麼?以及如何將任何潛在的驗證錯誤反饋給將命令放在總線上的代碼?例如像這樣:

_bus.Publish(new CreateClientCommand(
    Guid.NewGuid(), 
    _clientDetailsReport.ClientName, 
    _clientDetailsReport.Street, 
    _clientDetailsReport.StreetNumber, 
    _clientDetailsReport.PostalCode, 
    _clientDetailsReport.City, 
    _clientDetailsView.PhoneNumber)); 

_bus.Commit(); 

我知道CQRS通常會實現最終的一致性。這意味着它可能需要一段時間才能真正創建客戶端。一些MVC/CQRS代碼使用了這種方法:

[HttpPost] 
public ActionResult Add(DiaryItemDto item) 
{ 
    ServiceLocator.CommandBus.Send(new CreateItemCommand(Guid.NewGuid(),item.Title,item.Description,-1,item.From,item.To)); 

    return RedirectToAction("Index"); 
} 

顯然,索引頁可能顯示含有一些電網DiaryItems和用戶可能能夠看到最新創建DiaryItem(過了一會兒潛力)。任何反饋將非常感激。謝謝。

回答

2

您是否詢問命令本身的ID與它可能創建的實體的ID之間的區別?前者通常是一種基礎設施問題,可以通過諸如郵件信封,埋在RPC協議之類的東西中找到。後者將成爲你的域名的一部分。 (儘管在很多情況下,將一個實體的ID作爲一個基礎設施問題處理也不錯,因爲您可能會在您的持久性模型中爲了方便而選擇它。)

+0

在Vernon Vaughn的書中:實現領域驅動設計他們實際上認爲創建聚合根(gu)id是一個基礎設施問題。我想我可以將聚合根(gu)id添加到命令中。你認爲這可以接受嗎? – cs0815

+1

在我上一個項目中,我們轉向了由基礎結構生成的實體標識。他們是字符串。但是不管是誰生成的ID,它當然必須出現在命令中,所以你可以找到它來調用你的域邏輯!我想你的命令上的GUID(可能用於關聯寫入和讀取模型)應顯示在消息包中或命令基礎結構中,而不是每個程序員定義的命令中。 –

+0

您可以提供關於如何關聯讀寫模型的更多參考資料。我也很好奇,我一直認爲命令總線是單向的,那麼在commandBus.Publish(SomeImportantCommand)之後如何獲得消息(aka請求/響應模式?); commandBus.Commit(); – cs0815

2

最簡單的方法是使用guid你傳遞命令作爲實際的聚合ID,然後你有它,並且不必等待它在事件中傳遞回來

+1

感謝這就是我的想法。你如何處理'最終一致性'?如果用戶在詳細信息頁面之前導航到聚合根的詳細信息頁面細節在閱讀模型中?謝謝。 – cs0815

1

不確定爲什麼你的命令有一個ID它混淆了事情(是的,一些分佈式系統使用這個,但它應該是最後的手段)。大多數開發人員會將此視爲聚合的標識。

通常只需創建聚合ID並使用該命令發送它。在所有的命令創建實體之後..

命令在大多數情況下應該是同步的,所以你可以拋出錯誤。有了異步命令,你真的應該有一個成功或失敗的回調(而異步只能用在你真正需要的地方,這會增加系統的成本)。

您不會轉到下一步(如果您需要下一步),直到 A)它是一個處理最終一致性的系統,許多業務邏輯都這樣做。例如等待交易所或第三方處理某些事情,那麼該工作正在等待這些信息。 (即命令創建一個訂單,但訂單的處理例如OrderDetail可能還沒有完成,訂單處於訂單處理狀態)B)在繼續操作之前,您有成功,超時或失敗的響應。