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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:18:20