中介者设计模式与MediatR

概要

1. 中介者模式
2. MediatR

中介者模式

什么是中介者模式

中介者模式即对象通过中介者交互而非直接进行。

中介者模式让原本类之间的依赖转移到为了中介者与类间,由此在很大程度上降低程序的耦合度,并大大简化类之间的通信。

中介者类似消息的处理中心,对象向中介者发送请求,中介者分发请求至对应目标。获得目标响应后返回至发起者。

为什么要使用中介者模式

1.程序随功能增多产生复杂的依赖关系,某一方法可能分别依赖不同层级的对象

2.类间的通信、调用流程由于多对多的关系变得繁琐

3.由于类间的相互引用而产生高耦合的代码

中介者模式如何解决问题

以WebApi工程为例,最上层的controller只依赖于中介者对象,中介者对象依赖于业务逻辑。

1.根据中介者的位置进行分割,此时中介者作为controller和业务逻辑之间的分隔起到解耦的作用。上层的controller与下层的业务逻辑始终只与中介者交互,两部分即消息的发送和接收者可以独立的修改,controller的替换或者更新的工作量也就大大减少。

2.在我们对所有的逻辑都尽可能地进行分割的前提下,通过于中介者交互获得某一逻辑片段的响应,组合后完成复杂逻辑。

原本的复杂逻辑可能依赖于多个下层方法,分隔后复杂逻辑只依赖于中介者。

原本依赖的多个下层方法现在分布在各个逻辑片段中,由此,下层方法的改动只对这些逻辑片段产生影响。

3.以复杂逻辑为例,中介消息的接收者只表明调用各个逻辑的顺序以及组合方式。逻辑片段及其依赖的下层方法的修改只要保证自身的返回内容正确,符合请求目的,就不会对其他的所依赖的对象产生影响

中介者模式存在的问题

有的朋友可能说了,我只要写一个巨大的类,把所有的业务逻辑的方法都放进去,让所有的controller都依赖于这个类,那我是不是也实现了中介者模式?

从结构上来说,这个类也是起到了中介者的角色。但是随着业务增加,中介者对象变得臃肿庞大。

其次这个巨大的类相当于对所有的下层方法产生了依赖,每次使用这个类时,都需要将所有的依赖注入,与依赖注入的目的相违背。

而MediatR在一定程度上解决了这个问题。MediatR提供了简洁且功能丰富的中介者对象
并将依赖向外部分散,依赖注入到细致的下层逻辑中

MediatR

什么是MediatR

.NET中的中介者模式实现,一种进程内消息传递框架,提供了中介者对象
MediatR支持以同步或异步的形式进行请求/响应,支持消息的单播/多播

WebApp中应用MediatR

MediatR在WebApi中的位置处于Application与Presentation/Controller之间,请求进入后发送通过MediatR消息,消息处理方法中调用Application

由此,MediatR作为Presentation/Controller和Application的中间连接件,前者只对MediatR产生依赖,而MediatR只对后者产生依赖

把MediatR inject 到 presentation和把service inject到presentation有什么区别和各自的利弊?

首先就是两个依赖关系不一样 理想状态下是presentation只对mediator中介者产生依赖 如果是service直接注入的话 通常情况下不可能只注入一个 presentation就会产生多个引用 增加两者之间的耦合

MediatR把presentation和service分隔开来 这样两个部分的修改变更就更简单

优势是MediatR能分散所有的依赖 降低耦合
弊端是中介者成了程序不能分割的一部分 所以他必须要可靠高效

直接调用与通过MediatR调用比较
功能 通过MediaR调用
调用方法的前后进行额外处理 通过IPipelineBehavior实现类似中间件的功能,通过IRequestPreProcess,IRequestpostProcess来实现为某一方法调用前后附上额外运行的代码
调用方法触发运行一个或多个代码段 通过INotification实现消息的单播/多播
捕捉异常 通过IRequestExceptionHandler,IRequestExceptionAction处理执行方法中产生的异常,运行额外代码
Notification消息的发布策略

通过重写MediatR.PublishCore方法来实现自定义的发布策略
默认发布策略是遍历所有消息的handlers, 逐一执行