NestJS/TS 中的依赖地狱

mar*_*nka 3 javascript typescript nestjs

NestJS用许多模块构建项目,最近我有点迷失在它们中,我正在做的最后一件事被添加QueueService到我的ProjectServiceand中ProjectModule,但是在启动整个应用程序后,编译器向我抛出这个:

Error: Nest can't resolve dependencies of the QueueService (UtilsService, UserService, Connection, ?). Please make sure that the argument Object at index [3] is available in the ProjectModule context.
Run Code Online (Sandbox Code Playgroud)

索引 [3] 处的参数QueueServiceProjectService,那么为什么他们想要从我这里导入ProjectModule/ProjectService到我的ProjectModule?:P

这是我的所有代码:

@Injectable()
export class ProjectService {
    constructor(
        private conn: Connection,
        private utilsService: UtilsService,
        private userService: UserService,
        private notificationService: NotificationsService,
        private queueService: QueueService 
    ) { }
Run Code Online (Sandbox Code Playgroud)
@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt'})
  ],
  providers: [ProjectService, UtilsService, UserService, NotificationsService, QueueService ],
  controllers: [ProjectController],
  exports: [ProjectService]
})
export class ProjectModule {}
Run Code Online (Sandbox Code Playgroud)
@Injectable()
export class QueueService {
    constructor(
        readonly conn: Connection,
        readonly utilsService: UtilsService,
        readonly userService: UserService,
        readonly projectService: ProjectService
    ){}
}
Run Code Online (Sandbox Code Playgroud)
@Module({
  imports: [
    AuthModule,
    PassportModule.register({ defaultStrategy: 'jwt'})],
  providers: [QueueService , UtilsService, UserService, NotificationsService, ProjectService],
  controllers: [QueueController ],
  exports: [PassportModule]
})
export class QueueModule {}
Run Code Online (Sandbox Code Playgroud)

应用程序模块

@Module({
  imports: [
    ...,
    TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService
    }),
    PassportModule.register({ defaultStrategy: 'jwt'}),
    JwtModule.register({
        secret: 'secretKey'
    }),
    ScheduleModule.forRoot(),
    ...,
    ...,
    QueueModule,
    ...,
    ...,
    ProjectModule,
    ...,
    ...,
    ...
  ],
  controllers: [..., ..., ..., ..., ...],
  providers: [ ..., ..., ..., ..., ...,ProjectService, ..., ..., QueueService],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助,我在这里呆了 3-4 小时,我不知道我还能做什么:(

////////////////////////////////////////////////////////////////////////

Jay*_*iel 8

好吧,这里有很多东西要解压。因此,您的服务之间存在循环依赖关系,并且模块之间也应该存在循环依赖关系。现在发生的事情是您正在创建 的两个实例QueueService和 的两个实例ProjectService。但是,由于这些服务相互依赖,因此 Nest 无法正确实例化它们(至少目前是这样)。

因此,如果您想要每个两个,这里快速简单的解决方法是forwardRef为循环依赖类添加适当的内容。

队列服务

@Injectable()
export class QueueService {
    constructor(
        readonly conn: Connection,
        readonly utilsService: UtilsService,
        readonly userService: UserService,
        @Inject(forwardRef(() => ProjectService))
        readonly projectService: ProjectService
    ){}
}
Run Code Online (Sandbox Code Playgroud)

项目服务

@Injectable()
export class ProjectService {
    constructor(
        private conn: Connection,
        private utilsService: UtilsService,
        private userService: UserService,
        private notificationService: NotificationsService,
        @Inject(forwardref(() => QueueService))
        private queueService: QueueService 
    ) { }
Run Code Online (Sandbox Code Playgroud)

现在,如果这就是您想要的,那就太好了,请随时停止阅读此处并继续您的工作。


那么应该发生什么?如果您想要每个服务的真正单例(服务仅创建一次),您应该通过它们所属的模块共享提供程序并导入模块,而不是创建新值provider。由于您的ProjectModuleQueueModule是循环依赖的,因此您需要再次使用forwardRef. 上面的服务仍然有效,所以我不担心重写这些,但你的模块应该如下所示:

队列模块

@Module({
  imports: [
    AuthModule,
    forwardRef(() => ProjectModule),
    PassportModule.register({ defaultStrategy: 'jwt'})],
  providers: [QueueService , UtilsService, UserService, NotificationsService],
  controllers: [QueueController ],
  exports: [PassportModule, QueueService]
})
export class QueueModule {}
Run Code Online (Sandbox Code Playgroud)

项目模块

@Module({
  imports: [
    forwardref(() => QueueModule),
    PassportModule.register({ defaultStrategy: 'jwt'})
  ],
  providers: [ProjectService, UtilsService, UserService, NotificationsService ],
  controllers: [ProjectController],
  exports: [ProjectService]
})
export class ProjectModule {}
Run Code Online (Sandbox Code Playgroud)

您绝对应该检查您的UtilsModuleNotificationsModule、 和UserModule来清理它们的导出,并重新使用该模块而不是新的提供程序实例。