简体   繁体   English

NestJS/TS 中的依赖地狱

[英]Dependency hell in NestJS/TS

I build NestJS projecct with many modules and recently I got lost in them a bit, My last thing which I'm doing was added QueueService to my ProjectService and ProjectModule , but after launch whole app, the compiler throw me this:我用许多模块构建NestJS项目,最近我有点迷失了,我做的最后一件事是将QueueService添加到我的ProjectServiceProjectModule中,但是在启动整个应用程序后,编译器向我抛出了这个:

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.

The argument at the index[3] at QueueService is ProjectService , so why they want from me to import ProjectModule/ProjectService into my ProjectModule ? QueueService的 index[3] 处的参数是ProjectService ,那么为什么他们希望我将ProjectModule/ProjectService导入我的ProjectModule :P :P

here is my all code:这是我的所有代码:

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

AppModule应用模块

@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 {}

thanks for any help, I stuck here for 3-4h and I do not know what can I do more:(感谢您的帮助,我在这里停留了 3-4 小时,我不知道我还能做些什么:(

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

Okay, lots to unpack here.好的,这里有很多东西要解压。 So you've got circular dependencies between your services and you should have circular dependencies between your modules.所以你的服务之间有循环依赖关系,你的模块之间应该有循环依赖关系。 What's happening right now is that you're creating two instances of QueueService and two instances of ProjectService .现在发生的事情是您正在创建QueueService的两个实例和ProjectService的两个实例。 However, because these services depend on each other, there isn't a way for Nest to properly instantiate them (at least how you have it currently).然而,由于这些服务相互依赖,Nest 没有办法正确地实例化它们(至少目前是这样)。

So, the quick and easy fix here, if you want two of each, is to add the proper forwardRef for the circularly dependent classes.因此,如果您想要每个两个,这里快速简便的解决方法是为循环依赖的类添加正确的forwardRef

QueueService队列服务

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

ProjectService项目服务

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

Now if that's all you want, great, feel free to stop reading here and go about your business.现在,如果这就是您想要的,太好了,请随时停止阅读此处和 go 关于您的业务。


So what should be happening?那么应该发生什么? If you want true singletons of each service (services only created once) you should be sharing the providers via the modules they belong to and importing the module, not creating a new provider value.如果您想要每个服务的真正单例(服务只创建一次),您应该通过它们所属的模块共享提供者并导入模块,而不是创建新的provider值。 As your ProjectModule and QueueModule are circularly dependent, you'll need to once again use forwardRef .由于您的ProjectModuleQueueModule是循环依赖的,因此您需要再次使用forwardRef The services above are still valid, so I won't worry about re-writing those, but your modules should look like below:上面的服务仍然有效,所以我不用担心重写它们,但是你的模块应该如下所示:

QueueModule队列模块

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

ProjectModule项目模块

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

You should absolutely look into your UtilsModule , NotificationsModule , and UserModule to clean up their exports, and re-use the module instead of new provider instances as well.您绝对应该查看您的UtilsModuleNotificationsModuleUserModule以清理它们的导出,并重新使用模块而不是新的提供程序实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM