如何在tsyringe中向可注入类注入单例实例?
解决tsyringe注入实例与直接resolve类实例不一致的问题
问题原因
你遇到的核心问题是:@singleton()装饰器会自动将MockUserRepository类注册为容器内的单例,而你手动调用container.register('UserRepository', {useClass: MockUserRepository}, {lifecycle: Lifecycle.Singleton})是创建了一个独立的别名注册项。这两个注册项(类本身的单例、别名指向的单例)在tsyringe容器中是分开管理的,所以会生成两个不同的实例。
解决方案
有两种简洁的解决方式:
方式一:统一使用别名获取实例
不要直接通过MockUserRepository类resolve实例,而是始终使用别名'UserRepository'来获取,这样注入到UserServiceImpl的实例和你手动获取的实例会完全一致:
// 改用别名resolve实例 const userRepository = container.resolve<UserRepository>('UserRepository'); await userRepository.create({ id: 'userId' }); const user = await userService.getUserById('userId'); // 此时能正确获取用户
方式二:让别名复用类的单例注册
利用useExisting让别名'UserRepository'直接复用MockUserRepository类的单例注册,这样不管是通过类还是别名resolve,拿到的都是同一个实例:
// 移除原来的register配置,替换为以下代码 container.register('UserRepository', { useExisting: MockUserRepository }); // 之后无论是注入别名,还是直接resolve类,实例都是同一个 const userService = container.resolve(UserServiceImpl); const userRepository = container.resolve(MockUserRepository);
这种方式的好处是不需要修改后续获取实例的代码,同时保证所有途径拿到的都是@singleton()装饰的那个单例实例。
内容的提问来源于stack exchange,提问作者Harineko
相关产品推荐
相关产品推荐

