시작하기
커스텀 프로바이더는 다음과 같은 경우에 사용됩니다.
- Nest 프레임워크가 만들어주는 인스턴스 또는 캐시 된 인스턴스 대신 인스턴스를 직접 생성하고 싶은 경우
- 여러 클래스가 의존관계에 있을 때 이미 존재하는 클래스를 재사용하고자 할 때
- 테스트를 위해 모의 버전으로 프로바이더를 재정의하려는 경우
밸류 프로바이더
밸류 프로바이더는 provide와 useValue 속성을 가집니다.
useValue는 어떤 타입도 받을 수 있기 때문에 useValue 구문을 이용해 외부 라이브러리에서 프로바이더를 삽입하거나 실제 구현을 모의 객체로 대체할 수 있습니다.
@Module({
imports:[UsersModule],
providers: [{
provide:UsersService,
useValue:mockUserService
}],
exports: [AuthService],
})
export class AuthModule {}
provide에 UserService를 지정하여 type으로 사용하였고 실제 밸류는 mockUserService를 사용한 것입니다.
useValue에는 provide에 선언된 클래스와 동일한 인터페이스를 가진 리터럴 객체 또는 new로 생성한 인스턴스를 사용해야 합니다.
NestJS는 provide 속성을 injection token이라고 주석으로 기술하고 있고, 토큰으로 클래스 이름 외에 문자열, 심벌, Abstract, Function 인터페이스를 사용할 수 있습니다.
@Module({
controllers: [AuthController],
providers: [{
provide:'CONNECTION',
useValue:connection
}],
exports: [AuthService],
})
export class AuthModule {}
AuthRepository에서 데이터베이스에 연결하기 위해 Connection 객체를 임의의 문자열로 선언할 수 있습니다.
그리고 해당 프로바이더를 사용하는 AuthRepository에서 같은 토큰으로 주입받을 수 있습니다.
@Injectable()
export class AuthRepository{
constructor(@Inject('CONNECTION') connection: Connection)
}
클래스 프로바이더
클래스 프로바이더는 useClass 속성을 사용하며, 사용해야 할 인스턴스를 동적으로 구성할 수 있습니다.
const configServiceProvider = {
provide: ConfigService,
useClass:
process.env.NODE_ENV === 'dev'
? DevelopmentConfigService
: ProductionConfigService,
};
@Module({
providers: [configServiceProvider],
})
export class AuthModule {}
개발환경에 따른 ConfigService를 제공하도록 할 수 있습니다.
팩토리 프로바이더
팩토리 프로바이더 역시 프로바이더 인스턴스를 동적으로 구성하고자 할 때 사용하며 useFactory 속성을 사용하고 타입이 함수로 정의되어 있습니다.
원하는 인수와 리턴 타입으로 함수를 구성하면 됩니다.
const connectionFactory = {
provide: 'CONNECTION',
//주입받을 OptionProvider
useFactory: (optionProvider: OptionProvider) => {
const option = optionProvider.get();
return new DatabaseConnection(option);
},
//다시 선언
inject: [OptionProvider],
};
@Module({
providers: [connectionFactory],
})
export class AuthModule {}
함수를 수행하는 과정에서 다른 프로바이더를 주입받아 사용 가능합니다. 주의할 점은 주입받을 프로바이더를 inject 속성에 다시 선언해줘야 합니다.
커스텀 프로바이더 내보내기
다른 모듈에서 프로바이더를 사용하기 위해선 내보내기(export)를 해줘야 합니다.
커스텀 프로바이더는 토큰을 사용할 수도 있고, 프로바이더 객체를 사용할 수도 있습니다.
//'CONNECTION' 토큰 사용
const connectionFactory = {
provide: 'CONNECTION',
useFactory: (optionProvider: OptionProvider) => {
const option = optionProvider.get();
return new DatabaseConnection(option);
},
inject: [OptionProvider],
};
@Module({
providers: [connectionFactory],
exports: ['CONNECTION']
})
export class AuthModule {}
//connectionFactory 객체 사용
const connectionFactory = {
provide: 'CONNECTION',
useFactory: (optionProvider: OptionProvider) => {
const option = optionProvider.get();
return new DatabaseConnection(option);
},
inject: [OptionProvider],
};
@Module({
providers: [connectionFactory],
exports: [connectionFactory]
})
export class AuthModule {}
'Framework > NestJS' 카테고리의 다른 글
[NestJS] 스코프 (0) | 2023.05.04 |
---|