MediatR使用


什么是MediatR

項目地址:https://github.com/jbogard/MediatR

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.

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

 

什么是中介者模式

定義:

定義一個中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合松散,且可以獨立地改變它們之間的交互。中介者模式又叫調停模式,它是迪米特法則的典型應用。

 

中介者模式是一種對象行為型模式,其主要優點如下。
降低了對象之間的耦合性,使得對象易於獨立地被復用。
將對象間的一對多關聯轉變為一對一的關聯,提高系統的靈活性,使得系統易於維護和擴展。

其主要缺點是:當同事類太多時,中介者的職責將很大,它會變得復雜而龐大,以至於系統難以維護。

 

抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象注冊與轉發同事對象信息的抽象方法。

具體中介者(ConcreteMediator)角色:實現中介者接口,定義一個 List 來管理同事對象,協調各個同事角色之間的交互關系,因此它依賴於同事角色。

抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現所有相互影響的同事類的公共功能。

具體同事類(Concrete Colleague)角色:是抽象同事類的實現者,當需要與其他同事對象交互時,由中介者對象負責后續的交互。

 

應用場景:

對於關系比較復雜的網狀結構,改成點狀結構,降低之間的耦合。

比如說:

1、每一個都認識很多朋友,大家需要記住各自朋友的聯系方式,大家可以用過微信聯系。那么微信就是一個中介者.

2、MVC框架中  控制器(C)  就是模型(M)和視圖(V)的中介者

3、房地產平台  與  買房者  賣房者

MediatR使用

MediatR作用

1、事件/消息驅,發布/訂閱型的業務邏輯。

2、解耦網狀關系

3、將命令的構造和命令的處理分開

4、CQRS

MediatR核心對象

1、IMediator

//終結者對象

 

2、IRequest  IRequest<T>

請求模型。請求響應模式使用。

3、IRequestHandler<in TRequest,out TResponse>

處理請求IRequest<T>,的處理者。

如果有多個處理IRequestHandler會用最后一個

 

4、services.AddMediatR(程序集)

掃描程序集,將相關的類注入進去

 

5、INotification

通知模型

6、INotificationHandler<in TNotification>

通知處理者

 

上面2、3用於請求響應模式(一對一)。5、6用於通知發布模型(一對多)

 

MediatR消息類型

1、Request/Response   請求響應模式

請求/響應模式,也可以叫做命令模式,主要適用於命令和查詢場景。一個請求只能被一個處理者捕獲,如果存在多個處理者,那么只有最后一個處理者會被激活。

單播消息傳輸,也就是一對一的消息傳遞,一個消息對應一個消息處理。其通過IRequest來抽象單播消息,用IRequestHandler進行消息處理。

模型定義

IRequest<string>里面string 返回參數。也支持不返回參數的GetOrderByIdRequestModel : IRequest
    /// <summary>
    /// 請求/響應接口適用於命令和查詢場景。 *都只能有一個Handler,如果注冊多個,只有最后一個會生效。
    /// </summary>
    public class GetOrderByIdRequestModel : IRequest<string>
    {
        public string OrderId { get; set; }
    }

處理者定義

IRequestHandler<GetOrderByIdRequestModel, string>   第一個參數請求參數,第二個返回參數。
    public class GetOrderByIdQueryHandler : IRequestHandler<GetOrderByIdRequestModel, string>
    {
        public Task<string> Handle(GetOrderByIdRequestModel request, CancellationToken cancellationToken)
        {
            //do something
            return Task.FromResult(request.OrderId);
        }
    }

調用

    [Route("api/[controller]")]
    [ApiController]
    public class MediatRDemonController : ControllerBase
    {
        private readonly IMediator _mediator;
        public MediatRDemonController(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);
        }
    }

 控制器里這么玩,控制器關注於身份認證、基礎設施、緩存等一些非業務邏輯處理,不在關心業務

2、Notification  發布模式

我使用它的大多數情況是Notification這種模式。因為我希望用它來做模型的領域事件。

發布模式,一般用於發布一個事件,通知訂閱者某件事情已經發生,對此事感興趣的訂閱者可以采取行動了。一般是一個發布者,多個訂閱者。(可以改造成發布到隊列)

多播消息傳輸,也就是一對多的消息傳遞,一個消息對應多個消息處理。其通過INotification來抽象多播消息,對應的消息處理類型為INotificationHandler。

模型

    /// <summary>
    /// 發布消息的模型
    /// </summary>
    public class OrderCreatedEvent : INotification
    {
        public string UserId { get; set; }

        public OrderCreatedEvent(string orderId)
        {
            this.UserId = orderId;
        }
    }

處理者

    /// <summary>
    /// 領域事件處理者
    /// 一個事件可以有多個處理者
    /// </summary>
    public class OrderCreatedDomainEventHandler : INotificationHandler<OrderCreatedEvent>
    {
        private readonly ILogger _logger;

        public OrderCreatedDomainEventHandler(ILogger<OrderCreatedDomainEventHandler> logger)
        {
            _logger = logger;
        }

        public Task Handle(OrderCreatedEvent notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Order has found by userid id: {notification.UserId} from publisher");
            return Task.CompletedTask;
        }
    }

發布消息

            //do something...
            await _mediator.Publish(new OrderCreatedEvent(request.UserId), cancellationToken);
            return request.UserId;

這種模式可以用於 發送領域事件 

 

 

代碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM