NestJs 在多个模块中使用相同的服务实例

Woo*_*zar 5 nestjs

我有一个 NestJs 应用程序,它使用两种服务。连接到 Db 的 DbService 和执行速度相当慢并使用注入的 DbService 的 SlowService。

现在应用程序将提供 api 基本路径之外的健康路线,所以我需要一个不同的模块来为健康路线提供控制器。

我创建了一个基本模块。

import { Module } from '@nestjs/common'
import { SlowService } from './slow.service'
import { DbService } from './db.service'

@Module({
  imports: [],
  controllers: [],
  providers: [DbService, SlowService],
  exports: [DbService, SlowService]
})
export class BaseModule {
}
Run Code Online (Sandbox Code Playgroud)

ApiModule 和 HealthModule 现在都导入了基本模块以便能够使用这些服务。

  imports: [BaseModule],
Run Code Online (Sandbox Code Playgroud)

只有一个小问题。两个模块似乎都构建了自己的服务实例,但我需要它是同一个实例。我假设是这样,因为在启动应用程序时,构造函数中的 console.log 出现了两次。我错过了设置还是什么?

更新

这是我的引导程序方法,因此您可以看到我如何初始化模块。

async function bootstrap (): Promise<void> {
  const server = express()
  const api = await NestFactory.create(AppModule, server.application, { cors: true })
  api.setGlobalPrefix('api/v1')
  await api.init()
  const options = new DocumentBuilder()
    .setTitle('...')
    .setLicense('MIT', 'https://opensource.org/licenses/MIT')
    .build()
  const document = SwaggerModule.createDocument(api, options)
  server.use('/swaggerui', SwaggerUI.serve, SwaggerUI.setup(document))
  server.use('/swagger', (req: express.Request, res: express.Response, next?: express.NextFunction) => res.send(document))
  const health = await NestFactory.create(HealthModule, server.application, { cors: true })
  health.setGlobalPrefix('health')
  await health.init()
  http.createServer(server).listen(Number.parseInt(process.env.PORT || '8080', 10))
}
const p = bootstrap()

Run Code Online (Sandbox Code Playgroud)

Mar*_*vdB 11

也许您将服务定义为 2 个模块的提供者。你需要做的仅仅是定义你的BaseModule作为进口在你需要它的模块中。

这个例子说明了服务OtherServiceOtherModule其中需要DbServiceBaseModule。如果您运行该示例,您将看到它仅实例化DbService一次。

import {Injectable, Module} from '@nestjs/common';
import {NestFactory} from '@nestjs/core';

@Injectable()
export class SlowService {
  constructor() {
    console.log(`Created SlowService`);
  }
}

@Injectable()
export class DbService {
  constructor() {
    console.log(`Created DbService`);
  }
}

@Module({
  imports: [],
  providers: [SlowService, DbService],
  exports: [SlowService, DbService]
})
export class BaseModule {}

@Injectable()
export class OtherService {
  constructor(private service: DbService) {
    console.log(`Created OtherService with dependency DbService`);
  }
}

@Module({
  imports: [BaseModule],
  providers: [OtherService],
})
export class OtherModule {}

@Module({
  imports: [
    BaseModule,
    OtherModule
  ],
})
export class AppModule {}

NestFactory.createApplicationContext(AppModule).then((app) => console.log(' context created'));
Run Code Online (Sandbox Code Playgroud)

这个要点演示了提供者的错误用法,导致实例化DbService两次:https : //gist.github.com/martijnvdbrug/12faf0fe0e1fc512c2a73fba9f31ca53

  • 非常感谢您的详细回答。这正是我认为我所做的,但我会再次调查。 (4认同)
  • @Woozar,我遇到了同样的问题,这个答案也对我有帮助。我建议选择它作为接受。 (3认同)