.Net Core 常用类库 MediatR CQRS

1.MediatR  可参考 https://www.jianshu.com/p/583bcba352ec

先了解 CQRS: 命令(增 删  改)查询责任隔离,简单理解为读写分离 哈,一般情况下输入和输出模型是不一致的 

看两张图了解一下:

 

 

 这种情况最好不要共享模型 

CQRS也就是这种思想,一个操作对应两个模型 

对于大多数系统 查询的频率是远高于命令的

在DDD项目中,CQRS是必不可少的就是把数据查询和命令的模式分离开

如图项目截图:

 CQRS有利于区分不同的模型,负责的领域模型和查询模型分开

也有利于事件朔源

MediatR 实现中介者模式的类库 (用来减低多个对象和类之间的通信复杂度)

中介者模式:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。

类似机场的空管中心和飞机的调度

 

处理程序:负责处理查询或者命令消息

有两种分派消息的方式:

   -请求/响应消息,适用于CQRS,消息分发给单个处理程序

  - 通知消息,发布/订阅模式 ,消费分发给多个处理程序

请求/响应消息,适用于CQRS,消息分发给单个处理程序的例子:

包:MediatR  MediatR.Extensions.Microsoft.DependencyInjection

           

 

 

 

   三步:1.创建消息对象

复制代码
namespace CQRSWithMediatorSample.RequestModels.CommandRequestModels
{
    /// <summary>
    /// 消息对象 请求模式,实现了一个 响应模式的接口
    /// </summary>
    public class MakeOrderRequestModel : IRequest<MakeOrderResponseModel>
    {
        public Guid OrderId { get; set; }
        public string OrderName { get; set; }
        public DateTime DateOrder { get; set; }
        public Guid ProductId { get; set; }
        public int Quantity { get; set; }
        public double Amount { get; set; }
        public Guid OrderPersonId { get; set; }
    }
}
复制代码
复制代码
namespace CQRSWithMediatorSample.RequestModels.QueryRequestModels
{
    /// <summary>
    /// 查询的消息对象,实现了一个 响应模式的接口
    /// </summary>
    public class GetOrderByIdRequestModel : IRequest<GetOrderByIdResponseModel>
    {
        public Guid OrderId { get; set; }
    }
}
复制代码

2.创建消息处理器:

复制代码
namespace CQRSWithMediatorSample.Handlers.CommandHandlers
{
    /// <summary>
    /// 命令处理器 实现了 IRequestHandler 注意两个泛型
    /// </summary>
    public class MakeOrderCommandHandler : IRequestHandler<MakeOrderRequestModel,MakeOrderResponseModel>
    {

        /// <summary>
        /// 实现了Handle方法,可以支持异步
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<MakeOrderResponseModel> Handle(MakeOrderRequestModel request, CancellationToken cancellationToken)
        {
            var result = new MakeOrderResponseModel
            {
                IsSuccess = true,
                OrderId = new Guid("53d26807-ad70-4449-8479-024c54eb2020")
            };

            // 业务逻辑

            return Task.FromResult(result);
        }
    }
}
复制代码
复制代码
namespace CQRSWithMediatorSample.Handlers.QueryHandlers
{
    /// <summary>
    /// 查询处理器
    /// </summary>
    public class GetOrderByIdQueryHandler : IRequestHandler<GetOrderByIdRequestModel, GetOrderByIdResponseModel>
    {

        public Task<GetOrderByIdResponseModel> Handle(GetOrderByIdRequestModel request, CancellationToken cancellationToken)
        {
            var orderDetails = new GetOrderByIdResponseModel();
            // 业务逻辑
            return Task.FromResult(orderDetails);
        }
    }
}
复制代码

3.发送消息

复制代码
namespace CQRSWithMediatorSample.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class OrderController : ControllerBase
    {
        /// <summary>
        /// 发送消息通过依赖注入
        /// </summary>
        private readonly IMediator _mediator;

        public OrderController(IMediator mediator)
        {
            _mediator = mediator;
        }

        [HttpPost]
        public IActionResult MakeOrder([FromBody] MakeOrderRequestModel requestModel)
        {
            //发送消息
            var response = _mediator.Send(requestModel).Result;
            return Ok(response);
        }

        [HttpGet]
        public IActionResult OrderDetails(Guid id)
        {
            //发送消息
            var response = _mediator.Send(new GetOrderByIdRequestModel {OrderId = id}).Result;
            return Ok(response);
        }
    }
}
复制代码

 最后要在Start中 注册MedaitR服务

复制代码
public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            //注册MedaitR服务参数为一个必须含有相关处理器的程序集
            services.AddMediatR(Assembly.GetExecutingAssembly());
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
复制代码

 总结:减少使用过多的依赖注入,只需要定义好消息模型就可以了 哈

通知消息,发布/订阅模式 ,消费分发给多个处理程序例子:

三步:

1.实现通知对象

复制代码
namespace MediatorWithNotificationSample.NotificationModels
{
    /// <summary>
    /// 实现通知对象
    /// </summary>
    public class GeneralNotificationModel : INotification
    {
        public string Title { get; set; }
        public string Content { get; set; }

        public GeneralNotificationModel(string title, string content)
        {
            Title = title;
            Content = content;
        }
    }
}
复制代码

2.创建通知处理器 这里创建了 两个

复制代码
namespace MediatorWithNotificationSample.Handlers.NotificationHandlers
{
    /// <summary>
    /// 通知处理器,泛型是需要处理的模型
    /// </summary>
    public class GeneralNotificationHandler : INotificationHandler<GeneralNotificationModel>
    {
        public Task Handle(GeneralNotificationModel notification, CancellationToken cancellationToken)
        {
            Console.WriteLine($"{notification.Title}:{notification.Content}");
            return Task.CompletedTask;
        }
    }
}
复制代码
复制代码
namespace MediatorWithNotificationSample.Handlers.NotificationHandlers
{
    /// <summary>
    ///  通知处理器,泛型是需要处理的模型
    /// </summary>
    public class LogHandler : INotificationHandler<GeneralNotificationModel>
    {
        private readonly ILogger<LogHandler> _logger;

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

        public Task Handle(GeneralNotificationModel notification, CancellationToken cancellationToken)
        {
            _logger.LogInformation($"{notification.Title}:{notification.Content}");
            return Task.CompletedTask;
        }
    }
}
复制代码

3.发送(通知)消息 例如DDD中的领域之间的通信 (领域通信)

复制代码
namespace MediatorWithNotificationSample.Handlers.CommandHandlers
{
    public class MakeOrderCommandHandler : IRequestHandler<MakeOrderRequestModel,MakeOrderResponseModel>
    {
        private readonly IMediator _mediator;

        public MakeOrderCommandHandler(IMediator mediator)
        {
            _mediator = mediator;
        }

        public Task<MakeOrderResponseModel> Handle(MakeOrderRequestModel request, CancellationToken cancellationToken)
        {
            var result = new MakeOrderResponseModel
            {
                IsSuccess = true,
                OrderId = new Guid("53d26807-ad70-4449-8479-024c54eb2020")
            };
            //发布消息
            _mediator.Publish(new GeneralNotificationModel("已下单", result.OrderId.ToString()), cancellationToken);

            return Task.FromResult(result);
        }
    }
}
复制代码

 

posted @   根仔  阅读(673)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示