如何向TypeORM数据库的实体中注入provider?
TypeORM 实体的实例化由 ORM 内核自行完成,不会经过 NestJS 的依赖注入容器处理,因此你在构造函数中添加的
@Inject装饰器无法生效,自然会得到undefined结果。
方案1:调整分层逻辑(推荐)
实体的核心职责是做数据库表和数据对象的映射,不建议承载业务逻辑。你可以把需要用到ClientProxy的逻辑迁移到对应模块的Service或自定义Repository中,这两类实例由 NestJS IoC 容器管理,直接用构造函数注入即可正常获取实例。
方案2:手动从全局容器获取
如果确实有场景需要在实体内部调用Provider,可以通过全局挂载Nest应用实例的方式手动获取:
- 先封装全局应用实例工具:
// src/utils/app-instance.util.ts import { INestApplication } from '@nestjs/common'; let nestAppInstance: INestApplication; export const setNestAppInstance = (app: INestApplication) => { nestAppInstance = app; }; export const getNestAppInstance = () => nestAppInstance;
- 在项目启动文件
main.ts中完成实例挂载:
import { setNestAppInstance } from 'src/utils/app-instance.util'; async function bootstrap() { const app = await NestFactory.create(AppModule); setNestAppInstance(app); await app.listen(3000); } bootstrap();
- 在实体内部需要的位置手动获取
ClientProxy:
import { getNestAppInstance } from 'src/utils/app-instance.util'; import { ClientProxy } from '@nestjs/microservices'; // 你的实体类 export class YourEntity { // 实体方法 sendMessage() { const messageClient = getNestAppInstance().get<ClientProxy>('NAME'); // 后续业务逻辑 } }
注意:调用实体方法时需确保Nest应用已完成初始化,否则会出现实例未定义的报错。
方案3:用实体订阅者承载生命周期关联逻辑
如果你的需求是在实体的增删改查等生命周期节点触发消息发送,可以使用TypeORM的EventSubscriber,订阅者支持Nest依赖注入:
import { Injectable, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm'; import { YourEntity } from './your.entity'; @EventSubscriber() @Injectable() export class YourEntitySubscriber implements EntitySubscriberInterface<YourEntity> { constructor( @Inject('NAME') private messageClient: ClientProxy ) {} // 绑定监听的实体 listenTo() { return YourEntity; } // 示例:实体插入完成后触发 async afterInsert(event: InsertEvent<YourEntity>) { this.messageClient.emit('your_event_topic', event.entity); } }
最后将该订阅者加入对应模块的providers数组即可生效。
内容的提问来源于stack exchange,提问作者CryToy
相关产品推荐
相关产品推荐

