CQRS(Command Query Responsibility Segregation)命令查詢職責分離模式,它主要從咱們業務系統中進行分離出咱們(Command 增、刪、改)和(Query 查),
同時他能夠明確的區分咱們每個動做向咱們的請求模型和響應模型.從而下降了咱們系統的複雜性.git
CQRS模式經過使用不一樣的接口來分離讀取數據和更新數據的操做。CQRS模式能夠最大化性能,擴展性以及安全性, 還會爲系統的持續演化提供更多的彈性,防止Update命令在域模型Level發生衝突。
一般狀況咱們使用同一數據模型進行咱們數據的查詢和修改,這是一個很是簡單的CURD,在一些複雜的應用程序中,這種方法會變的難以操做,例如在讀取方面應用程序可能會存在大量的查詢,
返回具備不一樣的數據傳輸對象(DTO),對象映射可能會變的很是複雜,在寫入方面,模型可能實施複雜的驗證和業務邏輯.結果致使模型太多操做,總體變的至關得複雜.github
以下圖所示:api
MediatR他爲咱們解決將消息發送與消息處理進行了解耦,他同時支持異步和同步來發送和監聽消息.安全
Install MediatR異步
PM> Install-Package MediatR
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接口來實現,該接口有兩個參數,第一個是請求內容,第二個是響應內容.async
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.DependencyInjectioncode
PM> MediatR.Extensions.Microsoft.DependencyInjection
在Startup.cs中註冊MediatR對象
services.AddMediatR(Assembly.GetExecutingAssembly());
咱們只須要注入IMediator接口,經過以下代碼咱們來使用他們blog
[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 主要包含兩大概念,一個是讀寫分離,一個是事件源。事件源不是必須項
https://github.com/hueifeng/BlogSample/tree/master/src/CQRSMediatR