NestJ, использующие один и тот же экземпляр сервиса в нескольких модулях - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть приложение NestJs, которое использует два сервиса. DbService, который подключается к Db, и SlowService, который работает довольно медленно и использует внедренный DbService.

Теперь приложение должно предоставлять маршруты работоспособности вне базового пути 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 {
}

ApiModule и HealthModule теперь импортируют базовый модуль, чтобы иметь возможность использовать сервисы.

  imports: [BaseModule],

Есть только небольшая проблема. Кажется, что оба модуля создают свой собственный экземпляр службы, но мне нужно, чтобы он был одним и тем же. Я предполагаю это, потому что console.log из конструктора появляются дважды при запуске приложения. Я пропускаю настройку или что-то?

UPDATE

Вот мой метод начальной загрузки, так что вы можете увидеть, как я инициализирую модули.

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()

1 Ответ

1 голос
/ 24 апреля 2019

Возможно, вы определили сервисы как провайдеры для 2 модулей. Вам нужно только определить BaseModule как import в модуле, где он вам нужен.

В этом примере демонстрируется служба OtherService в OtherModule, которой требуется DbService из BaseModule. Если вы запустите пример, вы увидите, что он создает экземпляр 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'));

Эта суть демонстрирует использование ПЛОХО провайдеров, что приводит к созданию экземпляра DbService дважды: https://gist.github.com/martijnvdbrug/12faf0fe0e1fc512c2a73fba9f31ca53

...