1. 程式人生 > >NET Core中使用MediatR實現命令和中介者模式

NET Core中使用MediatR實現命令和中介者模式

tab 添加 www. 執行 重定向 什麽 接下來 ont 修飾

NET Core中使用MediatR實現命令和中介者模式

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
{
public string Username { get; set; }
public string Password { get; set; }
}
IRequest是指請求的響應是布爾響應。
現在,需要一個處理程序來處理這種類型的請求。

public class NewUserHandler : IRequestHandler<NewUser, bool>
{
public Task 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
{
public Task Handle(NewUser notification, CancellationToken cancellationToken)
{
//Save to log
Debug.WriteLine(" **** Save user in database *****");
return Task.FromResult(true);
}
}
第二個處理程序在下面的代碼中定義。

public class EmailHandler : INotificationHandler
{
public Task Handle(NewUser notification, CancellationToken cancellationToken)
{
//Send email
Debug.WriteLine(" **** Email sent to user *****");
return Task.FromResult(true);
}
}
這是第三個處理程序的代碼

public class LogHandler : INotificationHandler
{
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/

NET Core中使用MediatR實現命令和中介者模式