.NET Core 使用MediatR CQRS模式

前言

CQRS(Command Query Responsibility Segregation)命令查詢職責分離模式,它主要從我們業務系統中進行分離出我們(Command 增、刪、改)和(Query 查),
同時他可以明確的區分我們每一個動作向我們的請求模型和響應模型.從而降低了我們系統的復雜性.

CQRS模式通過使用不同的接口來分離讀取數據和更新數據的操作。CQRS模式可以最大化性能,擴展性以及安全性, 還會為系統的持續演化提供更多的彈性,防止Update命令在域模型Level發生沖突。
通常情況我們使用同一數據模型進行我們數據的查詢和修改,這是一個非常簡單的CURD,在一些復雜的應用程序中,這種方法會變的難以操作,例如在讀取方面應用程序可能會存在大量的查詢,
返回具有不同的數據傳輸對象(DTO),對象映射可能會變的非常復雜,在寫入方面,模型可能實施復雜的驗證和業務邏輯.結果導致模型太多操作,整體變的相當得復雜.

如下圖所示:

MediatR他為我們解決將消息發送與消息處理進行了解耦,他同時支持異步和同步來發送和監聽消息.

MediatR

Install MediatR

PM> Install-Package MediatR
  • IMeditator
  • IRequese、IRequest
  • IRequestHandler<in TRequest, TResponse>
    public class CreateOrderRequestModel: 
        IRequest<string>
    {
        public string UserId { get; set; }
        public string CardNumber { get; set; }
    }
    public class GetOrderByIdRequestModel:IRequest<string>
    {
        public string OrderId { get; set; }
    }
 //返回值
 public interface IRequest<out TResponse> : IBaseRequest{}
 //無返回值
 public interface IRequest : IRequest<Unit>, IBaseRequest{}

創建處理程序,所有的處理程序都通過IRequestHandler接口來實現,該接口有兩個參數,第一個是請求內容,第二個是響應內容.

    public class CreateOrderCommandHandler
        : IRequestHandler<CreateOrderRequestModel, string>
    {
        public Task<string> Handle(CreateOrderRequestModel request, CancellationToken cancellationToken)
        {
            //do something...
            return Task.FromResult(request.UserId);
        }
    }

正如下代碼片段,處理程序實現了IRequestHandler帶有輸入和輸出類型定義的接口

public interface IRequestHandler<in TRequest, TResponse> where TRequest : IRequest<TResponse>
  {
    Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
  }
    public class GetOrderByIdQueryHandler :
        IRequestHandler<GetOrderByIdRequestModel, string>
    {
        public Task<string> Handle(GetOrderByIdRequestModel request, CancellationToken cancellationToken)
        {
            //do something
            return Task.FromResult(request.OrderId);
        }
    }

Install MediatR.Extensions.Microsoft.DependencyInjection

PM> MediatR.Extensions.Microsoft.DependencyInjection

在Startup.cs中注冊MediatR

services.AddMediatR(Assembly.GetExecutingAssembly());

我們只需要注入IMediator接口,通過如下代碼我們來使用他們

    [Route("api/[controller]")]
    [ApiController]
    public class OrderController : ControllerBase
    {
        private readonly IMediator _mediator;
        public OrderController(IMediator mediator)
        {
            _mediator = mediator;
        }

        [HttpPost]
        public async Task<IActionResult> Post([FromBody]CreateOrderRequestModel requestModel)
        {
            var response =await _mediator.Send(requestModel);
            return Ok(response);
        }

        [HttpGet]
        public async Task<IActionResult> Get([FromQuery]GetOrderByIdRequestModel requestModel)
        {
            var response = await _mediator.Send(requestModel);
            return Ok(response);
        }
    }

CQRS 主要包含兩大概念,一個是讀寫分離,一個是事件源。事件源不是必須項

Reference

https://github.com/hueifeng/BlogSample/tree/master/src/CQRSMediatR

posted @ 2020-04-28 22:02  HueiFeng  閱讀(...)  評論(...編輯  收藏
ag二分彩