핵심은 **“직접 생성하여 의존관계를 직접 생성하지 않는다는 것”**이다. NestJS에서는 프로바이더들을 위한 컨테이너인 모듈를 기반하여 개체를 런타임에 생성하여 DI를 처리한다.
아래 코드를 보면 세 가지 단계로 나눌 수 있다.
// cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
// cats.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './cat.interface';
import { CreateCatDto } from './create-cat.dto';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Post()
create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
@Get()
findAll(): Cat[] {
return this.catsService.findAll();
}
}
// cats.service.ts
import { Injectable } from '@nestjs/common';
import { Cat } from './cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
// cat.interface.ts
export interface Cat {
name: string;
age: number;
breed: string;
}
// create-cat.dto.ts
export class CreateCatDto {
readonly name: string;
readonly age: number;
readonly breed: string;
}
모듈에 등록한 프로바이더를 직접 생성하지 않아 눈에 보이지 않기 때문에 IoC가 되었는지 안 되었는지 판별하기 어렵다.
그렇다면 이런 상황이라면 어떨까. CatController가 Tiger에 대한 비즈니스 로직을 사용하고 싶다면??
코드는 아래와 같다.
TigerService
@Injectable()
export class TigerService {
private readonly tigers: Tiger[] = [];
create(tiger: Tiger) {
this.tigers.push(tiger);
}
findAll(): Tiger[] {
return this.tigers;
}
}
TigerModule
@Module({
providers: [TigerService],
})
export class TigersModule {}
CatModule
@Module({
imports: [TigersModule],
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}