zoukankan      html  css  js  c++  java
  • 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;

    这种模式可以用于 发送领域事件 

    代码下载

  • 相关阅读:
    C语言第一天
    【PHP学习笔记】Hello,World!
    Photoshop文本位置范围
    快捷套取单色图片
    cesium加载纽约市3dtiles模型
    Python基础——0前言
    Python基础——1基础
    Python基础——2函数
    Python基础——3特性
    Python基础——4高阶函数
  • 原文地址:https://www.cnblogs.com/wudequn/p/13063254.html
Copyright © 2011-2022 走看看