공식문서 파트
https://docs.nestjs.com/fundamentals/custom-providers
providers는 의존성 주입을 통해 다른 클래스에 주입될 수 있는 클래스이다.
- Class Provider
- Value Provider
- Factory Provider
src/app.module의 providers 배열을 보자.
축약 표기법
providers: [AppService]
위 구문은 사실 축약형이고, 아래와 같이 명시적으로 작성할 수 있다.
명시적 표기법
providers: [
{
provide: AppService, // token
useClass: AppService, // class
},
provide
- provider를 등록할 때 제공되는 토큰이고, 일종의 식별자로 사용된다.
- 의존성 주입시 이 토큰을 기준으로 provider를 검색하게 된다.
useClass
- 의존성을 제공하는 클래스를 지정
- 여기 사용된 클래스의 인스턴스가 의존성으로 주입된다.
축약형은 이 토큰과 클래스가 동일한 이름으로 지정되는 일반적인 경우를 반영한 표기법인 것이다.
이제 이 class provider를 custom provider로 적용해보자.
custom provider를 사용하기 위해 먼저, 새로운 service를 생성한다.
그리고 useClass를 새로운 service로 변경한다.
src/app.module
@Module({
...
providers: [
{
provide: AppService,
useClass: AppJapanService,
}
]
provide(token)은 기존 서비스 토큰이고,
의존성 주입은 새로 생성한 service 클래스로 지정했다.
이렇게 되면, 이미 AppService를 주입받고 있던 app.Controller가 의존성을 주입받는 클래스가 AppJapanService가 되는 것이다.
그러면, app.Controller에서는 AppJapanService의 메소드를 실행한다.
두 번째로 Value Providers가 있다.
앞서 class providers는 class를 의존성으로 주입했다면, value providers는 값을 의존성으로 주입하는 것이다.
useValue
- 의존성 주입에 사용할 값을 직접 제공한다.
위의 코드에서 provider를 추가해보자.
src/app.module
@Module({
...
providers: [
{
provide: AppService,
useClass: AppJapanService,
},
{
provide: 'APP_NAME',
useValue: 'Nest Events Backend!'
}
]
token으로 'APP_NAME', 그리고 useValue에 'Nest Events Backend!'를 값으로 줬다.
그리고 Service 클래스에 이 값을 주입한다.
src/app.japan.service
import { Inject, Injectable } from '@nestjs/common';
@Injectable()
export class AppJapanService {
constructor(
@Inject('APP_NAME')
private readonly name: string
) { }
getHello(): string {
return `こんにちは世界! from ${this.name}`;
}
}
결과값은 다음과 같다.
こんにちは世界! from Nest Events Backend!
이로써 value provider로 custom한 provider의 값을 잘 주입받아온 것을 확인할 수 있다.
Factory Providers는 의존성 주입에 사용할 객체를 생성하는 팩토리 함수를 지정한다.
특정 이름의 provider를 반환하거나 팩토리 함수 그 자체로 의존성 주입에 사용될 수 있다.
inject
- useFactory와 함께 사용되는 옵션으로, useFactory에서 사용할 다른 providers를 지정할 수 있다.
- inject에는 배열로 의존성으로 주입받을 provider의 토큰을 지정한다.
useFactory
- 의존성 주입에 사용할 객체를 생성하는 팩토리 함수를 지정한다.
src/app.dummy.ts
export class AppDummy {
public dummy(): string {
return 'dummy';
},
}
dummy()라는 하나의 메소드를 가진 클래스를 작성한다.
src/app.module.ts
{
provide: 'MESSAGE',
inject: [AppDummy],
useFactory: (app) => `${app.dummy()} Factory!`,
},
AppDummy,
]
이제 Service 클래스에 'MESSAGE'를 주입받아 실행시켜서, dummy Factory! 값이 잘 출력될지 적용해보자.
src/app.japan.service.ts
import { Inject, Injectable } from '@nestjs/common';
@Injectable()
export class AppJapanService {
// 의존성 주입
constructor(
@Inject('APP_NAME')
private readonly name: string,
@Inject('MESSAGE')
private readonly message: string,
) {}
getHello(): string {
return `こんにちは世界! from ${this.name}, ${this.message}`;
}
}
결과값은 다음과 같다.
こんにちは世界! from Nest Events Backend!, dummy Factory!
이 글은 제게 많은 도움이 되었습니다.