NestJS - 의존성 주입
NestJS - 의존성 주입이란
NestJS 의 핵심 중 하나는 바로 의존성 주입(Defendency Injection) 입니다.
의존성 주입(Defendency Injection)
의존성 주입은 제어의 역전(Inversion of Control) 의 기술중 하나입니다.
- 제어의 역전: 개발자가 제어해야할 영역을 프레임워크에게 믿고 맏기는 것.
- 의존성 주입: 개발자가 필요한 자원(클래스, 함수..)들을 외부에서 생성자를 통해 넣어준다.
위키피디아에 실려있는 5살에게 의존성을 설명하는 내용이 있어서 가져와봤습니다.링크
아이가 냉장고에서 스스로 물건을 꺼낼 때 문제가 발생할 수 있습니다.
문을 열어두거나 엄마나 아빠가 원하지 않는 것을 얻게 될 수도 있습니다.
냉장고에 있지 않거나 유통기한이 지난 것을 찾고 있을 수도 있습니다.
그렇다면 아이가 해야 할 일은 "어떤 점심과 함께 마실 것이 필요합니다."라고 정확한 요구 사항을 말하면,
아이의 부모님은 아이가 앉을 때 먹을 것이 있는지 확인합니다.
즉, 아이에게 냉장고 문을 열수 있는 능력을 주는 것이 아닌, 아이의 부모에게 그 일을 위임하여 맡기는 것과 같습니다.
NestJS 에서 의존성 주입하기
xxx.controller.ts
import { UserService } from './user.service';
export class UserController {
constructor(private userService: UserService) {}
@Get()
async findAll() {
return await this.userService.findAll();
}
}
xxx.service.ts
@Injectable()
export class UserService {
//...
async findAll() {
return this.usersRepository.findAll();
}
//...
}
우선 의존성 주입의 대상을 지정해줘야 하는데 간단합니다.
위의 service 코드 처럼 Injectable 데코레이터를 붙이면의존성 주입의 대상이 됩니다.
이것은 Provider 에 의한 주입대상이 된다는 것입니다.
그리고 의존성을 주입한 클래스를 사용하기 위해서는 아래 코드와 같이 해당 컨트롤러가 주입된 모듈 내(xxx.module.ts), providers 필드에 배열로 전달해야 합니다.
xxx.module.ts
@Module({
imports: [],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
이제 의존성을 주입만 하면 됩니다.
NestJS 에서는 생성자(Constructor) 를 통해 의존성을 주입할 수 있습니다.
constructor(private userService: UserService) {}
의존성을 주입했기에 userService
의 타입만 지정했을 뿐인데 UserService 의 메소드를 호출할 수 있는 것을 보실 수 있습니다.
이는 바로 userService 가 UserService 타입인 것을 NestJS framework 가 인지하고 가 알아서 처리해줍니다(클래스의 생성, 소멸 주기 등등...).
프로퍼티 스타일 주입
생성자를 통한 주입이 아닌, 클래스 필드의 형태로도 주입이 가능합니다.
필드 위에 Inject 데코레이더를 사용하면 됩니다
//...
@Inject()
private userService: UserService
//...
하지만 공식문서에서는 생성자를 이용한 의존성 주입을 권장한다고 합니다.