如何在Simple Injector中批量注册CQRSlite事件处理器?
解决CQRSlite与Simple Injector批量注册事件处理器的方案
问题核心在于CQRSlite的RouteRegistrar需要提前知晓所有具体事件处理器类型,而你最初使用的开放泛型批量注册(container.Register(typeof(ICancellableEventHandler<>), ...))是延迟创建实例的模式,无法被RouteRegistrar识别。以下是几种无需开启ResolveUnregisteredConcreteTypes的替代方案:
方案1:使用Simple Injector内置的RegisterManyForOpenGeneric方法
这是最简洁的官方推荐方式,专门用于批量注册所有实现了开放泛型接口的具体类型:
container.RegisterManyForOpenGeneric( typeof(ICancellableEventHandler<>), typeof(MaterialAddedToOperationHandler).Assembly);
该方法会自动扫描指定程序集中所有非抽象、实现了ICancellableEventHandler<T>的类,并将每个类注册为对应泛型接口的实现。这样CQRSlite的RouteRegistrar就能直接找到所有处理器类型,同时保持容器注册的显式性。
方案2:手动扫描并注册具体处理器类型
如果需要更灵活的过滤逻辑(比如排除某些类型),可以手动遍历程序集内的处理器类型,逐个注册:
var targetAssembly = typeof(MaterialAddedToOperationHandler).Assembly; // 筛选所有符合条件的事件处理器类型 var handlerTypes = targetAssembly.GetTypes() .Where(t => !t.IsAbstract && !t.IsInterface) .Where(t => t.GetInterfaces() .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICancellableEventHandler<>))); // 逐个注册到对应的泛型接口 foreach (var handlerType in handlerTypes) { var matchingInterface = handlerType.GetInterfaces() .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICancellableEventHandler<>)); // 根据你的项目需求选择生命周期(Transient/Scoped/Singleton) container.Register(matchingInterface, handlerType, Lifestyle.Transient); }
方案3:自定义CQRSlite的路由注册逻辑
如果上述两种方式仍不满足需求,可以重写CQRSlite的RouteRegistrar逻辑,让它能从Simple Injector容器中获取所有已注册的泛型接口实现类型。不过这种方式复杂度较高,仅建议在有特殊定制需求时使用。
内容的提问来源于stack exchange,提问作者bdongus
相关产品推荐
相关产品推荐

