跟我一起學.NetCore之MediatR好像有點火

前言

隨著微服務的流行,而DDD(領域驅動設計)也光速般興起,CRQS(Command Query Responsibility Seperation–命令查詢職責分離)、領域事件名詞是不是經常在耳邊環繞,而MediatR組件經常用來對其技術的落地,憑這,小夥伴們說火不火?(強行引入主題,牛掰不!!!);但是今天不說微服務,也不說DDD,只說MediatR的使用,哈哈哈,開始吧;

image-20201029084904330

正文

img

二話不說就上圖,圖中大概意思就是說:MediatR是用.Net實現的簡單中介者模式,無需其他依賴就能處理進程內的消息傳遞,支援請求/響應、命令、查詢、通知和事件的同步或非同步傳遞,通過C#的泛型智慧調度。

開源地址://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綜藝圈”,識別關注跟我一起學~~~

擼文不易,莫要白瞟,三連走起~~~~