nestjs 无法注入服务 问题发现
在 viewService 里面导入 UserService,发现一直提示错误,没有找到可以注入的内容
检查了一遍代码,确认逻辑代码没有问题
怀疑是不是循环依赖了,检查代码,发现代码基本与其他 Moduel 的服务相同,没有出现循环依赖的情况
打印 ModuleContainer,在当前 ViewModule 里面找到了导入的 UserModule,也存在 UserService
view.service.ts 尝试打印是否成功导入 UserModule
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Injectable ()export class ViewService { constructor ( private modulesContainer: ModulesContainer, private userService: UserService, @InjectRepository (ViewEntity) private viewEntityRepository: Repository<ViewEntity> ) { [...modulesContainer.values()].map((module ) => { if (module .metatype.name === "ViewModule" ) { console .log("=======imports=======" ); console .log(module .imports); console .log("=======providers======" ); console .log(module .providers); console .log("=======exports======" ); console .log(module .exports); console .log("\n\n\n\n\n" ); console .log("=======UserModule exports======" ); [...module .imports.values()].map((innerModule) => { if (innerModule.metatype.name === "UserModule" ) { console .log(innerModule.exports); } }); } }); } }
view.module.ts
1 2 3 4 5 6 7 @Module ({ imports: [TypeOrmModule.forFeature([ViewEntity, ViewLikeStatEntity]), UserModule], controllers: [ViewController], providers: [ViewService], exports: [ViewService], }) export class ViewModule {}
view.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export type ViewRelationType = "topic" ;export interface JoinListInterface { uid: string ; avatar: string ; nickname: string ; roler: number ; } @Injectable ()export class ViewService { constructor (private readonly userService: UserService, @InjectRepository (ViewEntity) private readonly viewRepository: Repository<ViewEntity> ) {} create(createViewDto: CreateViewDto) { return "This action adds a new view" ; } ... }
控制台
1 2 3 4 5 6 7 8 [error] 2021-07-28 18:11:32.1 [ExceptionHandler] Nest can't resolve dependencies of the ViewService (?, ViewEntityRepository). Please make sure that the argument dependency at index [0] is available in the ViewModule context. Potential solutions: - If dependency is a provider, is it part of the current ViewModule? - If dependency is exported from a separate @Module, is that module imported within ViewModule? @Module({ imports: [ /* the Module containing dependency */ ] })
解决问题
再次检查代码,发现 view.service.ts 导出了三个东西,一个 type,一个 interface,还有一个 viewService 服务
全文查找导出的接口,发现在一个实体里面有这个类型的引入,就是 JoinListInterface .
topic.entity.ts
1 2 3 4 5 6 7 8 9 10 @Entity ("topics" , { schema: "42how" })export class TopicEntity { @PrimaryGeneratedColumn ({ type : "bigint" , name: "id" , unsigned: true }) id: number ; join: { count?: number ; list?: JoinListInterface[]; } = { count: 0 , list: [] }; }
尝试删除 JoinListInterface ,服务注入成功
原本以为 ts 的 interface,type 是不参与到编译过后的 js 文件,检查编译后 topic.entity.js 文件,发现 const view_service_1 = require("../modules/view/view.service");
这一句,虽然 interface 没有被使用,但是这个 js 文件被引入了。因为这个实体类被引入的比较多,产生了循环依赖,在 nestjs 进行注入的时候,这个文件导出是 undefined,查找不到服务,无法注入。
总结
ts 中 export 的类型文件应该单独定义,不要跟逻辑代码放在一个文件。
类型文件虽然没有参与编译,但是会引入文件,如果引用的过于复杂,会导致循环依赖的情况
感谢青木大佬的帮助