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

DDD项目中如何筛选注册MediatR Handler以规避依赖注入构造错误

解决MediatR仅注册部分Handler的问题

方案1:通过标记接口筛选注册

先定义一个空的标记接口,用来标识审计应用需要的Handler:

public interface IAuditHandler { }

让所有审计相关的Handler实现这个接口:

public class GetAuditLogQueryHandler : IRequestHandler<GetAuditLogQuery, List<AuditLogDto>>, IAuditHandler
{
    private readonly AuditDbContext _dbContext;

    public GetAuditLogQueryHandler(AuditDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    // 实现Handle方法逻辑...
}

注册时手动筛选程序集中符合条件的Handler,仅添加这些类型:

var applicationAssembly = Assembly.GetExecutingAssembly();

// 筛选所有实现IAuditHandler且是有效RequestHandler的类型
var auditHandlerTypes = applicationAssembly.GetTypes()
    .Where(t => 
        t.IsClass && !t.IsAbstract &&
        typeof(IAuditHandler).IsAssignableFrom(t) &&
        t.GetInterfaces().Any(i => 
            i.IsGenericType && 
            i.GetGenericTypeDefinition() == typeof(IRequestHandler<,>)))
    .ToList();

builder.Services.AddMediatR(options =>
{
    options.Lifetime = ServiceLifetime.Scoped;
    // 逐个添加筛选后的Handler
    foreach (var handlerType in auditHandlerTypes)
    {
        options.AddHandler(handlerType);
    }
});

方案2:按命名空间筛选注册

如果审计相关的Handler都集中在同一个命名空间下(比如YourApp.Application.Audit.Handlers),可以直接按命名空间过滤:

var applicationAssembly = Assembly.GetExecutingAssembly();

var auditHandlerTypes = applicationAssembly.GetTypes()
    .Where(t => 
        t.IsClass && !t.IsAbstract &&
        t.Namespace?.StartsWith("YourApp.Application.Audit.Handlers") == true &&
        t.GetInterfaces().Any(i => 
            i.IsGenericType && 
            i.GetGenericTypeDefinition() == typeof(IRequestHandler<,>)))
    .ToList();

builder.Services.AddMediatR(options =>
{
    options.Lifetime = ServiceLifetime.Scoped;
    foreach (var handlerType in auditHandlerTypes)
    {
        options.AddHandler(handlerType);
    }
});

方案3:架构拆分(推荐长期维护)

把审计相关的Handler、请求模型单独拆分到一个独立的类库(比如YourApp.Application.Audit),这样两个应用可以按需引用:

  • 主应用引用完整的YourApp.Application类库,注册时加载整个应用程序集:
    builder.Services.AddMediatR(options =>
    {
        options.Lifetime = ServiceLifetime.Scoped;
        options.RegisterServicesFromAssemblies(typeof(MainAppHandler).Assembly);
    });
    
  • 审计应用仅引用YourApp.Application.Audit类库,注册时只加载这个类库的程序集:
    builder.Services.AddMediatR(options =>
    {
        options.Lifetime = ServiceLifetime.Scoped;
        options.RegisterServicesFromAssemblies(typeof(GetAuditLogQueryHandler).Assembly);
    });
    

为什么之前用IAuditHandler没成功?

大概率是你仍在使用RegisterServicesFromAssemblies批量注册,这个方法会加载程序集中所有符合MediatR规则的Handler,不会自动过滤标记接口。必须手动筛选类型后用AddHandler逐个添加,才能实现精准注册。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:51:14