MediatR 发布和 MediatR 发送

Posted

技术标签:

【中文标题】MediatR 发布和 MediatR 发送【英文标题】:MediatR publish and MediatR send 【发布时间】:2020-11-20 23:49:55 【问题描述】:

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

await Mediator.Send(command);

查询也一样

var data = await Mediator.Send(queryObject);

我刚刚意识到 Mediator.Publish 也有,在搜索后我觉得它也在做同样的事情。我试图了解 Mediator.Send 和 Mediator.Publish 之间的区别是什么。 我已经阅读了 MediatR 库文档,但我仍然不明白它们之间的区别。 请帮助我了解其中的区别。

感谢您的帮助

【问题讨论】:

我认为“发送”方法用于发送命令并给出响应,但“发布”方法用于发送事件并且不返回任何响应。 它确实为我指明了正确的方向。谢谢 【参考方案1】:

MediatR 发送两种消息:

请求/响应消息,分派到单个处理程序 通知消息,分派给多个处理程序
Send 可能会返回响应,但不必这样做。 Publish 从不返回结果。

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

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

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

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

使用 mediatR 的一个很好的例子,例如通过 Microsoft 在EShopOnContainers 中订购微服务:github。您将看到 CQRS 和 DDD 与 EF 核心和 ASP Net 的示例用法。

【讨论】:

太好了,谢谢你的解释。那么这意味着发布将用于域事件? 是的,但它也可能是应用程序/集成事件。 mediatR 与事件总线的集成示例在 EShopOnContainers 中

以上是关于MediatR 发布和 MediatR 发送的主要内容,如果未能解决你的问题,请参考以下文章

在 asp .net 核心中为 MediatR 库的发送和发布方法添加通用处理程序

MediatR 和 CQRS 测试。如何验证调用了该处理程序?

Spring 版MediatR--中介者模式实现库

使用 Moq 模拟 MediatR 3

如何使用 MediatR 进行测试

.NET 5 源代码生成器——MediatR——CQRS