网站搜索

javascript - Nest 无法解析 BlahService 的依赖项,尽管它是 Global()


我在使用 NestJS 时遇到了一个问题,它似乎只发生在一个模块上,其他模块都正常工作。我有以下模块。

错误是:

[ExceptionHandler] Nest can't resolve dependencies of the ApplicationService (ApplicationModel, AwsService, UserService, ?, JobService). Please make sure that the argument at index [3] is available in the ApplicationModule context.

AgencyService 是 [3]。如果我从 ApplicationModule 中移除 AgencyModule,NestJS 可以成功编译,并且我可以进行 API 调用。

AgencyModule,
ApplicationModule,
AuthModule,
JobModule,
UserModule,

所有这些模块都被其他模块用于它们的服务提供者,所以我没有在它们之间使用 forwardRef() 导入它们,而是直接将它们设为 Global() - 可能不是最佳实践,但无所谓(它能工作)。

我的 AppModule 文件。

@Module({
  imports: [
    MongooseModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        uri: configService.get('MONGO_DB_URL'),
        useNewUrlParser: true,
      }),
      imports: [ConfigModule],
      inject: [ConfigService],
    }),
    ConfigModule,
    AgencyModule,
    ApplicationModule,
    AuthModule,
    DevModule,
    JobModule,
    UserModule,
    VideoModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

每个模块文件夹都有以下结构。

agency/
- dto/
- agency.controller.ts
- agency.interface.ts
- agency.schema.ts
- agency.service.ts
- agency.module.ts

我的 AgencyModule 文件。

@Global()
@Module({
  imports: [
    SharedModule,
    MongooseModule.forFeature([{ name: 'Agency', schema: AgencySchema }]),
  ],
  controllers: [
    AgencyController,
  ],
  providers: [
    AgencyService,
    AwsService,
  ],
  exports: [
    AgencyService,
  ],
})
export class AgencyModule implements NestModule {
  public configure(consumer: MiddlewareConsumer) {
    consumer
      .apply()
      .forRoutes(
        { path: 'agency', method: RequestMethod.GET },
      );
  }
}

我的 AgencyService 文件。

@Injectable()
export class AgencyService {
  constructor(
    @InjectModel('Agency') private readonly agencyModel: Model<Agency>,
    private readonly awsService: AwsService,
    private readonly applicationService: ApplicationService,
  ) {
    //
  }

  // More stuff here but not worth adding to the snippet.

}

我的 ApplicationModule 文件。

@Global()
@Module({
  imports: [
    SharedModule,
    MongooseModule.forFeature([{ name: 'Application', schema: ApplicationSchema }]),
  ],
  controllers: [
    ApplicationController,
  ],
  providers: [
    ApplicationService,
    AwsService,
  ],
  exports: [
    ApplicationService,
  ],
})
export class ApplicationModule implements NestModule {
  public configure(consumer: MiddlewareConsumer) {
    consumer
      .apply()
      .forRoutes(
        { path: 'application', method: RequestMethod.GET },
      );
  }
}

我的 ApplicationService 文件。

@Injectable()
export class ApplicationService {
  constructor(
    @InjectModel('Application') private readonly applicationModel: Model<Application>,
    private readonly awsService: AwsService,
    private readonly userService: UserService,
    private readonly agencyService: AgencyService,
    private readonly jobService: JobService,
  ) {
    //
  }

  // More stuff here but not worth adding to the snippet.

}

AwsService 是一个没有模块的共享服务。

答案#1

使用 @Global() 并不会自动解决循环依赖,你仍然需要在双方使用 @Inject(forwardRef(() => MyService)),详见文档。

正如你自己指出的,循环依赖(forwardRef)和全局模块(@Global)是不好的编码风格,应当避免。相反,要明确你的依赖关系。如果你遇到循环依赖,可以将常用部分提取到一个共享的服务/模块中,由双方共同导入,参见这个讨论线程。