【问题标题】:Guid of created aggregate root in CQRSCQRS 中创建的聚合根的 Guid
【发布时间】:2014-06-24 10:11:51
【问题描述】:

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(一段时间后的可能性)。任何反馈将不胜感激。谢谢。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 在 Vernon Vaughn 的书:实施领域驱动设计中,他们实际上主张让创建聚合根 (gu)id 成为基础架构问题。我想我可以将聚合根的 (gu)id 添加到命令中。您认为这可以接受吗?
    • 在我的上一个项目中,我们开始使用由基础设施生成的实体 ID。它们是字符串。但不管是谁生成的 ID,它当然必须出现在命令上,这样你才能找到它来调用你的域逻辑!我希望您的命令上的 GUID(可能对关联写入和读取模型有用)应该显示在消息信封或命令基础结构中,而不是出现在每个程序员定义的命令中。
    • 您能否提供有关如何关联读写模型的更多参考资料。我也很好奇,我一直认为命令总线是单向的,那么在 commandBus.Publish(SomeImportantCommand); 之后如何获取消息(又名请求/响应模式?) commandBus.Commit();
    • 如有更多问题,请在 SO 上发布新问题,或发布到 DDD 邮件列表之一!
    • 我已经提出了一些问题。那里的社区似乎比 SO 更有帮助(-:。无论如何,谢谢。
    【解决方案2】:

    执行此操作的最简单方法是使用您传递给命令的 guid 作为实际聚合 Id,然后您就可以使用它,而不必等待它在事件中被传回

    /p>

    【讨论】:

    • 谢谢,我就是这么想的。你如何处理“最终一致性”?如果用户在详细信息页面的详细信息位于读取模型中之前导航到聚合根的详细信息页面会发生什么?谢谢。
    【解决方案3】:

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

    通常只需创建聚合 ID 并使用命令发送。毕竟命令是创建实体..

    在大多数情况下,命令应该是同步的,这样您就可以将错误返回。使用 async 命令,您确实应该对成功或失败进行回调(并且 async 应该只在您真正需要的地方使用,它会增加系统的大量成本)。

    您不会进入下一步(如果您需要下一步),直到 A)它是一个处理最终一致性的系统,很多业务逻辑都这样做。例如,等待交易所或第 3 方处理某事,则工作正在等待该信息。 (即命令创建了一个订单,但订单的处理,例如 OrderDetail 可能还没有,并且订单处于订单处理状态) B) 在继续之前,您对命令有成功、超时或失败响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 2017-08-25
      • 2022-03-23
      • 2018-09-13
      • 1970-01-01
      相关资源
      最近更新 更多