前言

随着微服务的流行,而DDD(领域驱动设计)也光速般兴起,CRQS(Command Query Responsibility Seperation--命令查询职责分离)、领域事件名词是不是经常在耳边环绕,而MediatR组件经常用来对其技术的落地,凭这,小伙伴们说火不火?(强行引入主题,牛掰不!!!);但是今天不说微服务,也不说DDD,只说MediatR的使用,哈哈哈,开始吧;

正文

二话不说就上图,图中大概意思就是说:MediatR是用.Net实现的简单中介者模式,无需其他依赖就能处理进程内的消息传递,支持请求/响应、命令、查询、通知和事件的同步或异步传递,通过C#的泛型智能调度。

开源地址:https://github.com/jbogard/MediatR

Mediator有两种消息调度方式:

  • Request/Response(请求/响应)消息,只能单个处理程序处理;

    一个请求/响应消息由一个消息处理程序进行处理;通过实现IRequest接口来抽象请求/响应消息,实现IRequestHandler来进行消息处理;

  • Notification(通知)消息,可以由多个处理程序处理;

    一个通知消息由多个消息处理程序进行处理;通过实现INotification接口来抽象通知消息,实现INotificationHandler来进行消息处理;

刚才说到,MediatR组件实现了简单的中介者模式,刚好逮住机会说说中介者设计模式;

中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

大话设计模式

结构如下图(图来源于大话设计模式):

上面是不是有点专业,咱们找个生活中例子,比如房产中介,先假如没有房产中介这个中间对象时,卖房者和买房者之间都是互相关联,耦合在一起,卖房者之间可以互相推荐找优质房源给买房者,买房者之间也能互相分享好的房源,自己不适合,朋友或者亲戚可能适合,如下图:

上图看上去是不是显得每个人都很忙,而且需要对接不同的人,电话和信息肯定少不了,那是不是就没时间干其他的了,比如上班、陪孩、约会这些咋可能少嘛,对不对;有了房屋中介之后,看下图:

这样看着是不是比较清晰了,卖房找中介,买房找中介,通过中介统一分享信息,这样就忙房屋中介即可(人家专业,就是干这行的),其余每个人,就和中介交互信息即可。

结合上面的结构图和案例,代码如下:

由于有多个房屋中介公司,这里先将其进行抽象出来,相当于结构图中Mediator:

然后将卖房者和买房者进行抽象化,相当于结构图中的Colleague,如下:

实现具体的卖房者和买房者,相当于结构图中的ConcreteColleague1、ConcreteColleague2,如下:

实现具体的中介者,相当于结构图中的ConcreteMediator,如下图:

使用及运行效果如下:

由上可以明显感觉到中介者好处,各对象没有直接耦合,而是通过中介者进行各对象的连接,从原来的网状结构就变得相对单一;但具体的中介者的任务会因为ConcreteColleague的越来越多变得比较繁重,代码不容易维护,因为中介者需要了解所有ConcreteColleague对象操作; 以上买卖房的思想可能没有很好的体现各个ConcreteColleague交互,但如果换成房屋出租,感觉是不是稍微直接一点啦。

Mediator中介者模式就简单到这吧,回到文章主题MediatR组件,停!!!小伙伴会问:Mediator中介者和MediatR组件是不是哪个词写错了?如果指的是单词的话,MediatR不对,但从功能角度上看,MediatR不仅仅实现了Mediator中介者模式,而且加入了依赖注入,使得使用更加方便,这可能就是作者将其命名MediatR的原因吧。后续抽时间再和小伙伴们一起扒扒源代码,这里就先看看怎么使用,看看到底有多方便,先用控制台程序演示↓↓↓

请求/响应消息及其处理:

使用及运行如下图:

以上定义简单分为以下几步:

  1. 请求消息和请求消息处理类;
  2. 注册相关MediatR相关组件;
  3. 从容器中获取到中介者,通过中介者发送消息;

以上简单三步完成之后,对应消息类型的处理类就会自动处理,这就是据泛型智能处理对应消息功能。这些都是MediatR组件内部处理好,为小伙伴们减少创建对象、关联中介者、消息关联等操作。

请求/响应消息是一对一处理的,假如有多个处理怎么办呢?

结论:当同一个类型请求/响应消息有多个处理类时,会根据扫描注册时进行****覆盖,最终只有一个处理类生效。

应用场景:通常会用来实现CQRS(命令查询职责分离),也可以用于模块解耦相关场景。

注意:

  • IRequest代表无返回值;
  • IRequest代表有返回值,返回类型为T;
  • IRequestHandler<RequestMsg,T>中RequestMsg指消息类,代表该处理类只能处理RequestMsg的消息,T代表返回类型;

通知消息及其处理

使用及运行如下图:

通知消息是支持多处理类处理的。

应用场景:领域事件的实现;也可以用于业务分离场景,比如用户注册成功之后,需要进行消息发送通知,有邮件、微信、短信等方式。

在WebAPI中使用MediatR,如下:

跟着图中步骤走:

开始使用吧,走起:

跑起来看看,一气呵成,哈哈哈:

通过以上Demo可以看到,控制器现在和业务没有直接关系,不需要再和业务层关联,通过一个中介者完成业务流程,显得控制器更加清晰,只负责提供接口、接收数据和权限标注。上面Demo为了演示都把新增用户的命令消息和新增成功的事件消息都放在一起,其实在实际开发中可以根据需要进行归类。

总结

好啦,MediatR的应用就先到这吧,后续单独抽时间整理一篇源码和小伙伴一起分享。

整理了一些面试资料,关注公众号“Code综艺圈”,发送"面试"获取下载地址,至于教程,手里的也有一些Web前端、.Net后端、Java的教程,但现在网上资源比较多,大部分小伙伴喜欢在线看;如果有需要,小伙伴可以私聊我,目前先把面试相关的资料放上去,收集内容会持续更新,包含一些大厂面试题,助力小伙伴找到心仪的工作:

一个被程序搞丑的帅小伙,关注"Code综艺圈",识别关注跟我一起学~~~

撸文不易,莫要白瞟,三连走起~~~~

跟我一起学.NetCore之MediatR好像有点火的更多相关文章

  1. 跟我一起学.NetCore之MVC过滤器,这篇看完走路可以仰着头走

    前言 MVC过滤器在之前Asp.Net的时候就已经广泛使用啦,不管是面试还是工作,总有一个考点或是需求涉及到,可以毫不疑问的说,这个技术点是非常重要的: 在之前参与的面试中,得知很多小伙伴只知道有一两 ...

  2. 跟我一起学.NetCore之选项(Options)核心类型简介

    前言 .NetCore中提供的选项框架,我把其理解为配置组,主要是将服务中可供配置的项提取出来,封装成一个类型:从而服务可根据应用场景进行相关配置项的设置来满足需求,其中使用了依赖注入的形式,使得更加 ...

  3. 跟我一起学.NetCore之静态文件处理的那些事

    前言 如今前后端分离开发模式如火如荼,开发职责更加分明(当然前后端一起搞的模式也没有完全褪去):而对于每个公司产品实施来说,部署模式会稍有差别,有的会单独将前端文件部署为一个站点,有的会将前端文件和后 ...

  4. 跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)

    前言 撸码需谨慎,裸奔有风险.经常在一些技术交流群中了解到,还有很多小伙伴的项目中Api接口没有做任何安全机制验证,直接就裸奔了,对于一些临时项目或是个人小项目还好,其余的话,建议小伙伴们酌情考虑都加 ...

  5. 跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)

    前言 权限管控对于一个系统来说是非常重要的,最熟悉不过的是菜单权限和数据权限,上一节通过Jwt实现了认证,接下来用它实现接口权限的验证,为什么不是菜单权限呢?对于前后端分离而言,称其为接口权限感觉比较 ...

  6. 跟我一起学.NetCore之日志(Log)模型核心

    前言 鲁迅都说:没有日志的系统不能上线(鲁迅说:这句我没说过,但是在理)!日志对于一个系统而言,特别重要,不管是用于事务审计,还是用于系统排错,还是用于安全追踪.....都扮演了很重要的角色:之前有很 ...

  7. 跟我一起学.NetCore之中间件(Middleware)简介和解析请求管道构建

    前言 中间件(Middleware)对于Asp.NetCore项目来说,不能说重要,而是不能缺少,因为Asp.NetCore的请求管道就是通过一系列的中间件组成的:在服务器接收到请求之后,请求会经过请 ...

  8. 跟我一起学.NetCore之中间件(Middleware)应用和自定义

    前言 Asp.NetCore中的请求管道是通过一系列的中间件组成的,使得请求会根据需求进行对应的过滤和加工处理.在平时开发中会时常引用别人定义好的中间件,只需简单进行app.Usexxx就能完成中间件 ...

  9. 跟我一起学.NetCore之文件系统应用及核心浅析

    前言 在开发过程中,肯定避免不了读取文件操作,比如读取配置文件.上传和下载文件.Web中html.js.css.图片等静态资源的访问:在配置文件读取章节中有说到,针对不同配置源数据读取由对应的ICon ...

随机推荐

  1. DVWA从注入到GETSHELL

    好好过你的生活,不要老是忙着告诉别人你在干嘛. 最近在复习学过的东西,自己就重新搭了个dvwa来学习新思路,写一些简单的脚本来练习写代码的能力. 众所周知SQL注入的危害是相当大的,对于每个老司机来说 ...

  2. Hbuilder获取手机当前地理位置的天气

    前言:前面一段时间,公司项目里有一个需求 是获取当前手机地理位置当天的天气情况  将实时天气信息提供给客户.在网上搜索资料时候,发现知识很零碎,自己实现以后整理出来,方便于各位的学习与使用. 一.获取 ...

  3. mysql-6-groupby

    #进阶5:分组查询 /* SELECT FROM WHERE GROUP BY ORDER BY 查询列表要求是分组函数和 group by 之后出现的字段 1.筛选条件分为两类: 数据源 位置 关键 ...

  4. 无所不能的Embedding 2. FastText词向量&文本分类

    Fasttext是FaceBook开源的文本分类和词向量训练库.最初看其他教程看的我十分迷惑,咋的一会ngram是字符一会ngram又变成了单词,最后发现其实是两个模型,一个是文本分类模型[Ref2] ...

  5. puts()和gets()函数

    puts()和gets()函数 1. puts()函数 puts()函数用来向标准输出设备(屏幕)写字符串并换行, 其调用格式为: puts(s); 其中s为字符串变量(字符串数组名或字符串指针). ...

  6. #ifndef, #define, #endif三者的作用

    #ifndef, #define, #endif 作用   #ifndef 它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义.文件包含.条件编译) ...

  7. JVM性能调优(3) —— 内存分配和垃圾回收调优

    前序文章: JVM性能调优(1) -- JVM内存模型和类加载运行机制 JVM性能调优(2) -- 垃圾回收器和回收策略 一.内存调优的目标 新生代的垃圾回收是比较简单的,Eden区满了无法分配新对象 ...

  8. 多测师讲解python_模块间的调用_高级讲师肖sir

    案例1: 在aaa.py  文件A类中定义一个函数sadp: 在bbb.py文件中导入aaa模块,导入类 ,调用函数 案例2: aaa模块中定义一个A类, 在定义一个sadp的函数, 在bbb模块中导 ...

  9. 在容器服务中获取客户端真实源 IP

    适用范围:腾讯云容器服务(Tencent Kubernetes Engine ,TKE), 以下简称 TKE. 为什么需要获取客户端真实源 IP? 当需要能感知到服务请求来源去满足一些业务需求时,就需 ...

  10. 多层级makefile

    多层级makefile 当项目变大之后,需要多层级的makefile来编译,每个makefile的具体功能实现参考单源文件目录makefile.然后再在顶层目录写一个总的makefile来实现编译逻辑 ...