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;
额外校验项
- 修正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); } }
- 使用常量避免拼写错误:通过
constants.ts统一管理注入令牌,杜绝手动拼写错误:
export const REPOSITORY_TOKENS = { UserRepository: 'UserRepository', AddressRepository: 'AddressRepository', // 其他仓库令牌 };
内容的提问来源于stack exchange,提问作者user27243259
相关产品推荐
相关产品推荐

