为什么要使用 MediatR 的 3 个理由和 1 个不使用它的原因

https://codeopinion.com/why-use-mediatr-3-reasons-why-and-1-reason-not/

来自 Jimmy BogardMediatR 库 在过去的几年中,正在变得难以置信地流行,它也确实值的这样受到欢迎。它对自己的定义是:简单、平凡的 .NET 中介者模式的实现。那为什么那么多的开发者使用它呢?为什么你也应该使用 MediatR? 这里给出你至少需要考虑使用它的 3 个理由,还有一个为什么你不应该使用它的理由。

什么是 MediatR?

对于不熟悉 MdeidatR 或者不熟悉中介者模式的人来说:

对于软件开发人员来说,中介者模式定义了一个封装一组对象相互交互的对象。该模式是属于行为模式的一种,因为它可以扩展程序运行的行为。

原因 1: 解藕

多数演示 MediatR 的示例使用 ASP.NET Core,但是这并不意味着这是它创建价值的仅有框架。关键是从顶层的框架代码中解藕你的应用代码,而不用关心代码是否真正负责执行你的代码。

这里有一个使用 ASP.NET Core MVC 的示例。

关键点是创建一个请求对象,将它传递给 MediatR,由 MediatR 负责调用针对该请求对象的正确的处理器。

而这里的 PlaceOrderHandler 下单处理器对象完全不需要饮用任何类型或者 ASP.NET Core 的 API。

原因 2: 应用程序请求

至于为什么从顶层框架解藕,例如与 ASP.NET Core 解藕的重要性,问一下自己:我正在创建的是一个应用程序,还是一个 Web 应用程序?

这里的区别是:Web 应用程序是应用程序的一种。

应用程序可以有多种不同的输入。不是所有的请求都通过 HTTP 来实现。这里可能有多种方式与你的应用程序交互。

例如,你可能有需要重复执行的任务,在日常中的特定时间处理特定的操作。或者你可能存在通过消息中间件中抽取特定的消息来触发的任务。

在你的系统中,存在着通过各种方式来调用程序的行为,而不仅仅是通过 HTTP 请求。

在上面的 ASP.NET Core 示例中,我们将来自 HTTP 的请求最终转换成为一个应用程序请求对象。该应用程序请求对象完全从系统的顶级框架中解藕,从而可以在任何地方使用该对象。

使用 MediatR 来创建应用程序请求对象就可以跨越集成边界。

原因 3: 请求处理管线

一旦你能够通过应用程序请求对象来考虑问题,你就可以通过这些请求对象来深入考虑创建请求处理管线。

如果你熟悉 ASP.NET Core 的中间件的话,你会知道它的目的是定义 HTTP 请求的处理管线。

你还可以通过 MediatR 来创建同样的概念。有几种不同的方式可以创建它,这里介绍一种实现 IPipelineBehavior 的示例。

当调用 mediator.Send() 的时候,在调用你的基础处理器处理 (PlaceOrderHander) 之前。 RequestHandlerDelegate 负责调用 PlaceOrderHandler。这就使得我们可以在真正的处理之前切入处理,甚至可以短路而完全不调用它。比如说存在输入数据验证问题的时候。

这就意味着你可以创建任意数目的前置处理器,或者在执行实际行为之后的后置处理器。

它难以置信的强大,支持你可以从你的应用程序请求中分离各种关注点。

为什么不使用它?

不使用 MediatR 的原因很简单,就是所有的处理都是进程内的。这意味着当调用 mediator.Send() 的时候,处理请求的相关处理器也是在同样的进程中执行。

NServiceBus 的作者 Udi Dahan 在我的响应下提出这个问题:

您认为驱使人们从基于 MediatR 的解决方案转向利用进程外消息传递的解决方案的痛点/动机是什么?

进程外的动机将是库功能中的所有附加构建(重试/失败/等)。更快地使用收到的 msg 响应到调用方(不是已处理)。

你有没有发现,在人们开始不使用进程内处理的时候,会因为没有这些东西而感到痛苦?如果是这样,根据你的经验,他们的旅程在多大程度上表现出来?

事件,最大触发器转移到进程外,我猜,在进程内,尽管每个处理程序都是独立的,但异常可能会使整个初始请求失败链失败(取决于异常处理)。一旦你感受到那种痛苦,我会说这就是转折点

用更简单的话来说,您希望每个事件处理程序独立执行

由于所有的处理都是进程内,这对于 Events/Notification (MediatR 称它们为 Nofifications ) 变得显而易见

对于 Notification 来说,它可以拥有 0 到多个处理器。不过,所有的的 Notification 处理器都是在相同的进程中执行的。

在上面的示例中,如果你将一个 Notification 推入到 MediatR 中,这里有 3 个处理器处理该 Notification。它将会执行全部 3 个处理。不过,如果其中一个抛出了异常,会发生什么呢?

该异常会冒泡到你通过 MediatR 发布消息的地方。你将会如何处理它呢?你会重新发布该消息,以便在重新执行的时候成功执行它?如果任务之一是发送邮件呢?

你希望在隔离状态下执行事件处理。这就是转而使用进程外消息的时刻。

在这种场景下,你可能希望看一下 NServiceBus, Brighter, MassTransit, Rebus

# 为什么要使用 MediatR 的 3 个理由和 1 个不使用它的原因的更多相关文章

  1. 浅析Java 泛型

    泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...

  2. Java内部类的定义和使用

    为什么要用到内部类: 在java开发学习中我们经常会碰到内部类.内部类又有很多的优势:首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法名称参数相同,你应 ...

  3. 短视频APP+不同类型社交应用发展分析+化妆品电商

    短视频APP——昙花一现还是发展趋势? 在这个互联网与科技并行且飞速发展的时代,各种app不断涌入市场,其中短视频app便是一个典型,美拍,就成功入围2014年十大最火app.而短视频app也势必要成 ...

  4. python基础知识8——模块1——自定义模块和第三方开源模块

    模块的认识 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需 ...

  5. IT技术开发人员获得成功的六大步骤

    IT技术开发人士成功的6大步骤 一个前辈在移民加拿大后写的文章,写得不错,值得借鉴,转来给大家看看,也给自己   序言:经过001多年的洗礼,认识了这里这么多的JJMMGGDD,前几天刚得到签证, 无 ...

  6. (转)Shadow Map & Shadow Volume

    转自:http://blog.csdn.net/hippig/article/details/7858574 shadow volume 这个术语几乎是随着 DOOM3 的发布而成为FPS 玩家和图形 ...

  7. 【转】如何使用Android Studio把自己的Android library分发到jCenter和Maven Central

    转自:http://www.devtf.cn/?p=760&utm_source=tuicool 如何使用Android Studio把自己的Android library分发到jCenter ...

  8. APP store 上架过程中碰到的那些坑&被拒的各种奇葩原因整理&审核指南中文版

    苹果官方发布的十大常见被拒原因 1.崩溃次数和Bug数量.苹果要求开发者在将应用提交给App Store之前彻查自己的应用,以尽量避免Bug的存在. 2.链或错误的链接.应用中所有的链接必须是真实且有 ...

  9. java内部类的作用分析

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  10. 单片机设计与KeilC编程总结

    1基本原则    质量是关键.没有人会对很差的工作感到满足.当完成高质量的工作时,你会为此而感到骄傲.不管你是否知道,你都会因为你的高质量工作而得到信誉.因此,要想为自己所做的事感到骄傲,就需要建立个 ...

随机推荐

  1. 封装大屏组件 screenfull

    错误场景:使用大屏插件 screenFull 报错:in ./node_modules/screenfull/index.js  Module parse failed: Unexpected tok ...

  2. 014 Python 的数据类型(数字、字符串、列表、字典)

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Datatime:2022/7/24 20:31 # Filename:014 Python 的数据类型( ...

  3. 0608-nn和autograd的区别

    0608-nn和autograd的区别 目录 一.nn 和 autograd 的区别 二.Function 和 Module 在实际中使用的情况 pytorch完整教程目录:https://www.c ...

  4. day15-三大基本结构

    顺序结构 Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行. 顺序结构是最简单的算法结构. 语句和语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组 ...

  5. 使用Pydantic和SqlAlchemy实现树形列表数据(自引用表关系)的处理,以及递归方式处理数据差异

    在我的设计框架业务中,字典大类.部门机构.系统菜单等这些表,都存在id.pid的字段,主要是作为自引用关系,实现树形列表数据的处理的,因为这样可以实现无限层级的树形列表.在实际使用Pydantic和S ...

  6. 使用 KubeKey 安装部署 Kubernetes 与 Kube-OVN

    作者简介:林瑞超,锐捷网络开发工程师, KubeSphere 社区 contributor, 关注Kube-OVN, Cilium 等容器网络相关技术 背景 KubeKey 是 KubeSphere ...

  7. 解决ros-melodic-desktop-full安装过程中未满足的依赖关系问题

    sudo apt install ros-melodic-desktop-full 正在读取软件包列表- 完成正在分析软件包的依赖关系树 正在读取状态信息- 完成 有一些软件包无法被安装.如果您用的是 ...

  8. vue,js直接导出excel,xlsx的方法,XLSX_STYLE 行高设置失效的问题解决,冻结窗体修改支持

    1.先安装依赖:xlsx.xlsx-style.file-saver三个包 npm install xlsx xlsx-style file-saver 出现错误: This relative mod ...

  9. 还在为慢速数据传输苦恼?Linux 零拷贝技术来帮你!

    前言 程序员的终极追求是什么?当系统流量大增,用户体验却丝滑依旧?没错!然而,在大量文件传输.数据传递的场景中,传统的"数据搬运"却拖慢了性能.为了解决这一痛点,Linux 推出了 ...

  10. 『玩转Streamlit』--文本与标题组件

    本篇准备开始介绍Streamlit的组件. Streamlit的组件非常多,后续几篇打算按照用途的分类,介绍每个分类中最常用的组件. 本次从最简单的组件开始,介绍文本和标题相关的组件,也就是以下4个组 ...