NestJS 基于接口注入自定义 TypeOrm 存储库

Posted

技术标签:

【中文标题】NestJS 基于接口注入自定义 TypeOrm 存储库【英文标题】:NestJS inject custom TypeOrm repository based on an Interface 【发布时间】:2021-01-07 08:16:35 【问题描述】:

我目前正在使用 TypeOrm 为 NestJS 完成数据库集成 docs。在这些文档中,有一些示例展示了如何使用 NestJS 中的 app.module 注入自定义数据库存储库。所有这些示例都使用自定义存储库的实际类型注入类。

@Injectable()
export class AuthorService 
  constructor(private authorRepository: AuthorRepository) 


此代码通过 app.modules 注入,提供如下导入:

@Module(
  imports: [TypeOrmModule.forFeature([AuthorRepository])],
  controller: [AuthorController],
  providers: [AuthorService],
)
export class AuthorModule 

如果您可以针对实现进行编程,这很有效,但我更喜欢在我的类中使用接口。我已经在之前的question 中找到了通过与 NestJS 的接口注入类的解决方案,但是当我尝试像这样注入我的自定义存储库时,它似乎没有正确实例化并且变得未定义。

(node:16658) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'save' of undefined

因此,我假设您只能通过 app.module 中的 forFeature() 调用注入 customRepositories,但据我所知,这不允许我使用接口进行注入。有没有其他方法可以注入自定义 TypeOrm 存储库,而无需替换所有接口以实现自定义存储库?提前致谢!

编辑

这是我当前的代码,我设法让它注入,但这仍然迫使我每次调用构造函数时都使用实现而不是接口。这主要是由于模拟而导致的测试问题。

  @CommandHandler(FooCommand)
export class FooHandler
  implements ICommandHandler<FooCommand> 

  private fooRepository: IFooRepository; // Using Interface as a private property.
  private barEventBus: IEventBus;
  
  constructor(fooRepository: FooRepository,
     barEventBus: EventBus)  // Forced to use implementation in constructor for injection.
    this.fooRepository = fooRepository;
    this.barEventBus = barEventBus;
  
@EntityRepository(FooEntity)
export class FooRepository extends Repository<FooEntity> implements IFooRepository 

  getFoo() 
    // Do stuff
  


@Module(
  imports: [TypeOrmModule.forRoot(), TypeOrmModule.forFeature([FooRepository]],

  // Other module setup
)
export class AppModule 

【问题讨论】:

为什么要将自定义存储库作为接口而不是类注入? 因为针对接口进行编程有助于保持我的代码分离。 forFeature() 注入迫使我在构造函数中使用实现,而我想保留该接口。 @Jordi 能否请您包含您尝试注入自定义存储库的代码,以便我们查看整个场景 我已经添加了我的代码。我让它与类实现一起工作,但如果可能的话,我仍然更愿意在我的构造函数类中使用接口注释。 【参考方案1】:

它应该与使用 InjectRepository 装饰器一起使用,您在其中指定存储库但随后您键入 is 作为您的界面,并且在测试时您只需提供 IFooRepository

示例代码:

  constructor(@InjectRepository(FooRepository) fooRepository: IFooRepository,
 barEventBus: EventBus)  

【讨论】:

以上是关于NestJS 基于接口注入自定义 TypeOrm 存储库的主要内容,如果未能解决你的问题,请参考以下文章

在 Nestjs 中注入 Tree Typeorm 存储库

如何将 NestJS 配置注入 TypeORM 实体?

如何将 NestJS 中的服务注入 typeorm 存储库?

Nest js 和 typeorm 自定义存储库问题

NestJS/TypeORM:无法读取未定义的属性“createQueryBuilder”

NestJS TypeORM InjectRepository 无法读取未定义的属性“原型”