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
相关产品推荐
相关产品推荐

