使用MediatR时同一请求模型如何获取不同响应类型
MediatR 匹配 Handler 逻辑说明
你的假设完全正确,MediatR 的 Send 方法确实仅通过请求类型来匹配对应的 Handler,同一请求类型仅能绑定唯一 Handler,你当前的代码必然会运行报错,核心问题如下:
- 首先你没有让
ProductModel实现IRequest<TResponse>接口,本身就不符合 MediatR 的请求定义规则 - 就算你给
ProductModel实现了对应接口,绑定两个不同的 Handler 后,运行时会直接抛出「找到多个匹配 Handler」的异常
正确的实现方案
你确实需要为每个不同的业务操作单独定义唯一的请求模型,这是 MediatR 的设计约定,也符合 CQRS 模式的设计思路,哪怕不同请求的入参结构完全一致,也不建议复用同一个请求类。
第一步:定义独立的请求类
// 查询订单的请求类 public class GetOrdersQuery : IRequest<IEnumerable<Order>> { public ProductModel Product { get; set; } } // 保存产品的请求类 public class SaveProductCommand : IRequest<Product> { public ProductModel Product { get; set; } }
第二步:修改 Handler 绑定对应请求
public class GetOrdersHandler : IRequestHandler<GetOrdersQuery, IEnumerable<Order>> { private readonly FakeDataStore _fakeDataStore; public GetOrdersHandler(FakeDataStore fakeDataStore) { _fakeDataStore = fakeDataStore; } public async Task<IEnumerable<Order>> Handle(GetOrdersQuery request,CancellationToken cancellationToken) { return await _fakeDataStore.GetAllOrdersForProduct(request.Product); } } public class SaveProductHandler : IRequestHandler<SaveProductCommand, Product> { private readonly FakeDataStore _fakeDataStore; public SaveProductHandler(FakeDataStore fakeDataStore) { _fakeDataStore = fakeDataStore; } public async Task<Product> Handle(SaveProductCommand request,CancellationToken cancellationToken) { return await _fakeDataStore.SaveProduct(request.Product); } }
第三步:修改控制器的调用逻辑
public class ProductsController : ControllerBase { private readonly IMediator _mediator; public ProductsController(IMediator mediator) => _mediator = mediator; [HttpPost("orders")] public async Task<ActionResult> GetAllOrders(ProductModel model) { var result = await _mediator.Send(new GetOrdersQuery { Product = model }); return Ok(result); } [HttpPost] public async Task<ActionResult> SaveProduct(ProductModel model) { var result = await _mediator.Send(new SaveProductCommand { Product = model }); return Ok(result); } }
补充说明
- 独立的请求类代码量极小,不会产生过多冗余,同时还能让业务边界更清晰,后续维护成本更低
- 如果你确实不想拆分请求类,可以使用 MediatR 的
INotification通知机制,但通知是多播模式,所有匹配的 Handler 都会依次执行,且通知没有返回值,完全不符合你当前需要不同返回值的业务场景,不推荐使用。
内容的提问来源于stack exchange,提问作者LP13
相关产品推荐
相关产品推荐

