MediatR 試用紀錄
一個很受歡迎的套件。常用於實作CQRS pattern。試用看看。
引言
最近經常看到 CQRS pattern,然後使用MediatR實作。
本人對CQRS
沒興趣,有興趣的只有MediatR
的訊息傳遞模組。
MediatR應用類型現在有三種
IRequest
(including generic variants andUnit
) 就是 Request/Reponse模式。INotification 通知模式,也是本人最有興趣的。
IStreamRequest
未試用。
開發前置準備
開發環境
IDE: Visual Studio 2022
platform: .NET6
project type: Blaozr WASM hosted app
安裝套件
PM> Install-Package MediatR
PM> Install-Package MediatR.Extensions.Microsoft.DependencyInjection
註冊
// Add services to the container.
services.AddMediatR(typeof(Program));
關鍵指令紀錄
IRequest
模式
IRequest
模式定義 Request/Response 與其 Handler:
using MediatR;
namespace YourProject.MediatRHandler;
/// 此例是CQRS pattern 中的 Query 簡要範例,Command 也是差不多的用法。
/// IRequest Handler
public class QueryUserHandler : IRequestHandler<QueryUserRequest, QueryUserResponse>
{
public Task<QueryUserResponse> Handle(QueryUserRequest request, CancellationToken cancellationToken)
{
return Task.FromResult(new QueryUserResponse {
DisplayName = $"我是{request.Id}的名字"
});
}
}
/// Response
public class QueryUserResponse
{
public string DisplayName { get; set; } = string.Empty;
}
/// Request
public class QueryUserRequest : IRequest<QueryUserResponse>
{
public int Id { get; set; }
}
應用:
[Route("api/[controller]")]
[ApiController]
public class MyDataController : ControllerBase
{
readonly MediatR.IMediator _mediator;
public MyDataController(MediatR.IMediator mediator)
{
_mediator = mediator;
}
[HttpPost("[action]")]
public QueryUserResponse QryUserData()
{
var response = _mediator.Send(new QueryUserRequest { Id = 987 }).Result;
return response;
}
}
INotification
模式
INotification
模式定義 Notification:
using MediatR;
namespace YourProject.MediatRHandler;
/// 定義 INotification
public class Ping : INotification {
public string Msg { get; set; } = string.Empty;
}
定義接收 Notification 的 handler:
using MediatR;
namespace YourProject.MediatRHandler;
/// INotification Handler - 接收Notification
/// ※接收方原則上在那都可以,此為到方便測試所以寫在附近。
public class Pong1 : INotificationHandler<Ping>
{
public Task Handle(Ping notification, CancellationToken cancellationToken)
{
Debug.WriteLine($"Pong1:{notification.Msg}:@{DateTime.Now}");
return Task.CompletedTask;
}
}
/// INotification Handler - 另一個接收Notification
/// ※接收方原則上在那都可以,此為到方便測試所以寫在附近。
public class Pong2 : INotificationHandler<Ping>
{
public Task Handle(Ping notification, CancellationToken cancellationToken)
{
Debug.WriteLine($"Pong2:{notification.Msg}:@{DateTime.Now}");
return Task.CompletedTask;
}
}
應用:
[Route("api/[controller]")]
[ApiController]
public class MyDataController : ControllerBase
{
readonly MediatR.IMediator _mediator;
public MyDataController(MediatR.IMediator mediator)
{
_mediator = mediator;
}
[HttpPost("[action]")]
public QueryUserResponse QryUserData()
{
// 比如:執行商業邏輯
var response = _mediator.Send(new QueryUserRequest { Id = 987 }).Result;
// 比如:當完成商業邏輯後送出通知訊息。
// 送出 Notification
_mediator.Publish(new MediatRHandler.Ping { Msg = "XY23" });
return response;
}
}
試用心得
CQRS pattern
with MediatR
的應用應該比較適合實作微服務。比如:非同步的、資料後送類的、通知類的、可射後不理的,比如像是 Action Log 或資料歸檔 Data Archive 或 Authz 這類domain範圍不大的、數據相依性不多甚至沒有的等等簡單就能封裝的(closure)資料包的應用。
其他說明:可以實作Notification、CQRS Pattern。很受觀迎的CQRS實作技術。
試用心得優點:適合用於後端,如與WebApi搭配使用。
試用心得缺點:可惜其Notification Publisn 在 WebAssembly 前端無效。
Last updated