在CQRS中创建聚合根的Guid

时间:2014-06-24 10:11:52

标签: asp.net-mvc domain-driven-design cqrs ncqrs

查看here中的代码:

[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(一段时间后的潜力)。任何反馈都将非常感激。谢谢。

3 个答案:

答案 0 :(得分:2)

您是否在询问命令本身的ID与它可能创建的实体的ID之间的区别?前者通常是基础设施问题,可以在诸如消息信封之类的东西上找到,埋在RPC协议中等等。后者将成为您域名的一部分。 (虽然在很多情况下,将实体的ID视为基础设施问题也很好,因为您可以在持久性模型中方便地选择它。)

答案 1 :(得分:2)

最简单的方法是使用你在命令上传递的guid作为实际的聚合ID,然后你可以将它交给它,而不必等待它在事件上传回来< / p>

答案 2 :(得分:1)

不确定为什么你的命令有一个id它会混淆的东西(是的,一些分布式系统使用它,但它应该是最后的手段)。大多数开发人员会将此视为聚合的ID。

通常只需创建聚合ID并使用命令发送它。在所有命令创建实体之后..

在大多数情况下,命令应该是同步的,这样您就可以抛出错误。使用异步命令,您确实应该回调成功或失败(并且只应在真正需要的情况下使用async,这会给系统增加很多成本)。

您不会移动到下一步(如果您需要下一步),直到其中任何一步 A)它是一个处理最终一致性的系统,很多业务逻辑确实做到了这一点。例如,等待交换或第三方处理某些事情,然后工作正在等待该信息。 (即命令创建订单,但订单处理,例如OrderDetail可能尚未存在,订单处于订单处理状态) B)在继续之前,您对命令有成功,超时或失败响应。