To do this you have to create an injection token for your interface and use the @Inject() decorator with the injection token when injecting your service. Then in your module you can declare which implementation to provide for that injection token.
Below is a simple greeting service interface and our injection token that will be used when registering our service as a provider.
greeting-service.interface.ts
// This will be our injection token.
export const GREETING_SERVICE = 'GREETING SERVICE';
export interface IGreetingService {
greet(name: string): Promise<string>;
}
A basic service that will implements our greeting interface...
professional-greeting.service.ts
import { Injectable } from '@nestjs/common';
import { IGreetingService } from './greeting-service.interface';
@Injectable()
export class ProfessionalGreetingService implements IGreetingService {
public async greet(name: string): Promise<string> {
return `Hello ${name}, how are you today?`;
}
}
And our greeting module where we register our service using the token...
greeting.module.ts
import { Module } from '@nestjs/common';
import { ProfessionalGreetingService } from './services/professional-greeting.service';
import { GREETING_SERVICE } from './services/greeting-service.interface';
import { GreetingController } from './controllers/greeting.controller';
@Module({
providers: [
{
// You can switch useClass to different implementation
useClass: ProfessionalGreetingService,
provide: GREETING_SERVICE
}
],
controllers: [
GreetingController
]
})
export class GreetingModule {}
Now when we inject our service, we can use the @Inject() decorator with our injection token. Whichever implementation you provived to useClass in our GreetingModule will be injected...
greeting.controller.ts
import { Controller, Get, Inject, Query } from '@nestjs/common';
import { GREETING_SERVICE, IGreetingService } from '../services/greeting-service.interface';
@Controller('greeting')
export class GreetingController {
constructor(
@Inject(GREETING_SERVICE)
private readonly _greetingService: IGreetingService
) {}
@Get()
public async getGreeting(@Query('name') name: string): Promise<string> {
return await this._greetingService.greet(name || 'John');
}
}
https://jasonwhite.xyz/posts/2020/10/20/nestjs-dependency-injection-decoupling-services-with-interfaces/
https://github.com/jmw5598/nestjs-di-decoupling-with-interfaces
https://docs.nestjs.com/fundamentals/custom-providers