前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【愚公系列】2023年01月 .NET CORE工具案例-基于MediatR的CQRS模式

【愚公系列】2023年01月 .NET CORE工具案例-基于MediatR的CQRS模式

作者头像
愚公搬代码
发布于 2023-03-16 07:54:18
发布于 2023-03-16 07:54:18
62300
代码可运行
举报
文章被收录于专栏:历史专栏历史专栏
运行总次数:0
代码可运行

文章目录


前言

1.什么是CQRS模式

CQRS 是一种与领域驱动设计 (DDD) 和事件溯源相关的架构模式,本质上是一种读写逻辑分离的机制。

CQRS可以有两种实现方式。

1、CQ两端数据库共享,只是在上层代码上分离。

这样做的好处是可以让我们的代码读写分离,更容易维护,而且不存在CQ两端的数据一致性问题, 因为是共享一个数据库的。

2、CQ两端不仅代码分离,数据库也分离,然后Q端数据由C端同步过来。

同步方式有两种:同步或异步,如果需要CQ两端的强一致性,则需要用同步;如果能接受CQ两端数据的最终一致性,则可以使用异步。

C端可以采用EventSourcing(简称ES)模式,所有C端的最新数据全部用DomainEvent表达即可。

而要查询显示用的数据,则从Q端的ReadDB(关系型数据库)查询即可。

2.中介者模式

中介者模式属于行为型模式,它包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用,从而使它们可以松散耦合。

当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用,保证这些作用可以彼此独立的变化。

具体二十三种设计模式可以查看这个专题:https://blog.csdn.net/aa2528877987/article/details/108290229

3.MediatR

MediatR是一个实现中介者模式的类库,可以帮我们轻松的实现CQRS 。

MediatR有两种功能,一种是单播消息传播(请求/响应消息),就是一对一消息传递,这个就比较适合CQRS模式;另一种是多播消息传递(发布通知),消息分发给多个应用,这种适用于消息订阅。下面简单介绍一下这两种方式的使用。

一、基于MediatR的CQRS模式

1.添加包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection

2.MediatR单播消息模式使用

2.1 创建消息对象

1、请求对象

命令对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命令对象,也就是增加或者修改传入的模型,正常情况下可以增加验证的功能
//请求需要继承IRequest,泛型里面是相应类
public class MakeCustomerRequestModel : IRequest<MakeCustomerResponseModel>
{
    public Guid CustomerId { get; set; }
    public string CustomerName { get; set; }
    public Guid BlongId { get; set; }
    public int Quantity { get; set; }
    public double Amount { get; set; }
    public string Phone { get; set; }
    public DateTime CreatTime { get; set; }
}

查询对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//查询对象,可以通过id等去查询
//请求需要继承IRequest,泛型里面是相应类
public class GetCustomerByIdRequestModel : IRequest<GetCustomerByIdResponseModel>
{
    public Guid CustomerId { get; set; }
}

2、响应对象

命令对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命令对象,返回主键ID,和是否查询成功
public class MakeCustomerResponseModel
{
    public bool IsSuccess { get; set; }
    public Guid CustomerId { get; set; }
}

查询对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//查询对象,返回查询的数据,刚好与前面相反
public class GetCustomerByIdResponseModel
{
    public Guid CustomerId { get; set; }
    public string CustomerName { get; set; }
    public Guid BlongId { get; set; }
    public int Quantity { get; set; }
    public double Amount { get; set; }
    public string Phone { get; set; }
    public DateTime CreatTime { get; set; }
}

2.2 创建消息处理器Handlers

命令对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命令处理,需要继承IRequestHandler泛型,和实现Handle方法,如下
public class MakeCustomerCommandHandler : IRequestHandler<MakeCustomerRequestModel, MakeCustomerResponseModel>
{
    public Task<MakeCustomerResponseModel> Handle(MakeCustomerRequestModel request, CancellationToken cancellationToken)
    {
        var result = new MakeCustomerResponseModel
        {
            IsSuccess = true,
            CustomerId = new Guid("4ED8843E-7718-40D1-B8E0-B813FE4E0A68")
        };
        // 业务逻辑
        return Task.FromResult(result);
    }
}

查询对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命令处理,需要继承IRequestHandler泛型,和实现Handle方法,如下
public class GetCustomerByIdQueryHandlers : IRequestHandler<GetCustomerByIdRequestModel, GetCustomerByIdResponseModel>
{
    public Task<GetCustomerByIdResponseModel> Handle(GetCustomerByIdRequestModel request, CancellationToken cancellationToken)
    {
        var orderDetails = new GetCustomerByIdResponseModel();
        // 业务逻辑
        return Task.FromResult(orderDetails);
    }
}

2.3 注入使用

1、注入

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#region 添加MediatR
builder.Services.AddMediatR(Assembly.GetExecutingAssembly());
#endregion

2、使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Route("[controller]/[action]")]
[ApiController]
public class CustomerController : ControllerBase
{
    private readonly IMediator _mediator;
    public CustomerController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public IActionResult MakeCustomer([FromBody] MakeCustomerRequestModel requestModel)
    {
        var response = _mediator.Send(requestModel).Result;
        return Ok(response);
    }

    [HttpGet]
    public IActionResult CustomerDetails(Guid id)
    {
        var response = _mediator.Send(new GetCustomerByIdRequestModel { CustomerId = id }).Result;
        return Ok(response);
    }
}

2、效果

命令对象

查询对象

3.MediatR多消息模式使用

3.1 创建消息对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class GeneralNotificationModel : INotification
{
    public string Title { get; set; }
    public string Content { get; set; }

    public GeneralNotificationModel(string title, string content)
    {
        Title = title;
        Content = content;
    }
}

3.2 创建消息处理器Handlers

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class GeneralNotificationHandler : INotificationHandler<GeneralNotificationModel>
{
    public Task Handle(GeneralNotificationModel notification, CancellationToken cancellationToken)
    {
        Console.WriteLine($"{notification.Title}:{notification.Content}");
        return Task.CompletedTask;
    }
}
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.3 注入使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023/01/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
    • 1.什么是CQRS模式
    • 2.中介者模式
    • 3.MediatR
  • 一、基于MediatR的CQRS模式
    • 1.添加包
    • 2.MediatR单播消息模式使用
      • 2.1 创建消息对象
      • 2.2 创建消息处理器Handlers
      • 2.3 注入使用
    • 3.MediatR多消息模式使用
      • 3.1 创建消息对象
      • 3.2 创建消息处理器Handlers
      • 3.3 注入使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档