Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you inject a service in NestJS into a typeorm repository?

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?

like image 392
DaCurse Avatar asked Feb 22 '20 00:02

DaCurse


People also ask

What is inject in NestJS?

Dependency injection is an inversion of control (IoC) technique wherein you delegate instantiation of dependencies to the IoC container (in our case, the NestJS runtime system), instead of doing it in your own code imperatively.

What is repository in NestJS?

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer. —

What is TypeORM in NestJS?

TypeORM Integration. For integrating with SQL and NoSQL databases, Nest provides the @nestjs/typeorm package. Nest uses TypeORM because it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.


Video Answer


2 Answers

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.

like image 78
Jay McDoniel Avatar answered Oct 19 '22 08:10

Jay McDoniel


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.. - 😉)

like image 32
Israel Avatar answered Oct 19 '22 07:10

Israel