MediatR 发布和 MediatR 发送

MediatR publish and MediatR send

我已经使用 MediatR 尝试了 CQRS 模式,我喜欢应用程序正在转换的干净状态。 在我看到和使用的所有示例中,我总是这样做

await Mediator.Send(command);

查询也是如此

var data = await Mediator.Send(queryObject);

我刚刚发现还有 Mediator.Publish,在我搜索之后似乎也在做同样的事情。我想了解 Mediator.Send 和 Mediator.Publish 之间的区别。 我已经阅读了 MediatR 库文档,但我仍然不明白它们之间的区别。 请帮助我理解其中的区别。

感谢您的帮助

MediatR has two kinds of messages it dispatches:

  • Request/response messages, dispatched to a single handler
  • Notification messages, dispatched to multiple handlers
  • Send 可以 return 回应,但不一定非要这样做。
  • Publish 从未 return 结果。

您正通过 _mediator.Send({command}) 向一个具体的处理程序发送请求(有时称为 命令)。它可能是例如将新产品保存到数据库的命令。它通常是来自用户 (frontend/API) 的请求,有时它可能是由其他 service 以同步方式在您的系统中发出的内部命令。总是期望命令将立即执行并且您将收到一些正确的结果或错误以立即通知客户端一些失败。

您正在通过 _mediator.Publish({event}) 向零个、一个或多个处理程序发布通知(通常称为事件)。当你想发布一些信息但你不知道谁需要它时,你使用了通知。例如。 NewProductEvent 在成功将产品添加到您的 仓库模块 后发布。很少有其他上下文想要订阅信息,例如向客户发送新产品可用的电子邮件,或在您的 商店模块 中为产品创建一些默认配置(该产品支持付款和送货)。您可以以同步方式使用通知。所有数据都将保存在一次交易中(产品和商店配置),或者您可以使用一些异步模式 service bus or/and sagas。在第二种情况下(异步),当订阅您的通知的其他服务或上下文发生错误时,您必须手动处理这些情况。

示例场景:未创建默认配置。

  • 如果您有几个上下文的一个事务(同步方式),您将收到一个错误,记录该错误并return它到user/client。
  • 以异步方式,您在将新产品保存到数据库后发送事件。您不希望产品在您的系统中处于半错误状态。因此,首先我建议在 Draft 状态下创建它并等待通知您配置成功创建的事件,然后将状态更改为例如 New/Correct 等

使用 mediatR 的一个很好的例子你会在例如使用 EF 核心和 ASP Net 在 EShopOnContainers by Microsoft: github. You will see an example usage of CQRS and DDD 中订购微服务。