前往小程序,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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
.NET Core 使用MediatR CQRS模式
CQRS(Command Query Responsibility Segregation)命令查询职责分离模式,它主要从我们业务系统中进行分离出我们(Command 增、删、改)和(Query 查),
HueiFeng
2020/04/09
5780
.NET Core 使用MediatR CQRS模式
CQRS(Command Query Responsibility Segregation)命令查询职责分离模式,它主要从我们业务系统中进行分离出我们(Command 增、删、改)和(Query 查), 同时他可以明确的区分我们每一个动作向我们的请求模型和响应模型.从而降低了我们系统的复杂性.
HueiFeng
2020/04/10
1.7K1
.NET Core 使用MediatR CQRS模式
[译]ASP.NET Core中使用MediatR实现命令和中介者模式
在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何在ASP.NET Core中使用它来解决我们的问题并使代码简洁。因此,我们将通过下面的主题来进行相关的讲解。
依乐祝
2018/11/12
1.2K0
.NET Core开发实战(第34课:MediatR:轻松实现命令查询职责分离模式(CQRS))--学习笔记(上)
源码链接: https://github.com/witskeeper/geektime/tree/master/samples/MediatorDemo
郑子铭
2021/01/13
5880
MediatR 知多少
首先不用查字典了,词典查无此词。猜测是作者笔误将Mediator写成MediatR了。废话少说,转入正题。
圣杰
2019/05/29
1.4K0
.NET 源代码自动生成
在这篇文章中,我们将探索如何使用.NET 5中的新source generator特性,使用MediatR库和CQRS模式自动为系统生成API。
郑子铭
2024/02/27
2570
.NET 源代码自动生成
MediatR: .NET 平台上的命令查询职责分离 (CQRS) 库
MediatR 是一个轻量级的库,用于实现应用程序中的中介者模式【实现命令查询职责分离 (CQRS) 模式和面向消息的架构】。通过将请求(命令或查询)与处理程序解耦,简化了应用程序的逻辑分层和扩展。
郑子铭
2025/04/04
660
MediatR: .NET 平台上的命令查询职责分离 (CQRS) 库
在 ASP.NET Core 项目中使用 MediatR 实现中介者模式
   最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前传统的调用方式似乎差异很大,整个项目各个层之间的代码全部是通过注入 IMediator 进行调用的,F12 查看源码后可以看到该接口是属于 MediatR 这个组件的。既然要照葫芦画瓢,那我们就先来了解下如何在 ASP.NET Core 项目中使用 MediatR。
程序员宇说
2019/11/20
1K0
在 ASP.NET Core 项目中使用 MediatR 实现中介者模式
在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信
AvaloniaUI是一个强大的跨平台.NET客户端开发框架,让开发者能够针对Windows、Linux、macOS、Android和iOS等多个平台构建应用程序。在构建复杂的应用程序时,模块化和组件间的通信变得尤为重要。Prism框架提供了模块化的开发方式,支持插件的热拔插,而MediatR则是一个实现了中介者(Mediator)模式的事件订阅发布框架,非常适合用于模块之间以及模块与主程序之间的通信。
沙漠尽头的狼
2024/03/03
2550
在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信
MediatR-进程内的消息通信框架
MediatR是一款进程内的消息订阅、发布框架,提供了Send方法用于发布到单个处理程序、Publish方法发布到多个处理程序,使用起来非常方便。目前支持 .NET Framework4.5、.NET Stardand1.3、.NET Stardand2.0等版本,可跨平台使用。
拓荒者IT
2019/09/23
1.8K0
.NET Core开发实战(第34课:MediatR:轻松实现命令查询职责分离模式(CQRS))--学习笔记(下)
实际上我们在定义我的查询的时候,也可以这样定义,例如我们定义一个 MyOrderQuery,把订单的所有名称都输出出去
郑子铭
2021/01/13
3930
在ASP.NET Core中使用MediatR实现通知系统
MediatR 是一个流行的开源库,用于在.NET应用中实现中介者模式(Mediator Pattern)。它通过封装消息的发送与处理逻辑,提供了一种简洁优雅的组件间通信方式。
郑子铭
2025/04/22
980
在ASP.NET Core中使用MediatR实现通知系统
在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信
AvaloniaUI是一个强大的跨平台.NET客户端开发框架,让开发者能够针对Windows、Linux、macOS、Android和iOS等多个平台构建应用程序。在构建复杂的应用程序时,模块化和组件间的通信变得尤为重要。Prism框架提供了模块化的开发方式,支持插件的热拔插,而MediatR则是一个实现了中介者(Mediator)模式的事件订阅发布框架,非常适合用于模块之间以及模块与主程序之间的通信。
沙漠尽头的狼
2024/03/11
3320
在Avalonia项目中使用MediatR和MS.DI库实现事件驱动通信
.NET Core开发实战(第35课:MediatR:让领域事件处理更加优雅)--学习笔记
之前 mediator 使用了 Send 的方式来处理 Command,它还有一个方法 Publish,这个方法的入参是一个 INotification
郑子铭
2021/01/13
1.1K0
C#开发者的顶级工具和框架
NCrunch 是一款适用于 Visual Studio 的自动化并发测试工具。它在后台持续运行你的测试,针对你的代码提供实时反馈。
郑子铭
2025/03/03
1790
C#开发者的顶级工具和框架
DDD领域驱动设计 (C# 整理自“老张的哲学”)
设计:这里指架构分层,即应该如何分层?领域逻辑写在哪?与持久化如何交互?如何协调多对象领域逻辑?如何实现逻辑与数据存储解耦等
明志德道
2023/10/21
2.1K0
DDD领域驱动设计 (C# 整理自“老张的哲学”)
Asp.net core使用MediatR进程内发布/订阅
  最近,一个工作了一个月的同事离职了,所做的东西怼了过来。一看代码,惨不忍睹,一个方法六七百行,啥也不说了吧,实在没法儿说。介绍下业务场景吧,一个公共操作A,业务中各个地方都会做A操作,正常人正常思维应该是把A操作提取出来封装,其他地方调用,可这哥们儿偏偏不这么干,代码到处复制。仔细分析了整个业务之后,发现是一个典型的事件/消息驱动型,或者叫发布/订阅型的业务逻辑。鉴于系统是单体的,所以想到利用进程内发布/订阅的解决方案。记得很久之前,做WPF时候,用过Prism的EventAggregator(是不是暴露年龄了。。。),那玩意儿不知道现在还在不在,支不支持core,目前流行的是MediatR,跟core的集成也好,于是决定采用MediatR。
AI.NET 极客圈
2019/07/19
9750
Asp.net core使用MediatR进程内发布/订阅
net8实现MediatR小示例C#
MediatR是.net下的一个实现消息传递的库,简洁高效,它采用中介者设计模式,通过进程内消息传递机制,进行请求/响应、命令、查询、通知和事件的消息传递,可通过泛型来支持消息的智能调度,用于领域事件中。
DotNet Whisperer
2024/08/14
1260
net8实现MediatR小示例C#
Hangfire Redis 实现秒级定时任务、使用 CQRS 实现动态执行代码
本文示例项目仓库:https://github.com/whuanle/HangfireDemo
痴者工良
2025/04/19
1440
Hangfire Redis 实现秒级定时任务、使用 CQRS 实现动态执行代码
【中介者模式(Mediator)】使用Java实现中介者模式
    中介者,何为中介者,顾名思义就是我们的在处理A和B之间的关系的时候,引入一个中间人,来处理这两者之间的关系,例如生活中我们需要去租房,买房,都会有中介,来处理房东和租客之间的协调关系,这个就是中介者,落实到具体的代码中呢,就像我们的Controller可能会依赖很多的Service层面的东西,在这里的代码都会注入很多Service,导致依赖很严重,耦合较高,并且多的情况下会使得Controller的代码看起来并不是那么简洁,而中介者模式,恰恰可以解决这一痛楚,降低Controller和Service层面的依赖,通过一个接口,来实现Controller调用业务层面的操作,在中介者体系下,我们更多的是关注我们自身的业务,以及在业务之中,我们如何构建我们的业务模型,以及每个业务需要做的事件处理操作即可,换做以往的开发模式,我们需要依赖Bussiness A,B,C三个Service。在引入了Mediator中介者模式,我们的Controller只需要注入并引入IMediator的对象,即可实现调用对应的A,B,C的业务操作。接下来,我们一起看看,如何设计以及如何使用。
陈显达
2024/01/25
1990
【中介者模式(Mediator)】使用Java实现中介者模式
推荐阅读
相关推荐
.NET Core 使用MediatR CQRS模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验