Typeorm + inversify for custom repositories

261 Views Asked by At

What would be the best way to inject custom repositories from typeorm using inversify. So far I came with 2 approaches:

Given a service that consumes a Repository:

@injectable()
export class EntityService {
  private readonly _repo: EntityRepository;
  constructor(@inject("entityRepo") repo: EntityRepository) {
    this._repo = repo;
  }
}

new class approach

Basically define a class that extends Repository:

@injectable()
export class EntityRepository extends Repository<Entity> {
  constructor(@inject("entityManager") em: EntityManager) {
    super(Entity, em);
  }
}

// inversify.config
container.bind<EntityRepository>("entityRepo").to(EntityRepository);

extend repository (with factory)

More to declare, but as explained in the docs:

export type EntityRepository = Repository<Entity> & {
  // custom operations declaration
}

export const repoFactory = (entityManager: EntityManager): EntityRepository => entityManager.getRepository(Entity).extend({
    // define operations
});


// inversify.config
container.bind<EntityRepository>("entityRepo").toConstantValue(repoFactory(myDS.manager));

The first solution seems more elegant and shorter, but this is what happens when I need to handle transactions:

handling transactions

@injectable()
export class EntityService {
  private readonly _repo: EntityRepository;
  // constructor
  doInTransaction() {
    return this._repo.manager.transaction((trManager) => {
      // only works with 'extend repository' method
      const repo: EntityRepository = trManager.withRepository(this._repo);

      // to work with 'new class', I have to do this
      const repo: EntityRepository = new EntityRepository(trManager);

      // all subsequent operations using 'repo' will be contained in a transaction.
    }
  }
}

What is the preferred approach?

Given these 2 solutions, which one is preferred? The first gives control over the instantiation of the repository, but the transactional issue means manually creating a new instance. The second option relies on a singleton (constant) repository.

0

There are 0 best solutions below