9
votes

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?

1

1 Answers

7
votes

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.