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

Posted

技术标签:

【中文标题】如何使用 NestJS 创建充当单例的服务【英文标题】:How to create a Service that acts as a singleton with NestJS 【发布时间】:2020-05-28 06:44:19 【问题描述】:

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

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

代码墙

app.module.ts:

@Module( imports: [FirstConsumerModule, SecondConsumerModule] )
export class AppModule 

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

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


@Module(
  imports: [DependencyServiceModule],
  providers: [DependencyService, FirstConsumer]
)
export class FirstConsumerModule 
  constructor(private readonly first: FirstConsumer) 

dependency.module.ts:

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


@Module( providers: [DependencyService], exports: [DependencyService] )
export class DependencyServiceModule 

代码完成

我想要获得的是 console.log Instance 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

【问题讨论】:

【参考方案1】:

在 NestJS 模块中是单例,只要它们是从同一个模块提供的,它们的提供者就会成为单例。在您的示例代码中,您的DependencyService 位于三个不同的providers 数组中,用于三个不同的模块。相反,应该做的是将它放在DependencyServiceModuleproviders 数组和exports 数组中。那么你只需要在FrstConsumerModuleSecondConsumerModuleimports 数组中拥有DependencyServiceModule 并且不要DependencyService 添加到任一providers 数组中。由于在 exports 数组中,提供程序已经可用于模块上下文。

@Module(
  providers: [DependencyService],
  exports: [DependencyService]
)
export class DependencyServiceModule 
@Module(
  imports: [DependencyServiceModule],
  providers: [FirstConsumer] // notice no DependencyService class
)
export class FirstConsumerModule 
@Module(
  imports: [DependnecyServiceModule, FirstCosnumerModule]
)
export class AppModule 

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

【讨论】:

感谢您的回答。 TLDR:nestjs 中的服务是单例的,但与模块有关。因此,如果您希望 ThingService 成为所有应用程序中的单个实例,则应创建一个模块来实例化上述 ThingService,然后将其导出。这样 ThingService 将永远只有一个实例

以上是关于如何使用 NestJS 创建充当单例的服务的主要内容,如果未能解决你的问题,请参考以下文章

单例的几种方式,以及如何破坏单例,使用枚举保护单例;

Meyers 的单例实现实际上是如何实现单例的

如何使用 Swift 3 将单例与 Alamofire 一起使用?

spring单例和非单例的问题

如何在不使用单例的情况下在多个视图控制器之间传递数据?

NestJS-Prisma 如何使用关系字段创建记录?