Angular 8升级至9后,继承类无法注入服务的问题求助
我之前从Angular 8升级到9时也碰到过一模一样的问题——核心原因是Angular 9默认启用的Ivy编译器对依赖注入的规则变得更严格了,尤其是针对继承类的构造函数注入逻辑。之前Angular 8的旧编译器可能对父类的DI元数据要求没那么高,但Ivy需要明确的标记才能正确解析继承链中的依赖。下面给你几个不用大规模重构就能解决的方案:
1. 给父类加上@Injectable()装饰器
不管你的FormStrategyDruidBase是普通类还是抽象类,都必须用@Injectable()标记它,这样Ivy才能识别它的构造函数依赖并正确传递给子类。比如:
import { Injectable } from '@angular/core'; @Injectable() export abstract class FormStrategyDruidBase { constructor( protected widgetType: DashboardWidget.TypeEnum, protected dashboardService: DashboardService, protected i18nService: I18NService, protected filterSelectService: FilterSelectService, protected formBuilder: FormBuilder ) { // 父类原有逻辑 } }
如果父类是抽象类也不用担心——Angular只需要它的DI元数据,不需要实例化它。
2. 确认子类super()的参数顺序完全匹配父类构造函数
Angular的依赖注入是按参数位置匹配的,哪怕参数名称正确,顺序错了也会导致注入失败。你要仔细核对父类构造函数的参数顺序,确保子类super()里的参数顺序和它完全一致。比如你示例里的super(DashboardWidget.TypeEnum.TimeLines, dashboardService, i18nService, filterSelectService, formBuilder),要对应父类构造函数的参数顺序:widgetType → dashboardService → i18nService → filterSelectService → formBuilder,这个顺序绝对不能错。
3. 临时关闭Ivy的严格注入检查(应急方案,不推荐长期用)
如果上面两个方案没法快速落地,你可以临时修改tsconfig.json中的Angular编译选项,关闭严格的注入参数检查:
{ "compilerOptions": { // 其他原有配置... }, "angularCompilerOptions": { "strictInjectionParameters": false, "enableIvy": true // 保留Ivy,只是放宽检查 // 或者暂时禁用Ivy:"enableIvy": false,回到旧编译器(不建议长期依赖) } }
注意:这个是临时方案,因为未来Angular会逐步淘汰旧编译器,所以尽量优先用前两个方案解决根源问题。
额外提醒
如果你的父类是在某个模块中提供的,还要确保该模块被正确导入;或者给父类的@Injectable()加上providedIn: 'root',让它成为全局可注入的类:
@Injectable({ providedIn: 'root' }) export abstract class FormStrategyDruidBase { // ... }
内容的提问来源于stack exchange,提问作者0leg

