信息发布→ 登录 注册 退出

C# 如何使用MediatR库 - 实现CQRS模式中的命令和查询

发布时间:2025-12-14

点击量:
CQRS将操作分为命令与查询,MediatR通过中介者模式实现解耦,提升系统可维护性与扩展性,适用于复杂业务场景。

c# 如何使用mediatr库 - 实现cqrs模式中的命令和查询

在现代C#应用程序开发中,CQRS(命令查询职责分离)模式被广泛用于提升系统可维护性和可扩展性。MediatR 是一个轻量级库,帮助我们在项目中轻松实现这一模式。它通过中介者模式将请求与处理逻辑解耦,使代码更清晰、更易于测试。

什么是CQRS?

CQRS 将数据操作分为两类:

  • 命令(Commands):用于修改状态的操作,比如创建、更新或删除数据。
  • 查询(Queries):仅用于读取数据,不改变任何状态。
这种分离让我们可以为写操作和读操作设计不同的模型、数据库甚至架构。

安装与配置 MediatR

在使用之前,先通过 NuGet 安装 MediatR 和依赖注入支持包:

dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection

然后在 Program.csStartup.cs 中注册服务:

builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

这样,MediatR 就会自动发现并注册所有实现 IRequestHandler 的类。

定义命令与处理程序

以“创建用户”为例,我们定义一个命令类:

public record CreateUserCommand(string Name, string Email) : IRequest;

接着编写对应的处理程序:

public class CreateUserCommandHandler : IRequestHandler
{
private readonly IUserRepository _userRepository;

public CreateUserCommandHandler(IUserRepository userRepository)
{
_userRepository = userRepository;
}

public async Task Handle(CreateUserCommand request, CancellationToken ct)
{
var user = new User(request.Name, request.Email);
await _userRepository.AddAsync(user, ct);
return user.Id;
}
}

这个处理程序接收命令,执行业务逻辑,并返回新用户的 ID。

挖错网 挖错网

一款支持文本、图片、视频纠错和AIGC检测的内容审核校对平台。

挖错网 185 查看详情 挖错网

定义查询与处理程序

对于查询,比如“根据ID获取用户信息”,我们这样定义:

public record GetUserByIdQuery(Guid Id) : IRequest;

处理程序从只读数据源中提取数据:

public class GetUserByIdQueryHandler : IRequestHandler
{
private readonly IUserReadRepository _readRepository;

public GetUserByIdQueryHandler(IUserReadRepository readRepository)
{
_readRepository = readRepository;
}

public async Task Handle(GetUserByIdQuery request, CancellationToken ct)
{
var user = await _readRepository.GetByIdAsync(request.Id, ct);
if (user == null) throw new KeyNotFoundException();
return user;
}
}

在控制器中使用 MediatR

在 ASP.NET Core 控制器中注入 ISender 接口来发送请求:

[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
private readonly ISender _sender;

public UsersController(ISender sender)
{
_sender = sender;
}

[HttpPost]
public async Task CreateUser([FromBody] CreateUserCommand command)
{
var userId = await _sender.Send(command);
return CreatedAtAction(nameof(GetUser), new { id = userId }, userId);
}

[HttpGet("{id}")]
public async Task> GetUser(Guid id)
{
var query = new GetUserByIdQuery(id);
var user = await _sender.Send(query);
return Ok(user);
}
}

ISender 是 MediatR 提供的核心接口,可用于发送任意请求类型。

优点与适用场景

使用 MediatR 实现 CQRS 带来的好处包括:

  • 职责清晰:每个类只做一件事。
  • 便于添加横切关注点:如日志、验证、事务控制等,可通过行为(Beh*iors)统一处理。
  • 可测试性强:处理程序容易单元测试。
  • 适合复杂业务系统:尤其在读写频率差异大或性能要求高的场景下表现优异。

基本上就这些。掌握 MediatR 的基本用法后,你可以逐步引入管道行为、缓存机制或事件发布等功能,进一步增强系统的灵活性和健壮性。不复杂但容易忽略的是保持请求类的简洁和单一职责,避免滥用导致过度拆分。

以上就是C# 如何使用MediatR库 - 实现CQRS模式中的命令和查询的详细内容,更多请关注其它相关文章!


相关文章: 深入理解Google Cloud Datastore查询:祖先路径与数据一致性  Pandas DataFrame 多条件优先级排序与排名  极速漫画官方主页网址 极速漫画漫画在线浏览官网链接  微博网页版首页入口 微博电脑端官网登录链接  限制HTML日期输入框的日期选择范围  快手极速版在线观看 官方网页版登录地址  《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情  在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案  2025年云电脑操作系统体验 | 无需本地硬件,随时随地使用高性能PC  深入理解Go语言中的指针类型:以*string为例  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口  Win10双系统截图高效法 截屏快捷键速记【技巧】  如何仅使用CSS更改登录界面背景图像图标的颜色  台积电1.4nm工艺A14瞄准2028:10年来性能提升80%  mcjs网页版在线存档 mcjs云存档登录入口  Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践  PHP教程:将数据库查询结果动态展示到HTML Textarea的最佳实践  黑猫投诉统一入口官网 消费者权益保护投诉平台  AI泡沫首次被“刺破”:GPU十年都无法存活!  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录  基于多条件高效更新SQL表:利用CASE表达式优化业务逻辑  Yii2模块参数配置指南:正确声明与访问模块级配置  在Blazor WebAssembly应用中动态注入客户端特定指标代码的策略  HTML空白字符处理机制:渲染、DOM与编码实践  钉钉视频会议声音异常如何处理 钉钉会议音频修复技巧  处理Kafka消费者会话超时:深入理解消息处理语义与幂等性  百度网盘网页版入口 百度网盘网页版官方登录网址  Golang如何测试channel通信行为_Golang channel通信测试与分析方法  Pandas DataFrame:高效添加条件计算列  如何在Promise链中优雅地中断后续then执行  蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版  抖音网页版平台入口 抖音网页版官网在线访问教程  CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略  解决Bootstrap卡片顶部边距导致背景图下移的问题  汽水音乐网页版使用入口_汽水音乐电脑版播放指南  J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析  在J*aScript中复现SciPy的B样条拟合与求值:关键考量  Python实现多节点属性重叠度分析教程  品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程  邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策  C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能  海棠账号登录入口_登录海棠账户同步阅读记录  J*aScript中localStorage数据的获取、清洗与格式化教程  Python多线程中正确使用sigwait处理SIGALRM信号  荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程  如何在CSS中使用浮动制作导航栏_float实现水平菜单  服务端验证_j*ascript输入检查  WooCommerce 购物车显示所有交叉销售商品教程  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!