如何在NestJS普通实体类中注入Repository提供者(非TypeORM)
如何在NestJS中将Repository提供者注入到普通实体类中?
问题原因
你通过new UserAggregateEntity(user)手动创建实例,这类对象不在Nest的DI容器管理范围内,因此@Inject()装饰器不会生效,导致customerRepository为undefined。Nest的依赖注入仅对由DI容器实例化的类(比如标记了@Injectable()的服务)生效。
解决方案
方案1:将聚合类转为可注入,使用工厂提供者创建实例
把UserAggregateEntity标记为@Injectable(),通过工厂提供者处理它需要的user参数,同时注入CustomerRepository。
- 修改聚合类,将依赖通过构造函数注入:
import { Injectable, Inject } from '@nestjs/common'; import { CustomerRepository } from './customer.repository'; import { UserEntity, CustomerEntity } from './entities'; @Injectable() export class UserAggregateEntity { private customer: CustomerEntity; constructor( private user: UserEntity, @Inject(CustomerRepository) private readonly customerRepository: CustomerRepository, ) {} async createCustomer(customer: CustomerEntity): Promise<string> { customer.user = this.user.id; const savedCustomer = await this.customerRepository.create(customer); this.customer = savedCustomer; return customer.id; } }
- 在模块中配置工厂提供者,动态传入
user参数:
import { Module, Provider } from '@nestjs/common'; import { UserAggregateEntity } from './user-aggregate.entity'; import { CustomerRepository } from './customer.repository'; export const UserAggregateFactory: Provider = { provide: 'UserAggregateFactory', useFactory: (customerRepository: CustomerRepository) => { return (user: UserEntity) => new UserAggregateEntity(user, customerRepository); }, inject: [CustomerRepository], }; @Module({ providers: [CustomerRepository, UserAggregateFactory], exports: ['UserAggregateFactory'], }) export class YourModule {}
- 在服务中使用工厂创建聚合实例:
import { Inject, Injectable } from '@nestjs/common'; import { UserEntity, CustomerEntity } from './entities'; @Injectable() export class UserService { constructor( @Inject('UserAggregateFactory') private readonly userAggregateFactory: (user: UserEntity) => UserAggregateEntity, ) {} async createCustomerForUser(user: UserEntity, customer: CustomerEntity) { const userAggregate = this.userAggregateFactory(user); return await userAggregate.createCustomer(customer); } }
方案2:将业务逻辑移至服务层(推荐)
领域实体/聚合根应专注于业务规则和状态管理,不直接依赖Repository。把调用Repository的逻辑移到服务层,聚合根只处理核心业务逻辑:
- 修改聚合类,移除Repository依赖:
export class UserAggregateEntity { private customer: CustomerEntity; constructor(private user: UserEntity) {} prepareCustomerForCreation(customer: CustomerEntity): CustomerEntity { customer.user = this.user.id; // 这里可添加业务规则校验、状态转换等逻辑 return customer; } setCustomer(customer: CustomerEntity) { this.customer = customer; } }
- 在服务层注入Repository并处理持久化:
import { Injectable } from '@nestjs/common'; import { CustomerRepository } from './customer.repository'; import { UserEntity, CustomerEntity } from './entities'; import { UserAggregateEntity } from './user-aggregate.entity'; @Injectable() export class UserService { constructor(private readonly customerRepository: CustomerRepository) {} async createCustomer(user: UserEntity, customer: CustomerEntity): Promise<string> { const userAggregate = new UserAggregateEntity(user); const preparedCustomer = userAggregate.prepareCustomerForCreation(customer); const savedCustomer = await this.customerRepository.create(preparedCustomer); userAggregate.setCustomer(savedCustomer); return savedCustomer.id; } }
这种方式更符合领域驱动设计(DDD)原则,聚合根聚焦领域逻辑,数据持久化由基础设施层和应用服务层处理。
方案3:手动从DI容器获取依赖(不推荐)
如果必须在手动实例化的类中使用依赖,可以通过Nest全局容器获取,但会增加耦合度,不建议生产代码使用:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { CustomerRepository } from './customer.repository'; // 启动时保存容器实例 let app; async function bootstrap() { app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap(); export class UserAggregateEntity { private customerRepository: CustomerRepository; private customer: CustomerEntity; constructor(private user: UserEntity) { // 从容器中获取Repository实例 this.customerRepository = app.get(CustomerRepository); } async createCustomer(customer: CustomerEntity): Promise<string> { customer.user = this.user.id; const savedCustomer = await this.customerRepository.create(customer); this.customer = savedCustomer; return customer.id; } }
内容的提问来源于stack exchange,提问作者monguz
相关产品推荐
相关产品推荐

