ASP.NET Core MVC 入門到精通 - 3. 使用MediatR

Jack Niu發表於2021-05-28

ASP.NET Core MVC 入門到精通 - 3. 使用MediatR

環境:

  • .NET 5
  • ASP.NET Core MVC (project)

1. MediatR

MediatR .NET中的簡單中介者模式實現,一種程式內訊息傳遞機制(無其他外部依賴)。支援以同步或非同步的形式進行請求/響應,命令,查詢,通知和事件的訊息傳遞,並通過C#泛型支援訊息的智慧排程。

Simple mediator implementation in .NET
In-process messaging with no dependencies.
Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.

另:中介者模式 - 定義一箇中介物件來封裝一系列物件之間的互動,使原有物件之間的耦合鬆散,且可以獨立地改變它們之間的互動。中介者模式又叫調停模式,它是迪米特法則的典型應用。

2. 安裝 & 配置

對於.NET5 (.net core), 使用nuget 安裝MediatR.Extensions.Microsoft.DependencyInjection.

配置:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddMediatR(typeof(Startup));
}

3. MediatR訊息型別

3.1. Notifications 通知模式

Notifications 通知模式用於生產者傳送通知,消費者(可以多個)接收到通知後,進行後續處理。
例:一個APS.NET 頁面,訪問時,傳送Notifications通知;消費者簡單記錄收到通知的時間。

3.1.1. 定義基於INotification的通知類

public class Ping : INotification { }

3.1.2. 定義消費者(關注通知的處理方法)

public class Pong1 : INotificationHandler<Ping>
{
    public Task Handle(Ping notification, CancellationToken cancellationToken)
    {
        Debug.WriteLine($"Pong1, {DateTime.Now}");
        return Task.CompletedTask;
    }
}

public class Pong2 : INotificationHandler<Ping>
{
    public Task Handle(Ping notification, CancellationToken cancellationToken)
    {
        Debug.WriteLine($"Pong2, {DateTime.Now}");
        return Task.CompletedTask;
    }
}

3.1.3. 傳送訊息通知

// 基於dotnet core的依賴注入,注入IMediator物件
private readonly IMediator _mediator;
public HomeController(ILogger<HomeController> logger, IMediator mediator)
{
    _logger = logger;
    _mediator = mediator;
}


public async Task<IActionResult> IndexAsync()
{
    // e.g. 訪問首頁時,傳送通知
    await _mediator.Publish(new Ping());
    return View();
}

3.1.4. 輸出

Pong1, 5/27/2021 4:37:18 PM
Pong2, 5/27/2021 4:37:18 PM

3.2. Request/Response 請求響應模式

request/response用於命令和查詢的場景。

3.2.1. 建立請求類:

public class RequestModel: IRequest<string>
{
}

3.2.2. 建立請求處理類

不同於通知模式,request/response只能有一個請求處理。

public class RequestHandeler : IRequestHandler<RequestModel, string>
{
    public Task<string> Handle(RequestModel request, CancellationToken cancellationToken)
    {
        return Task.FromResult($"Pong {DateTime.Now}"); // 測試,返回內容給request
    }
}

3.2.3. 頁面中傳送請求

private readonly ILogger<HomeController> _logger;
private readonly IMediator _mediator;

public HomeController(ILogger<HomeController> logger, IMediator mediator)
{
    _logger = logger;
    _mediator = mediator;
}

public async Task<IActionResult> IndexAsync()
{
    // send request, and show Response
    var response = await _mediator.Send(new RequestModel());
    Debug.WriteLine("Got response in controller: " +response);

    return View();
}

3.2.4. 輸出

Got response in controller: Pong 5/28/2021 2:04:26 PM

4. 總結

  • MediatR是一種程式內訊息傳遞機制
  • 支援以同步或非同步的形式進行請求/響應,命令,查詢(CQRS),通知和事件的訊息傳遞,並通過C#泛型支援訊息的智慧排程。
  • 其核心是訊息的解耦。
  • 應用場景: 實現CQRS、EventBus等。

5. 參考 & 程式碼

相關文章