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

TSyringe注入TypeORM Repository到Provider时数据库连接未就绪问题求助

问题根因

你遇到的报错本质是TypeORM的数据库连接是异步初始化流程,而你之前的TSyringe注册、resolve逻辑是同步执行的:

  • Repository构造函数中调用的getRepository依赖已经初始化完成的TypeORM连接
  • 你在导入注册文件时就同步执行了Provider的resolve逻辑,此时TypeORM还没完成连接建立,就会报实体仓库不存在的错误
  • setTimeout方案只是刚好等够了连接建立的时间,但稳定性差,不同环境下连接速度波动很容易再次触发报错

方案1:绑定启动流程,等TypeORM连接就绪后再执行依赖注册

这是最稳妥的方案,把整个应用的启动逻辑改成异步串行,确保依赖按顺序初始化:

实现步骤:

  1. 把入口启动逻辑改成异步函数,第一步先初始化TypeORM连接
  2. 连接成功后再依次导入、执行Repository和Provider的注册逻辑

代码示例:

// 应用入口文件 app.ts
import { createConnection } from 'typeorm';

async function bootstrap() {
  // 1. 优先完成数据库连接初始化
  await createConnection({
    // 你的TypeORM配置,也可以读ormconfig.json
  });

  // 2. 连接成功后再注册Repository
  import('./shared/container/repositories');

  // 3. 最后注册Provider,此时resolve依赖时Repository对应的ORM连接已经就绪
  import('./shared/container/providers');

  // 后续启动你的Express/Koa服务等逻辑
}

bootstrap().catch(err => {
  console.error('应用启动失败:', err);
  process.exit(1);
});

对应的providers/index.ts就不需要包setTimeout了,直接写原来的注册、resolve逻辑即可,因为导入的时候已经确保连接就绪。


方案2:惰性初始化Repository的ORM实例,不用调整启动顺序

如果不想改启动流程,可以修改Repository的实现,把getRepository的调用从构造函数移到实际调用时,避免实例化时就要求连接就绪:

代码示例:

export default class SafeUsdRepository implements ISafeUsdRepository {
  // 改成getter,只有实际调用仓库方法时才会获取ORM仓库实例,此时连接大概率已就绪
  private get ormRepository(): Repository<SafeUsd> {
    return getRepository(SafeUsd);
  }

  // 原有其他方法完全不用改
  async create(data: ICreateSafeUsdDTO): Promise<SafeUsd> {
    const safeUsd = this.ormRepository.create(data);
    await this.ormRepository.save(safeUsd);
    return classToClass(safeUsd);
  }

  // ... 其余方法保持不变
}

如果所有Repository都继承了公共基类,只需要改基类一次即可覆盖所有仓库,改造成本极低。


方案3:用TSyringe工厂函数实现依赖的异步初始化

也可以通过TSyringe的工厂注册能力,让依赖的实例化等待连接就绪:

代码示例:

// repositories/index.ts
import { container } from 'tsyringe';
import { getConnection } from 'typeorm';

container.register<ISafeUsdRepository>('SafeUsdRepository', {
  useFactory: async () => {
    // 等待连接就绪
    await getConnection();
    // 初始化仓库实例
    return new SafeUsdRepository();
  },
});

注册Provider的时候也可以用同样的逻辑,等待依赖的Repository实例就绪后再实例化Provider。


内容的提问来源于stack exchange,提问作者Régis Faria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:54:03