There is the following standard NestJS code:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
Also there is the code for module app:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I don't understand how app understands that app controller expects to get app service as the first argument? At first I thought that app just looks at providers array and put all services from this array in controller's constructor. But I could change the code in this way:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, NewService],
})
export class AppModule {}
Now I can use this NewService not only in AppController class, but in AppService class. How app knows that now I could use NewService in AppService class? Now I don't understand how we could do it, because TypeScript is just syntax sugar and exists only until compilation will be done and as I know app couldn't look at type of argument in AppService (for example fileService: FileService) and put the right service as argument when AppService will be created. I need technical details under the cover of this mechanism, not only use cases from official tutorial.
By registering it in the providers array you register it to the Nest IoC container.
If you check compiled js code, then you will find something like
WeatherHttpProvider = __decorate([
(0, common_1.Injectable)(),
__param(1, (0, common_1.Inject)(weather_parser_1.WEATHER_PARSER)),
__metadata("design:paramtypes", [axios_1.HttpService, Object])
], WeatherHttpProvider);
which in this case tells the WeatherHttpProvider about injected constructor params. This way it knows which class from the IoC container to use.