https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens
nestjs는 custom provider을 통해 4가지의 공급 타입을 제공한다.
- useValue: 상수 값이나 외부 라이브러리를 주입할 때 사용한다.
- useClass: 클래스를 주입할 때 사용한다.
- useFactory: 공급자를 동적으로 제공할 때 사용한다. 주입하는 내용은 팩토리에서 반환한 값을 기반으로 하며, inject 배열에 useFactory 파라미터에 넘길 값을 순서대로 제공해야 한다.
- useExisting: 기존 공급자에 대한 별칭을 만들어, 공급자에 접근하는 다른 방법을 제공한다.
DI container는 각 공급자를 식별하고 의존성을 요청하는 위치에 대해 알맞은 의존성을 삽입해야 하는데, 위 제시된 프로퍼티만으로는 적절한 공급자를 적절한 자리에 전달해주기 어렵다. 따라서 각 공급자들을 구분하기 위한 속성인 provide를 두고 있는데, 이를 nestjs에서는 DI token이라고 부른다.
DI token은 각 공급자를 식별하는데 사용하는 토큰이다. 공식 문서에 따르면 토큰은 다음 자료형이 될 수 있다.
- 클래스
- 문자열
- 심볼(Symbol)
- typescript 열거형
표준 공급자를 사용하는 경우 의존성을 주입할 때 클래스만 넘기는데, 이는 provide 및 useClass 속성에 동일한 클래스를 지정한 방식과 동일하다. 요약하면 nestjs의 공급자는 DI token과 공급 방식을 정의해야 한다고 볼 수 있다.
providers: [
AppService,
{
provide: MessagesService,
useValue: mockupMessagesService
},
// MessagesService,
{
provide: 'MSG_REPO',
useClass: MessageRepository
}
]
위 제시된 MessageRepository의 경우 'MSG_REPO' 라는 문자열을 토큰으로 사용하고 있다. 이를 통해 AppModule에서 MessageRepository 클래스 인스턴스를 해당 토큰으로 가져올 수 있다.
@Injectable()
export class MessagesService {
constructor(@Inject('MSG_REPO') private messageRepo: Repository) {
console.log("Message Service Created")
}
의존성을 주입할 필드에 @Inject(token) 데코레이터를 적용하여 내가 가져오고 싶은 공급자가 무엇인지 명시할 수 있다. 원래대로라면 타입스크립트가 컴파일 되는 과정에서 타입 정보 등이 모두 제거되어야 하지만, reflect-metadata 라이브러리 덕분에 데코레이터가 추가적인 정보를 자바스크립트 수준에 남길 수 있으므로 실제 코드가 실행되는 자바스크립트 환경에서 각 의존성을 구분하여 공급자를 주입할 수 있다.
DI 토큰이 식별의 역할을 수행한다는 점에서 내부 공급자를 외부로 공개하는 경우에도 DI 토큰을 이용한다. nestjs의 모듈의 providers에 등록된 공급자들은 기본적으로 해당 모듈 내부에서만 사용할 수 있다. 모듈 외부로 특정 공급자를 노출하고 싶다면 DI 토큰을 exports 배열에 등록한다.
@Module({
providers: [
{
provide: POWER_SERVICE,
useClass: PowerService,
},
],
exports: [POWER_SERVICE], // 외부에서 접근하도록 명시적으로 exports에 등록
})
export class PowerModule {}
결론
nestjs는 공급자를 구분하기 위해 DI token을 이용한다. custom provider 기준 provide에 지정하는 값으로, @Inject 데코레이터에 전달하여 DI 컨테이너가 의존성을 주입할 위치를 식별할 수 있게 한다.
기본적으로 providers에 등록된 제공자들은 모듈 내에서만 이용 가능하므로, 타 모듈에 정의된 의존성을 주입하고 싶다면 imports 배열에 해당 제공자의 DI 토큰을 넘겨서 외부에서 사용할 수 있게 만들어야 한다.
'javascript > 이외' 카테고리의 다른 글
[javascript] Ajv 라이브러리 (0) | 2023.09.25 |
---|---|
[jest] 동일 파일 내의 함수 mocking하기 (0) | 2023.08.23 |
mermaid.js - 프론트엔드에서 UML을 그리는 라이브러리 (0) | 2023.02.02 |
node redis : 노드 환경에서 사용하는 redis 데이터베이스 (0) | 2022.03.06 |
jest - 자바스크립트 테스팅 프레임워크 (0) | 2021.09.28 |