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

TSyringe+TypeORM+Express依赖注入报错:无法解析UserRepository

解决TSyringe + TypeORM依赖注入报错:UserRepository未注册

问题重现

报错信息:

Error resolving UserController: Error: Cannot inject the dependency "userService" at position #0 of "UserController" constructor. Reason:
    Cannot inject the dependency at position #0 of "UserService" constructor. Reason:
        Attempted to resolve unregistered dependency token: "UserRepository"

技术栈:Express + TypeScript + MySQL + TypeORM + TSyringe

核心错误原因

路由模块被提前加载:server.ts中导入userRouter时,user.router.ts里的container.resolve(UserController)会立即执行,而initializeDatabase是异步操作,此时数据库仓库和服务还未完成注册,导致依赖解析失败。

解决方案

方案1:延迟路由导入(推荐)

修改server.ts,将路由的导入和挂载放到数据库初始化完成后的回调中,确保依赖注册完成后再处理路由:

import app from './app';
import { initializeDatabase } from './config/ormconfig';

const PORT = process.env.PORT || 3000;

initializeDatabase().then(async () => {
    // 延迟导入路由,确保依赖已注册
    const userRouter = (await import('./routes/user.router')).default;
    app.use('/api/user', userRouter);

    app.get('/', (req, res) => {
        res.send('Hello World');
    });

    app.listen(PORT, () => {
        console.log(`Server is running on port ${PORT}`);
    });
}).catch((error) => {
    console.error('Error starting the server:', error);
});

方案2:延迟控制器解析

修改user.router.ts,不在模块加载时立即解析控制器,而是在请求处理时动态解析:

import { Router } from 'express';
import { container } from 'tsyringe';
import { UserController } from '../controllers/user.controller';

const router = Router();

// 每个请求时再解析控制器,避免提前执行依赖解析
router.post('/register', async (req, res) => {
    const userController = container.resolve(UserController);
    await userController.createUser(req, res);
});

router.post('/login', async (req, res) => {
    const userController = container.resolve(UserController);
    await userController.loginUser(req, res);
});

router.get('/:user_key', async (req, res) => {
    const userController = container.resolve(UserController);
    await userController.getUserByKey(req, res);
});

router.get('/', async (req, res) => {
    const userController = container.resolve(UserController);
    await userController.getAllUsers(req, res);
});

export default router;

额外校验项

  1. 修正UserService代码:你提供的user.service.ts实际是AddressService的代码,确保UserService正确注入UserRepository:
import { Repository } from 'typeorm';
import { User } from '../entities/user.entity';
import { injectable, inject } from 'tsyringe';
import { REPOSITORY_TOKENS } from '../config/constants';

@injectable()
export class UserService {
    constructor(
        @inject(REPOSITORY_TOKENS.UserRepository) private userRepository: Repository<User>
    ) {}

    // 业务方法示例
    async createUser(userData: Partial<User>) {
        return await this.userRepository.save(userData);
    }
}
  1. 使用常量避免拼写错误:通过constants.ts统一管理注入令牌,杜绝手动拼写错误:
export const REPOSITORY_TOKENS = {
    UserRepository: 'UserRepository',
    AddressRepository: 'AddressRepository',
    // 其他仓库令牌
};

内容的提问来源于stack exchange,提问作者user27243259

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:49:53