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

Code綜藝圈發表於2020-10-29

前言

隨著微服務的流行,而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綜藝圈",識別關注跟我一起學~~~

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

相關文章