[譯]ASP.NET Core中使用MediatR實現命令和中介者模式

来源:https://www.cnblogs.com/yilezhu/archive/2018/10/28/9866068.html
-Advertisement-
Play Games

作者:依樂祝 原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html 在本文中,我將解釋命令模式,以及如何利用基於命令模式的第三方庫來實現它們,以及如何在ASP.NET Core中使用它來解決我們的問題並使代碼簡潔。因此,我們將通過下麵的主題來進行相關 ...


作者:依樂祝
原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html

在本文中,我將解釋命令模式,以及如何利用基於命令模式的第三方庫來實現它們,以及如何在ASP.NET Core中使用它來解決我們的問題並使代碼簡潔。因此,我們將通過下麵的主題來進行相關的講解。

  • 什麼是命令模式?
  • 命令模式的簡單實例以及中介者模式的簡單描述
  • MVC中的瘦控制器是什麼?我們是如何實現使控制器變瘦的?
  • 我們如何在我們的.NET Core應用程式中使用MediatR
  • 使用命令和事件的實例

命令模式及其簡單實例

從根本上講,命令模式是一種數據驅動的設計模式,屬於行為模式的範疇。命令是我們可以執行的某種操作或行為,它可以是活動的一部分。一個活動可以有一個或多個命令和實現。

我們可以這樣來說,請求以命令的形式包裹在對象中,並傳給調用對象。調用者(代理)對象查找可以處理該命令的合適的對象,並把該命令傳給相應的對象,該對象執行命令 。

一個簡單的例子是多種類型的消息。Message類包含SendEmail()和SendSms()等屬性和方法。使用兩種類型的命令,並且需要一個介面,它應該由實現了EmailMessageCommand和SMSMessageCommand的類類繼承。還使用代理類來調用特定類型的消息類來處理操作。

Mediatr

Main class

class Program  
    {  
        static void Main(string[] args)  
        {  
            Message message = new Message();  
            message.CustomMessage = "Welcome by Email";  
            EmailMessageCommand emailMessageCommand = new EmailMessageCommand(message);  
  
            Message message2 = new Message();  
            message2.CustomMessage = "Welcome by SMS";  
            SmsMessageCommand smsMessageCommand = new SmsMessageCommand(message2);  
  
            Broker broker = new Broker();  
            broker.SendMessage(emailMessageCommand);  
            broker.SendMessage(smsMessageCommand);  
            Console.ReadKey();  
  
        }  
    }  

消息類

public class Message  
    {  
        public string CustomMessage { get; set; }  
  
        public void EmailMessage()  
        {  
            Console.WriteLine($"{CustomMessage} : Email Message sent");  
        }  
  
        public void SmsMessage()  
        {  
            Console.WriteLine($"{CustomMessage} : Sms Message sent");  
        }  
    }  

介面和代理類

public interface IMessageCommand  
{  
    void DoAction();         
}  
  
public class Broker  
{  
    public void SendMessage(IMessageCommand command)  
    {  
        command.DoAction();  
    }  
}  

命令

public class EmailMessageCommand : IMessageCommand  
    {  
        private Message oMessage;  
  
        public EmailMessageCommand(Message oMessage)  
        {  
            this.oMessage = oMessage;  
        }  
  
        public void DoAction()  
        {  
            oMessage.EmailMessage();  
        }  
    }  
  
    public class SmsMessageCommand : IMessageCommand  
    {  
        private Message oMessage;  
  
        public SmsMessageCommand(Message oMessage)  
        {  
            this.oMessage = oMessage;  
        }  
        public void DoAction()  
        {  
             
            oMessage.SmsMessage();  
        }  
    }  

輸出

Command, Mediator Pattern In ASP.NET Core Using Mediatr

什麼是瘦控制器,我們為什麼需要它?什麼是MediatR?

當我們開始使用MVC框架進行開發時,邏輯是用控制器的動作方法編寫的;就像我們有一個簡單的電子商務應用程式,其中用戶應該會下訂單。我們有一個控制器,OrderController,用來管理訂單。當用戶下訂單時,我們應該在資料庫中保存記錄。
在此之前,我們有一個簡化的代碼。然而,經過一段時間後,我們意識到還有一個確認電子郵件的業務需求。現在,第二步是發送確認電子郵件給客戶。後來,我們意識到,在這個步驟之後,我們還需要執行另一個操作,即,記錄信息等。最後,我們還需要將用戶的信息保存到CRM中。關鍵是它會增長控制器的大小。現在,我們可以稱之為“臃腫控制器”。
基於命令的體繫結構允許我們發送命令來執行某些操作,並且我們有單獨的命令處理程式,使關註點分離和提高單一職責。為了實現這個架構,我們可以使用第三方庫,比如MediatR(Mediator.),它為我們做了很多基礎工作。中介模式定義了一個對象,該對象封裝了一組對象是如何交互的。

中介模式的優勢及MediatR如何幫助我們實現中介模式

  • 中介模式定義了一個對象,該對象封裝了一組對象是如何交互的(如維基百科定義的)。
  • 它通過保持對象彼此明確地相互引用來促進鬆散耦合。
  • 它通過允許通信被卸載到一個只處理這類的類來促進單一責任原則。

MediatR庫如何幫助我們

MediatR允許我們通過讓控制器Action向處理程式發送請求消息來將控制器與業務邏輯解耦。MediatR庫支持兩種類型的操作。

  • 命令(預期輸出結果)
  • 事件(請求者不關心接下來發生了什麼,不期待結果)

我們已經介紹了命令模式,因此是時候定義一些命令並使用MediatR發出命令了。

在ASP.NET Core中安裝

我們需要從NuGet安裝MediatR和MediatR.Extensions.Microsoft.DependencyInjection包。

使用Mediatr在ASP.NET核心中的命ä"¤ï¼Œä"‹ä½“模式

使用Mediatr在ASP.NET核心中的命ä"¤ï¼Œä"‹ä½“模式

當這兩個軟體包安裝完畢後,我們需要添加services.AddMediatR(); 到startup.cs文件。看起來像這樣。

使用Mediatr在ASP.NET核心中的命ä"¤ï¼Œä"‹ä½“模式

現在,我們可以使用.NET Core 項目中的MediatR了。

實例

第一個示例演示了使用MediatR使用請求/響應類型的操作。它期望對請求做出一些反應。
第二個示例將向您展示一個事件,其中多個處理程式執行它們的工作,調用者並不關心接下來會發生什麼,也不期望任何結果/響應。

第一個例子

在這種場景下,我們希望註冊用戶並期望對請求做出一些響應。如果響應返回true,我們可以像登錄用戶一樣進行進一步的操作。
首先,我們需要創建一個繼承自IRequest的類。

public class NewUser: IRequest<bool>  
  {  
      public string Username { get; set; }  
      public string Password { get; set; }          
  }  

IRequest是指請求的響應是布爾響應。
現在,需要一個處理程式來處理這種類型的請求。

public class NewUserHandler : IRequestHandler<NewUser, bool>  
  {         
      public Task<bool> Handle(NewUser request, CancellationToken cancellationToken)  
      {  
          // save to database  
          return Task.FromResult(true);  
      }  
  }  

現在我們有了命令和它的處理程式,我們可以調用MediatR在我們的控制器中做一些操作。
這些是Home控制器的動作方法。

public class HomeController : Controller  
    {  
        private readonly IMediator _mediator;  
  
        public HomeController(IMediator mediator)  
        {  
            _mediator = mediator;  
        }  
       [HttpGet]  
        public ActionResult Register()  
        {  
            return View();  
        }  
  
        [HttpPost]  
        public ActionResult Register(NewUser user)  
        {  
            bool result = _mediator.Send(user).Result;  
  
            if (result)  
                return RedirectToAction("Login");  
              
            return View();  
        }  
      }  

第一個例子的結論

註冊操作方法使用了[HttpPost]屬性進行修飾,並接受新的用戶註冊請求。然後,它請求MediatR 進行處理。它期望來自請求的結果/響應,如果結果是真的,則將用戶重定向到登錄頁面。
這裡,我們有簡潔的代碼,大部分的工作是在控制器外部完成的。這實現了對不同操作的處理的關註點分離(SoC)和單一責任的分離。
在第二個示例中,我們將演示使用多個處理程式對命令執行不同操作的場景。

第二個實例

在這種情況下,我們使NewUser 繼承了INotification

public class NewUser : INotification  
{  
    public string Username { get; set; }  
    public string Password { get; set; }  
}  

現在,有三個處理程式逐個執行,以完成他們的工作。這些都是從INotificationHandler繼承下來的。

public class NewUserHandler : INotificationHandler<NewUser>  
    {  
        public Task Handle(NewUser notification, CancellationToken cancellationToken)  
        {  
            //Save to log  
            Debug.WriteLine(" ****  Save user in database  *****");  
            return Task.FromResult(true);  
        }  
    }  

第二個處理程式在下麵的代碼中定義。

public class EmailHandler : INotificationHandler<NewUser>  
    {  
        public Task Handle(NewUser notification, CancellationToken cancellationToken)  
        {  
            //Send email  
            Debug.WriteLine(" ****  Email sent to user  *****");  
            return Task.FromResult(true);  
        }  
    }  

這是第三個處理程式的代碼

public class LogHandler : INotificationHandler<NewUser>  
    {  
        public Task Handle(NewUser notification, CancellationToken cancellationToken)  
        {  
            //Save to log  
            Debug.WriteLine(" ****  User save to log  *****");  
            return Task.FromResult(true);  
        }  
    }  

然後,我們控制器中的代碼像下麵這樣

public class AccountsController : Controller  
    {  
        private readonly IMediator _mediator;  
        public AccountsController(IMediator mediator)  
        {  
            _mediator = mediator;  
        }  
        [HttpGet]  
        public ActionResult Login()  
        {  
            return View();  
        }  
        [HttpGet]  
        public ActionResult Register()  
        {  
            return View();  
        }  
  
        [HttpPost]  
        public ActionResult Register(NewUser user)  
        {  
            _mediator.Publish(user);  
            return RedirectToAction("Login");  
        }  
    }  

第二個例子的結論

此應用程式的輸出如下:
當用戶註冊後,三個處理程式逐個執行——分別是NewUserHandler、EmailHandler和LogHandler,並執行它們的操作。

這裡,我們使用了Publish 方法,而不是Send 函數。發佈將調用訂閱了NewUser 類的所有處理程式。這隻是一個示例,我們可以根據命令進行思考,然後按照我們在命令模式中討論的方式相應地執行一些操作。

Mediatr是如何提供幫助的?

它可以用來隱藏實現的細節,用來使控制器代碼更加乾凈和可維護,可以重用多個處理程式,並且每個處理程式都有自己的責任,因此易於管理和維護。

在我的下一篇文章中,我將嘗試解釋CQRS架構模式及其優點以及如何使用MediatR來實現CQRS。

原文地址:https://www.c-sharpcorner.com/article/command-mediator-pattern-in-asp-net-core-using-mediatr2/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們都知道程式員花費大量的時間在編寫、閱讀和編輯代碼上,因此一定要使用高效的文本編輯器才能夠提高並很好的完成工作的效率和保證工作的質量。 什麼是高效的文本編輯器呢?除了自己用的得心應手外,小U認為還應該包含以下幾個特點: ·突出代碼的結構,讓你在編寫代碼時就能夠發現常見的bug; 本人微信:mmp9 ...
  • 題目描述 已知:Sn​=1+1/2+1/3+…+1/n。顯然對於任意一個整數K,當n足夠大的時候,Sn​大於K。 現給出一個整數K(1≤K≤15),要求計算出一個最小的n;使得Sn​>K。 輸入輸出格式 輸入格式: 一個正整數K 輸出格式: 一個正整數N 輸入樣例:1 輸出樣例:2 答案代碼: #i ...
  • 一、前言 之前ZYNQ與PC之間的網路連接依賴於外接硬體協議棧晶元,雖然C驅動非常簡單,但網路帶寬受限。現採用LWIP+PS端MAC控制器+PHY晶元的通用架構。關於LWIP庫,已經有很多現成的資料和書籍。其有兩套API,一個是SOCKET,另一個是本例中要用到的RAW。RAW API理解起來較為復 ...
  • 在這裡我要實現的是Spring的IOC和AOP的核心,而且有關IOC的實現,註解+XML能混合使用! 參考資料: IOC:控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低電腦代碼之間的耦合度。其中最常見的方式叫做依賴註入(Depend ...
  • dfs
    sdfsf ...
  • 前言 這篇文章是WPF框架系列的最後一篇,在這裡我想闡述一下我對框架設計的理解。 我對框架設計的理解是這樣的: 框架設計不應該局限於任何一種設計模式,我們在設計框架時,應該將設計模式揉碎,再重組;這樣設計出來的框架才具有一戰之力。 框架設計應該根據項目團隊成員水平量身定製。 我上一篇文章《我們都知道 ...
  • Console.WriteLine("100-1000的水仙花數有"); for (int i = 100; i < 1000; i++) { int a = i / 100 % 10;//百位 int b = i / 10 % 10;//十位 int c = i % 10;//個位 if (a * ...
  • VC2010和VC2017的標準庫中,string(或wstring)的數據結構和操作有所不同,所以在將這兩種數據作為參數在兩個系統產生的函數中傳遞時會出現亂碼(string和wstring在2017下必須是引用傳遞) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...