Wednesday, 28 October 2020

NestJS inject custom TypeOrm repository based on an Interface

I'm currently working through the database integration docs for NestJS using TypeOrm. In these docs there are examples that show how to inject a custom database repository using the app.module from NestJS. All of these examples inject classes using the actual type of the custom repository.

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

This code is injected via the app.modules by providing a import like such:

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

This works well if you are fine with programming against an implementation, but I prefer to use an interface in my classes. I've already found the solution to injecting classes via an interface with NestJS in a previous question, but when I try to inject my custom repository like that, it doesn't seem to instanciate correctly and becomes undefined.

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

Because of this, I assume you can only inject customRepositories via the forFeature() call in the app.module, but that won't allow me to use interfaces for injection, as far as I know. Is there any other way I can inject a custom TypeOrm repository without having the replace all my interfaces for the implementation of my custom repository? Thanks in advance!

Edit

Here is my current code, I managed to get it to inject, but this still forces me to use the implementation instead of the interface each time I call the constructor. This is mainly an issue when testing due to mocking.

export class AuthorInviteHandler extends AbstractInviteHandler implements ICommandHandler<AuthorInviteCommand> {

  /**
   * Constructor
   * @param authorRepository 
   * @param eventBus 
   */
  constructor(authorRepository: AuthorRepository,
    eventBus: EventBus) 
  {
    super(authorRepository, eventBus)
  }
@Injectable()
export default abstract class AbstractInviteHandler {

  protected authorRepository: AuthorRepositoryInterface;
  protected eventBus: EventBus;

  /**
   * Constructor
   * @param authorRepository invite repository
   * @param eventBus eventbus
   */
  constructor(authorRepository: AuthorRepositoryInterface,
    eventBus: EventBus) {
    
    this.authorRepository = authorRepository;
    this.eventBus = eventBus;
  }
}


from NestJS inject custom TypeOrm repository based on an Interface

No comments:

Post a Comment