如何在LoopBack 4中全局访问repository供非控制器场景调用
LoopBack 4 非控制器类访问Repository的实现方案
核心原因
控制器中可以直接用@repository注入是因为控制器本身是被LoopBack框架托管的类,会自动经过依赖注入容器解析。普通的自定义类默认不在容器的托管范围内,直接使用装饰器不会生效。
实现步骤(适配定时任务场景)
步骤1:创建可注入的业务服务类
将数据库操作封装到标记为@injectable的服务类中,即可和控制器一样使用@repository注入Repository:
import { injectable, BindingScope } from '@loopback/core'; import { repository } from '@loopback/repository'; import { UserRepository } from '../repositories'; // 标记为单例作用域的可注入服务,符合定时任务的使用场景 @injectable({ scope: BindingScope.SINGLETON }) export class UserTaskService { constructor( @repository(UserRepository) public userRepository: UserRepository, ) {} // 封装定时任务要执行的数据库更新逻辑 async executeDailyUpdate() { // 此处编写你的业务逻辑,示例为批量更新用户数据 await this.userRepository.updateAll({ dailyUpdated: new Date() }); } }
步骤2:注册服务并启动定时任务
在应用启动逻辑中完成服务注册,从应用上下文中获取服务实例后绑定到cron定时任务即可:
// application.ts 中修改 import * as cron from 'node-cron'; import { UserTaskService } from './services/user-task.service'; export class MyApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), ) { constructor(options: ApplicationConfig = {}) { super(options); // 原有应用配置保持不变 // 注册自定义服务 this.service(UserTaskService); } async start() { await super.start(); // 从应用上下文中获取服务实例,容器会自动完成Repository的注入 const userTaskService = await this.get<UserTaskService>('services.UserTaskService'); // 配置cron规则,示例为每天凌晨1点执行 cron.schedule('0 0 1 * * *', async () => { try { await userTaskService.executeDailyUpdate(); } catch (err) { console.error('定时任务执行失败:', err); } }); } }
临时调用方案
如果需要在临时场景下直接调用Repository,可以直接从应用实例的上下文中获取:
// 前提是可以获取到应用实例app const userRepository = await app.get<UserRepository>('repositories.UserRepository'); // 直接调用Repository方法 await userRepository.find();
注意:不要手动实例化带有
@inject/@repository装饰器的类,手动创建的实例不会经过依赖注入容器解析,所有注入装饰器都会失效,必须通过app.get()方法从上下文中获取实例。
内容的提问来源于stack exchange,提问作者Sina Honarvar
相关产品推荐
相关产品推荐

