【问题标题】:EDA: "Cascading" Events or Explicit commands?EDA:“级联”事件还是显式命令?
【发布时间】:2012-08-07 13:42:06
【问题描述】:

场景

假设我有一个系统的三个主要组件:

  1. UI - 收集用户的输入并创建通过消息总线发送的 LoginUserCommand。然后,用户界面会为 MessageReceivedEvent(s) 侦听此消息总线。

  2. 用户服务 - 接收 LoginUserCommand 并引发 UserLoggedInEvent。这里的关键部分是消息服务需要被告知开始接收消息。

  3. 消息服务 - 为登录的用户引发 MessageReceivedEvent(s)

选项

我的设计问题是关于 User ServiceMessage Service 之间的交互。

当用户登录时,需要发生许多事情 - 服务需要协调,以便 UI 开始接收消息。

我应该……

  • User Service 引发 UserLoggedInEvent 并让 Message Service 监听此事件并执行用户接收所需的工作消息?

...或...

  • User Service 引发 UserLoggedInEvent 但然后创建一个命令 - StartMessageReceivingCommand 并将其显式发送到 Message Service?

问题

每种方法的优缺点是什么? (级联事件与显式命令)。还有其他选择吗?

【问题讨论】:

    标签: nservicebus cqrs event-sourcing event-driven-design eda


    【解决方案1】:

    如果您的服务是真正的服务,只需引发 userloggedinevent 并让“消息服务”决定下一步做什么。 如果用户登录,用户服务应该不知道需要开始接收消息的消息服务。只需引发事件并让每个订阅者自己决定下一步做什么。

    【讨论】:

    • 我想这是最有意义的。如果我需要触发消息服务独立于 UserLoggedInEvent 接收消息,那么我应该让它接受命令 - 例如StartMessageReceivingForUserCommand?
    • 命令仅在服务内发送,因此如果您的消息服务的其他部分需要触发此命令,您可以发送该命令。那时您可能会重构您的 UserLoggedInEventHandler 以仅发送事件到达时的命令。
    【解决方案2】:

    这对我来说没有多大意义。 UI 本身并不是一个逻辑服务。

    消息服务 发布的MessageReceivedEvent 消息是否足够公开,以至于任何用户界面都可以订阅该提要?如果没有,那么也许这些消息根本不应该发布。

    如果不允许用户处理MessageReceivedEvents,除非他们已登录,那么用户/安全服务有责任确保不会发生这种情况。

    如果MessageReceivedEvents确实需要发布,那为什么不在UI进程中运行用户服务

    1. UI 进程订阅(向消息服务发送订阅请求)到MessageReceivedEvent
    2. UILoginUserCommand 发送到用户服务 的remtoe 端点并在本地处理UserLoggedInReply
    3. UI 进程中有两个MessageReceivedEvent 处理程序
      • 第一个处理程序属于用户服务,如果用户未登录,则调用 bus.DoNotContinueDispatchingCurrentMessageToHandlers()
      • 第二个处理程序属于其他一些服务,它实际上对MessageReceivedEvents 做了一些有用的事情

    在步骤 3 中,当用户登录时,第一个处理程序是空操作。如果用户没有登录,第一个处理程序将完全停止其他 MessageReceivedEvent 处理程序的运行。

    还有更多关于指定消息顺序here

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      • 2014-03-25
      相关资源
      最近更新 更多