跟我一起学.NetCore之MediatR好像有点火

前言

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

image-20201029084904330

正文

img

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

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

Mediator有两种消息调度方式:

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

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

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

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

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

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

大话设计模式

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

img

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

img

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

img

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

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

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

img

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

img

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

img

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

img

使用及运行效果如下:

img

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

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

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

img

使用及运行如下图:

img

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

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

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

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

img

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

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

注意:

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

通知消息及其处理

img

使用及运行如下图:

img

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

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

在WebAPI中使用MediatR,如下:

跟着图中步骤走:

img

img

开始使用吧,走起:

img

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

img

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

总结

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

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

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

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

posted @ 2020-10-29 09:02  Code综艺圈  阅读(1730)  评论(8编辑  收藏  举报