Autofac复杂泛型DA类注册报错及StackOverflowException排查
问题根本原因与修复方案
现有注册代码的错误点
- 你的DA类使用
internal修饰,Autofac默认RegisterAssemblyTypes仅扫描程序集的public类型,导致所有DA类未被正确注册 - 抽象类
EntityDa<,>无法被实例化,单独注册泛型抽象基类完全多余,且你注册时指定的As(typeof(IEntityDa))与实际实现的泛型接口IEntityDa<TEntity>不匹配,会扰乱Autofac的解析逻辑 - 多余的泛型注册+缺失实际DA类注册,很容易触发依赖递归解析,最终导致
StackOverflowException
正确的注册方式
直接删除无效的泛型基类注册,修改程序集扫描逻辑包含internal类型即可:
// 扫描当前程序集所有非抽象、DA结尾的类(包含internal),注册为其实现的所有接口 builder.RegisterAssemblyTypes(this.ThisAssembly) .Where(t => !t.IsAbstract && t.IsClass && t.Name.EndsWith("Da")) .AsImplementedInterfaces() .InstancePerDependency(); // 如果你有直接注入`IEntityDa<TEntity>`泛型接口的场景,补充以下注册 builder.RegisterAssemblyTypes(this.ThisAssembly) .Where(t => !t.IsAbstract && t.IsClass && t.Name.EndsWith("Da")) .AsClosedTypesOf(typeof(IEntityDa<>)) .InstancePerDependency();
StackOverflowException排查方案
90%以上的Autofac场景栈溢出都是循环依赖导致的,比如PersonInfoDa依赖IStockDa,而StockDa的构造函数又直接/间接依赖IPersonInfoDa,就会触发无限递归构造,最终栈溢出:
- 先注释掉
PersonInfoDa构造函数中除上下文参数外的其他依赖,验证服务是否能正常启动,如果可以,说明问题出在依赖链上 - 逐个恢复构造函数的依赖参数,恢复到哪个参数时触发崩溃,就排查对应依赖类的构造函数,找出循环依赖链
- 确认循环依赖后,优先通过业务重构拆分循环依赖,如果暂时无法重构,可以通过注入
Lazy<T>延迟依赖实例化,或者改用属性注入的方式规避循环构造问题 - 你也可以在每个DA类的构造函数中添加控制台/日志输出,打印类名,运行时看反复输出的类名即可快速定位循环链
内容的提问来源于stack exchange,提问作者Dend
相关产品推荐
相关产品推荐

