domain-driven-design - CQRS 和同步操作(如用户注册)

标签 domain-driven-design cqrs domain-events

我正在采用 DDD 概念来设计我们的下一个项目,更具体地说是 CQRS。

在阅读了很多东西之后,我现在正在尝试实现一个简单的概念证明。

问题是我刚开始就被卡住了:p

我正在尝试将此方法应用于简单的用户注册过程,其中步骤是:

  • 用户填写注册表并提交请求
  • 该应用程序创建用户
  • 该应用程序对用户进行身份验证(自动登录)
  • 该应用程序向用户发送验证电子邮件
  • 该应用程序使用确认消息将用户重定向到其他地方

  • 从实现的角度来看,到目前为止我得到的是:
  • Controller 操作将请求数据映射到 RegisterCommand 对象
  • Controller 操作要求命令总线处理 RegisterCommand
  • 命令处理程序(UserService)“注册”方法创建一个新的用户对象(无论是通过新命令还是工厂对象)
  • 该模型引发了一个 RegisterEvent
  • 命令处理程序要求存储库存储新的用户对象

  • 就是这样, Controller Action 不知道任何这些。

    所以,我的猜测是,由于此上下文中的所有内容都必须同步完成(发送电子邮件除外),我可以使用直接/同步命令总线,并且在 Controller 操作中,在命令总线调用之后,我可以查询对于只读用户(查询数据库),如果存在,则假设一切顺利,因此我可以给用户一条确认消息。

    由事件处理程序处理的自动登录过程。

    假设这是正确的,如果出现问题怎么办,如何用正确的信息通知用户?

    我们可以在互联网上找到的文章中经常使用一个常见的例子:客户使用过期的信用卡支付订单。系统接受请求,通知用户一切正常,但几分钟后用户收到一封电子邮件,告诉他他的订单无法处理。

    嗯,这种情况在许多情况下是可以接受的,但对于其他一些情况,这是不可能的。那么处理这些用例的示例在哪里? :p

    谢谢 !

    最佳答案

    我认为这个注册用例比你想象的更接近支付订单用例。

    大多数 CQRS 思想领袖建议在发出命令之前在读取端进行验证,从而使您的命令成功的可能性更高。

    如果在读取端验证失败,您知道如何处理这个问题 - 在您发送注册命令之前让用户选择另一个名称。如果验证成功,发送命令——现在你说的最多可能是几百微秒,在你验证命令和发送命令之间,另一个用户可能已经进入并使用相同的用户名。不大可能。

    在这种情况发生的极少数情况下,您的行为与信用卡过期示例相同 - 下次用户登录时,您向他们提供解释和提交新用户名的表格 - 或发送他们收到一封电子邮件,内容是“嘿 - 其他人拥有该用户名,请单击此处选择一个新用户名”。为什么这样做?因为您拥有该用户的唯一 ID。

    看看像 Twitter 这样的用户注册页面。只要您输入用户名,它就会发出一个小小的 Ajax 调用并说“不,这个被占用了”或“这个很好!”那是预验证。

    我希望这有帮助!

    关于domain-driven-design - CQRS 和同步操作(如用户注册),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16250666/

    相关文章:

    c# - 哪个类应该负责为实体创建 ID?

    c# - 领域事件模式单点队列事件

    autofac - 将 Autofac 与领域事件结合使用

    java - 从 Google Datastore 加载 DDD 实体的设计模式是什么?

    typescript - DDD如何正确分离权限和角色

    java - 使用 Hibernate 实现基于集合 (DDD) 的存储库

    domain-driven-design - 事件源系统中的预测

    cqrs - 在事件存储中保留每个聚合的最新版本的快照

    user-interface - 什么是基于任务的 UI 的示例?

    php - PHP 中的 DDD -> 投影仪 -> 投影仪的注册方法应该在何时何地调用?