如何使用 NestJS 创建一个充当单例的服务

Val*_*rio 6 singleton dependency-injection nestjs

我正在尝试创建一个提供单例服务的模块。想象一个QueueService最简单的实现是单例服务。

可重现的存储库:https : //github.com/colthreepv/nestjs-singletons

代码墙

app.module.ts:

@Module({ imports: [FirstConsumerModule, SecondConsumerModule] })
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

firstconsumer.module.tssecondconsumer.module.ts(它们是相同的):

@Injectable()
class FirstConsumer {
  constructor(private readonly dependency: DependencyService) {}
}

@Module({
  imports: [DependencyServiceModule],
  providers: [DependencyService, FirstConsumer]
})
export class FirstConsumerModule {
  constructor(private readonly first: FirstConsumer) {}
}
Run Code Online (Sandbox Code Playgroud)

依赖.module.ts:

@Injectable()
export class DependencyService {
  constructor() { console.log("Instance created") }
}

@Module({ providers: [DependencyService], exports: [DependencyService] })
export class DependencyServiceModule {}
Run Code Online (Sandbox Code Playgroud)

代码完成

我想获得的是 console.logInstance created只发布一次。
在这一刻:

[NestFactory] Starting Nest application...
Instance created
Instance created
Instance created
[InstanceLoader] AppModule dependencies initialized +16ms
[InstanceLoader] DependencyServiceModule dependencies initialized +1ms
[InstanceLoader] FirstConsumerModule dependencies initialized +1ms
[InstanceLoader] SecondConsumerModule dependencies initialized +1ms
[NestApplication] Nest application successfully started +8ms
Run Code Online (Sandbox Code Playgroud)

Jay*_*iel 12

在 NestJS 中,模块是单例,只要它们是从同一个模块提供的,它们的提供者就被设置为单例。在您的示例代码中,您拥有三个不同模块的DependencyService三个不同providers数组。应该做的是将它放在providers数组DependencyServiceModuleexports数组中。那么您只需要在andDependencyServiceModuleimports数组中添加 the并且不要将 the 添加到任何一个的数组中。由于存在于数组中,提供者已经可用于模块上下文。FrstConsumerModuleSecondConsumerModuleDependencyServiceprovidersexports

@Module({
  providers: [DependencyService],
  exports: [DependencyService]
})
export class DependencyServiceModule {}
Run Code Online (Sandbox Code Playgroud)
@Module({
  imports: [DependencyServiceModule],
  providers: [FirstConsumer] // notice no DependencyService class
})
export class FirstConsumerModule {}
Run Code Online (Sandbox Code Playgroud)
@Module({
  imports: [DependnecyServiceModule, FirstCosnumerModule]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

使用上述内容,您只会看到一个“实例创建”日志,而不是两个。

  • 感谢你的回答。TLDR:nestjs 中的服务是单例,但**仅**关于模块。因此,如果您希望 _ThingService_ 成为所有应用程序中的单个实例,则应该创建一个实例化所述 _ThingService_ 的模块,然后将其导出。这样,_ThingService_ 将只有一个实例 (9认同)