MediatR可创建的命令/查询类型及应用层结构正确性咨询
MediatR 使用相关问题解答
一、MediatR 可处理的命令/查询类型
MediatR的核心是实现请求-响应模式,只要是能抽象为“请求-处理-结果”的操作,都可以用它来实现,常见场景包括:
- CRUD操作:比如创建资源的
CreateProductCommand、查询资源的GetProductListQuery - 身份认证相关:登录、获取用户声明完全适用,例如
LoginCommand返回登录令牌,GetUserClaimsQuery返回用户的权限声明集合 - 消息通知类:发送邮件、推送系统通知这类操作,可封装为
SendEmailCommand;如果不需要返回结果,也可以用INotification实现多处理器监听 - 业务逻辑操作:比如订单处理、发票计算这类包含复杂业务规则的操作,例如
ProcessOrderCommand、CalculateInvoiceAmountQuery - 系统维护操作:清理临时文件、同步数据这类系统级操作,也能封装为对应的命令
二、使用MediatR的核心规则
没有强制的硬性规则,但遵循这些实践能让你的代码更清晰、符合设计初衷:
- 单一职责:每个请求(命令/查询)只对应一个明确的操作,不要把多个无关逻辑塞进同一个请求里(比如不要做一个
UserCommand同时处理登录、注册、修改密码,拆成单独的请求) - CQRS 区分:
- 命令:用于改变系统状态(如更新数据、发送邮件),可以返回操作状态(如成功/失败、生成的令牌)
- 查询:仅用于读取数据,不能包含修改系统状态的逻辑(比如查询处理器里不能更新数据库)
- 通知的适用场景:当一个事件需要多个独立逻辑处理时(比如订单创建后,同时触发发邮件、更新库存、记录日志),用
INotification而非命令 - 处理器独立性:每个请求的处理器逻辑要独立,不要依赖其他处理器的执行结果,保持高内聚低耦合
三、关于应用层结构的说明
由于你未提供附图的具体内容,无法直接判断结构是否正确。这里给出基于DDD和MediatR的常用应用层结构示例,供你参考:
Application/ ├── Commands/ │ ├── Login/ │ │ ├── LoginCommand.cs │ │ └── LoginCommandHandler.cs │ └── SendEmail/ │ ├── SendEmailCommand.cs │ └── SendEmailCommandHandler.cs ├── Queries/ │ ├── GetUserClaims/ │ │ ├── GetUserClaimsQuery.cs │ │ └── GetUserClaimsQueryHandler.cs │ └── GetProduct/ │ ├── GetProductQuery.cs │ └── GetProductQueryHandler.cs ├── Notifications/ │ ├── OrderCreatedNotification.cs │ └── OrderCreatedNotificationHandler.cs ├── Dtos/ │ ├── UserDto.cs │ └── ProductDto.cs └── Interfaces/ └── IEmailService.cs
核心设计要点:
- 按请求类型(命令/查询/通知)划分目录,每个请求单独建子目录存放请求类和对应的处理器
- 数据传输对象(Dto)单独抽离,避免与领域模型或请求类耦合
- 依赖的外部服务接口定义在应用层,具体实现放在基础设施层
内容的提问来源于stack exchange,提问作者Daniil Kozenko
相关产品推荐
相关产品推荐

