为什么我的Nestjs服务会被实例化两次?

huangapple go评论61阅读模式
英文:

Why is my Nestjs Service being instantiated twice?

问题

我有以下的NgrokService代码:

@Injectable()
export class NgrokService
  implements OnApplicationBootstrap, OnApplicationShutdown
{
  port: string
  ngrokToken: string
  ngrok: typeof import('ngrok') | null = null

  constructor(private readonly configService: ConfigService) {
    this.port = this.configService.get('API_PORT') ?? '3001'

    this.ngrokToken = this.configService.getOrThrow('NGROK_TOKEN')

    if (process.env.NODE_ENV === 'development') this.ngrok = require('ngrok')
  }

  async onApplicationBootstrap() {
    if (process.env.NODE_ENV !== 'development') {
      return
    }

    this.tunnelUrl = await this.ngrok!.connect({
      addr: `https://localhost:${this.port}`,
      subdomain: '<my_subdomain>',

      region: 'us',
      authtoken: this.ngrokToken,
    })
  }

  async onApplicationShutdown() {
    if (process.env.NODE_ENV !== 'development') {
      return
    }

    this.ngrok!.disconnect()
  }
}

我在这里使用它:

@Module({
  imports: [],
  controllers: [HealthController],
  providers: [HealthService, AwsService, NgrokService],
})
export class HealthModule {}

还有在这里:

@Module({
  imports: [
    ...
  ],
  controllers: [...],
  providers: [
    ...
    NgrokService
  ],
})
export class AppModule {}

然而,不知何故,onApplicationBootstrap 钩子被调用了两次。经过调查,我只能通过将服务包装在一个模块中,创建一个全局锁变量来检查连接是否已经建立,才解决了这个问题。

我只想了解为什么会发生这种情况。为什么 Nestjs 会实例化服务两次?即使包装在模块中,服务也会被实例化两次。

英文:

I have the following NgrokService here:

@Injectable()
export class NgrokService
  implements OnApplicationBootstrap, OnApplicationShutdown
{
  port: string
  ngrokToken: string
  ngrok: typeof import(&#39;ngrok&#39;) | null = null

  constructor(private readonly configService: ConfigService) {
    this.port = this.configService.get(&#39;API_PORT&#39;) ?? &#39;3001&#39;

    this.ngrokToken = this.configService.getOrThrow(&#39;NGROK_TOKEN&#39;)

    if (process.env.NODE_ENV === &#39;development&#39;) this.ngrok = require(&#39;ngrok&#39;)
  }

  async onApplicationBootstrap() {
    if (process.env.NODE_ENV !== &#39;development&#39;) {
      return
    }

    this.tunnelUrl = await this.ngrok!.connect({
      addr: `https://localhost:${this.port}`,
      subdomain: &#39;&lt;my_subdomain&gt;&#39;,

      region: &#39;us&#39;,
      authtoken: this.ngrokToken,
    })
  }

  async onApplicationShutdown() {
    if (process.env.NODE_ENV !== &#39;development&#39;) {
      return
    }

    this.ngrok!.disconnect()
  }
}

I'm using it here:

@Module({
  imports: [],
  controllers: [HealthController],
  providers: [HealthService, AwsService, NgrokService],
})
export class HealthModule {}

and also here:

@Module({
  imports: [
    ...
  ],
  controllers: [...],
  providers: [
    ...
    NgrokService
  ],
})
export class AppModule {}

For some reason though, the onApplicationBootstrap hook gets called twice. After digging, I was only able to solve it by wrapping the service in a module and creating a global lock variable that checks if the connection was already made.

I just want to understand why this is happening. Why is Nestjs instantiating the service twice? Even wrapped in a module, the service gets instantiated twice.

答案1

得分: 4

提供者默认是每个模块的单例。

所以,如果你在多个模块中将 NgrokService 注册(即,在 providers 数组中),你将会得到多个实例。

英文:

providers are singleton by default per module

so if you have NgrokService registered (ie, in the providers array) in multiple modules, you'll get multiple instances.

答案2

得分: 0

如果你像这样做的话,也会遇到类似的行为:

```TypeScript
const app = await NestFactory.createMicroservice&lt;MicroserviceOptions&gt;(AppModule, microserviceOptions);
await app.init();

其中app.init()第二次调用了所有NestJS的初始化钩子。


<details>
<summary>英文:</summary>

Also, you could receive such behavior if you do something like that:

```TypeScript
const app = await NestFactory.createMicroservice&lt;MicroserviceOptions&gt;(AppModule, microserviceOptions);
await app.init();

Where app.init() secondly call all NestJS initializing hooks

huangapple
  • 本文由 发表于 2023年2月16日 04:05:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464942.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定