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

如何正确注册MediatR的泛型IRequestHandler请求处理器

解决方案

错误根因

你遇到的异常是两个原因共同导致的:

  • MediatR 默认的扫描注册逻辑仅支持自动注册闭合泛型/非泛型的Handler,不会自动识别开放泛型的Handler实现
  • 你手动注册开放泛型Handler时,DI容器无法正确匹配IRequestHandler<,>(2个泛型参数)和GetAccessesHandler<>(1个泛型参数)的泛型参数映射关系,导致构造时抛出参数数量不匹配的异常

修复方案

方案1:手动注册闭合泛型Handler(适用实体数量少的场景)

如果你用到的实体类型不多,直接为每个用到的实体注册对应闭合类型的Handler即可,稳定无歧义:

// 以Telephone实体为例,每新增一个用到的实体加一行对应注册
services.AddTransient<IRequestHandler<GetAccessesQuery<Telephone>, ObjectAccessesResponse>, GetAccessesHandler<Telephone>>();

注意:请删除原来的services.AddTransient(typeof(IRequestHandler<,>), typeof(GetAccessesHandler<>));这行代码,避免冲突

方案2:反射批量注册(适用实体数量多的场景)

如果有大量继承自EntityBase的实体需要用到这个泛型Handler,可以用反射批量扫描注册:

// 扫描所有继承自EntityBase的非抽象实体类
var entityTypes = typeof(EntityBase).Assembly.GetTypes()
    .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(EntityBase)));

foreach (var entityType in entityTypes)
{
    var closedQueryType = typeof(GetAccessesQuery<>).MakeGenericType(entityType);
    var closedHandlerType = typeof(GetAccessesHandler<>).MakeGenericType(entityType);
    var closedHandlerInterface = typeof(IRequestHandler<,>).MakeGenericType(closedQueryType, typeof(ObjectAccessesResponse));
    services.AddTransient(closedHandlerInterface, closedHandlerType);
}

同样要删除原来的开放泛型Handler注册代码。

额外检查项

确认AddMediatR已经包含了泛型Query和Handler所在的程序集,避免扫描遗漏:

// 如果GetAccessesQuery和Handler和ValidationBehavior不在同一个程序集,需要额外加对应程序集
services.AddMediatR(
    typeof(ValidationBehavior<,>).Assembly,
    typeof(GetAccessesQuery<>).Assembly
);

内容的提问来源于stack exchange,提问作者lemon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:48:01