1
votes

I would like to back my repositories with a request-scoped cache, similar to Hibernate's first-level-cache. I have a few ideas about how to do this, and my tie it in to typeorm-transactional-cls-hooked.

In the meantime, I created simple provider as follows:

@Injectable({ scope: Scope.REQUEST })
export class RequestScopedCache extends Object {

  private storage: any = {};

  public set(key: string, value: any) {
    this.storage[key] = value;
  }

  public get(key: string) {
    return this.storage[key];
  }
}

I wanted to inject it into my custom repository:

@Injectable()
@EntityRepository(Enqueued)
export class EnqueuedRepository extends Repository<Enqueued> {

  @Inject() readonly cache: RequestScopedCache;

  public async get(id: string) {
    const key = `${this.constructor.name}_${id}`;
    const result = this.cache.get(key);
    if (result) {
      return result;
    }
    const dbResult = await super.findOne(id);
    this.cache.set(key, dbResult);
    return dbResult;

  }

}

Neither constructor injection or property injection works on the custom repository. It looks like things have been wired-up so that a typeorm specific constructor (that seems to be private) gets called - the 1st parameter injected appears to be a connection.

So then I tried property injection, but that doesn't work either.

How can I inject my own config on a custom repository?

2

2 Answers

3
votes

Composition over inheritance, that is wrapping a repository, and using it as a provider can help here:

@Injectable()
export class EnqueuedRepository {
    @Inject() readonly cache: RequestScopedCache;

    constructor(
        @InjectRepository(Enqueued) private readonly enqueuedRepository: Repository<Enqueued>
    ) {
    }
}
0
votes

I am not sure if this is exactly relevant, but one possible approach of using custom repositories is as below : 1. I create a custom repository class as below

@Injectable()
@EntityRepository(UserEntity)
export class UserRepository extends Repository<UserEntity> {
 // You repo code here
 }
  1. Then inject it in the desired class as below
export class UserService {
 constructor(
   @InjectRepository(UserRepository)
   private userRepository: UserRepository,
 ) {}
// Your code here
}

The above approach helps to override default TypeORM functions and create customs ones as per your needs...