You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:18:04