如何避免逐个注册IMediatR实现程序集?现有方式过于繁琐
解决IMediatR批量注册程序集的问题
方案1:批量扫描所有包含IMediatR实现的程序集
通过反射扫描当前应用域内已加载的所有程序集,筛选出包含IRequestHandler或INotificationHandler等IMediatR核心接口实现的程序集,一次性完成注册。
示例代码:
// 获取所有包含IMediatR处理器的程序集 var targetAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(assembly => assembly.GetTypes().Any(type => type.GetInterfaces().Any(@interface => @interface.IsGenericType && (@interface.GetGenericTypeDefinition() == typeof(IRequestHandler<,>) || @interface.GetGenericTypeDefinition() == typeof(INotificationHandler<>))))) .ToList(); // 批量注册 builder.Services.AddMediatR(cfg => { foreach (var assembly in targetAssemblies) { cfg.RegisterServicesFromAssembly(assembly); } });
如果是ASP.NET Core应用,若存在延迟加载的程序集,可替换为AssemblyLoadContext.Default.Assemblies来获取全量已加载程序集。
方案2:封装扩展方法简化注册
把分散的程序集注册逻辑集中到扩展方法里,让Program.cs保持简洁。
先在项目中创建扩展类:
public static class MediatRExtensions { public static IServiceCollection AddAllMediatRHandlers(this IServiceCollection services) { services.AddMediatR(cfg => { // 集中添加所有包含处理器的程序集 cfg.RegisterServicesFromAssembly(typeof(UserQuery).Assembly); cfg.RegisterServicesFromAssembly(typeof(OrderCommand).Assembly); cfg.RegisterServicesFromAssembly(typeof(PaymentNotification).Assembly); }); return services; } }
然后在Program.cs中仅需一行代码调用:
builder.Services.AddAllMediatRHandlers();
方案3:按程序集命名前缀批量加载
如果业务程序集有统一命名前缀(比如MyProject.Domain、MyProject.Application),可通过名称筛选快速加载:
var assemblyPrefix = "MyProject."; var targetAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => a.FullName.StartsWith(assemblyPrefix)) .ToList(); builder.Services.AddMediatR(cfg => { foreach (var assembly in targetAssemblies) { cfg.RegisterServicesFromAssembly(assembly); } });
补充:为什么Assembly.GetExecutingAssembly()无效?
你的IMediatR处理器(Query/Command/Notification对应的Handler)大概率不在当前执行程序集(通常是Web项目)中,而是分散在其他类库项目里。Assembly.GetExecutingAssembly()只能获取当前运行的Web项目程序集,无法扫描到其他类库中的处理器,因此注册无效。
内容的提问来源于stack exchange,提问作者J003_
相关产品推荐
相关产品推荐

