You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nest.js动态模块中Injectable单例重复创建问题咨询

简介

我实现了一个动态模块ConnectionModule,该模块会根据配置返回包含不同连接提供者的模块实例。

@Module({})
export class ConnectionModule {
  static register(cnf: ConnectionsList) {
    const cons = [];
    if (cnf.db) cons.push(PrismaService);
    if (cnf.keyValueStorage) cons.push(RedisConnection);

    return {
      module: ConnectionModule,
      exports: cons,
      providers: cons,
    };
  }
}

该模块支持三种组合:

  • 仅包含PrismaService的模块
  • 仅包含RedisConnection(标注为@Injectable)的模块
  • 同时包含两种服务的模块

问题

PrismaService和RedisConnection被重复创建了两次。

当单独使用前两种组合时,一切正常;但引入同时依赖两种服务的模块后,出现以下日志:

2025-03-18T21:28:51.686Z [RedisConnection] info: Redis connected
2025-03-18T21:28:51.694Z [PrismaService] info: Prisma Client connected to Database
2025-03-18T21:28:51.703Z [PrismaService] info: Prisma Client connected to Database
2025-03-18T21:28:51.705Z [RedisConnection] info: Redis connected

我推测Nest.js基于ConnectionModule创建了三个不同的单例模块实例,导致每个模块内的服务都被重新创建。根据Nest.js文档,默认情况下@Injectable标记的服务应为单例模式。

RedisConnection实现代码

@Injectable()
export class RedisConnection implements OnModuleInit {
  private keyValueStorage: Redis;

  constructor(
    private readonly configService: ConfigService,
  ) {}

  async onModuleInit() {
    this.keyValueStorage = new Redis(
      this.configService.get<string>('REDIS_URL'),
    );
  }

  public getKeyValueStorage() {
    return this.keyValueStorage;
  }
}

*日志输出触发自this.keyValueStorage.on('connect')

PrismaService实现代码

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }
}

*日志输出触发自this.$connect();之后

请问这是我配置遗漏了什么,还是Nest.js的bug?


内容的提问来源于stack exchange,提问作者Даниил Зеленко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:55:09