0

0

C#如何实现CQRS模式 MediatR库入门与实践指南

幻夢星雲

幻夢星雲

发布时间:2025-12-19 12:22:33

|

191人浏览过

|

来源于php中文网

原创

MediatR是C#中实现CQRS最轻量主流的选择,以“请求-响应”模型分离命令与查询,提升可测性与扩展性;它作为进程内消息总线自动路由请求到唯一处理器,不强制接口,需自行组合事务、缓存等能力。

c#如何实现cqrs模式 mediatr库入门与实践指南

在C#中实现CQRS模式,MediatR是最轻量、最主流的选择之一。它不强制你写一堆接口和基类,而是用“请求-响应”模型自然地把命令(Command)和查询(Query)分开,让业务逻辑更清晰、可测试性更强、扩展更灵活。

一、理解CQRS与MediatR的核心分工

CQRS(Command Query Responsibility Segregation)本质是把“改数据”和“读数据”彻底拆开:命令负责修改状态(如创建订单、更新用户),查询只负责返回数据(如获取用户列表、查订单详情)。MediatR不是CQRS框架,而是一个进程内消息总线——它帮你把请求(IRequest)发给唯一对应的处理器(IRequestHandler),自动完成路由、依赖注入和生命周期管理。

关键点:

  • 一个请求类型(比如CreateUserCommand)只能有一个处理器;
  • 查询和命令都用IRequest统一建模,是否修改数据库由你决定;
  • MediatR本身不处理事务、缓存或事件发布,这些需你自行组合(比如配合Entity Framework Core + IUnitOfWork + IDomainEvent)。

二、快速上手:三步接入MediatR

以.NET 6+项目为例(控制台或Web API均可):

1. 安装包

通过NuGet安装:
MediatR(核心库)
MediatR.Extensions.Microsoft.DependencyInjection(集成ASP.NET Core DI)

2. 注册服务

Program.cs中添加:

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

这会自动扫描当前程序集下所有实现了IRequestHandlerINotificationHandler的类并注册。

3. 写一个查询示例

定义查询请求:

Question AI
Question AI

一款基于大模型的免费的AI问答助手、总结器、AI搜索引擎

下载
public record GetUserByIdQuery(int Id) : IRequest;

定义处理器:

public class GetUserByIdQueryHandler : IRequestHandler
{
    private readonly IUserRepository _repo;
    public GetUserByIdQueryHandler(IUserRepository repo) => _repo = repo;

    public async Task Handle(GetUserByIdQuery request, CancellationToken ct)
        => await _repo.GetByIdAsync(request.Id, ct);
}

在Controller中使用:

[HttpGet("{id}")]
public async Task> Get(int id)
    => Ok(await _mediator.Send(new GetUserByIdQuery(id)));

三、命令与验证的最佳实践

命令通常伴随业务规则校验。推荐组合FluentValidation:

  • 为每个命令定义对应Validator(如CreateUserCommandValidator : AbstractValidator);
  • 安装MediatR.Extensions.FluentValidation.AspNetCore,自动启用验证管道行为;
  • 验证失败时直接返回ValidationException,可在全局Filter中统一转为400响应。

命令执行后若需通知其他模块(如发邮件、更新搜索索引),不要在Handler里硬编码调用。改用INotification + INotificationHandler解耦:

await _mediator.Publish(new UserCreatedNotification(user), ct);

多个Handler可同时监听该事件,互不影响。

四、常见陷阱与应对建议

别把MediatR当Service Locator用:避免在Handler里通过IMediator再发另一个请求——这容易导致隐式调用链、事务边界混乱、难以调试。需要组合逻辑?提取成领域服务,由Handler协调。

事务控制要明确:MediatR不管理事务。命令Handler中若涉及EF Core操作,应在最外层(如中间件或基类Handler)开启DbContextTransaction,或用IUnitOfWork封装。

查询不要偷偷改状态:虽然技术上可以,但违背CQRS语义。如果某个“查询”必须触发副作用(如记录访问日志),应显式命名为TrackUserViewQuery,并在文档/命名中体现其非纯查询性质。

异步要到底:所有Handler方法必须标记async Task,不要用.Result.Wait()阻塞——尤其在Web环境下会导致线程饥饿。

基本上就这些。MediatR本身很薄,真正考验的是你对领域边界的划分能力。用好它,不是为了炫技,而是让每个类只做一件事:接收请求、专注逻辑、返回结果。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

178

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

212

2025.12.18

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1019

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

63

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

411

2025.12.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

389

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

6

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 3.1万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

Sass 教程
Sass 教程

共14课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号