Reputation: 825
I have a UserRepository
which handles creating/authenticating users infront of the database. I want to perform hashing & validation for the user's password, so I created a seperate service for that purpose, trying to follow single repsonsibility principle, which is declared like this:
@Injectable()
export default class HashService
And I import it in my module:
@Module({
imports: [TypeOrmModule.forFeature([UserRepository])],
controllers: [AuthController],
providers: [AuthService, HashService],
})
export class AuthModule {}
I wish to inject it into UserRepository
, I tried passing in it as a constructor parameter but it didn't work because it's base class already accepts 2 parameters there, so I tried injecting my service after them like so:
@EntityRepository(User)
export default class UserRepository extends Repository<User> {
constructor(
entityManager: EntityManager,
entityMetadata: EntityMetadata,
@Inject() private readonly hashService: HashService,
) {
super();
}
// Logic...
}
But hashService
was undefined, I also tried without the @Inject()
decorator.
What would be the best way to inject HashService
into my repository? Do I have to create a new instance of it?
Upvotes: 13
Views: 12199
Reputation: 1454
You can add it manually from the module service like this:
askers.service.ts:
constructor(
@InjectRepository(AskersRepository)
private repository: AskersRepository,
private logger: LoggingService,
) {
this.repository.logger = logger;
}
askers.repository.ts:
logger: LoggingService;
And then the logger service will be available in the repository like it has been injected.
Here is an article I wrote about the hacking of injecting a service with request scope into TypeORM (© to me.. - 😉)
Upvotes: 1
Reputation: 433
You may also assign an instance of particular service from main service that instantiate the repository.
i.e.
A. catalog.service.ts
@Injectable()
export class CatalogService {
constructor (
private readonly cacheService: CacheService,
public readonly catalogRepository: CatalogRepository
) {
this.catalogRepository.cacheService = this.cacheService;
}
}
B. catalog.repository.ts
@EntityRepository(CatalogEntity)
export class CatalogRepository extends Repository<CatalogEntity> {
cacheService: CacheService;
cacheExpirySeconds = 60*60;
}
Upvotes: 0
Reputation: 70151
Short answer: you don't.
TypeORM's custom repositories, repository classes, and entities are technically outside of Nest's DI system, so it's not possible to inject any values into them. If you really want to go about it, you can figure out what a Repository
class requires for it's constructor parameters and add them to a factory to instantiate the repository class and use it directly instead of via the TypeOrmModule.forFeature
, but that's quite a bit of extra work.
In my opinion, the custom repository pattern doesn't help too much in Nest, as services essentially hold the logic that the CustomRepository
would. The repository classes are your gateway to the database, but don't need any extra logic added to them.
Upvotes: 13