typeOrm 공부중 대체 useFactory가 뭔지 몰라서 헤매다가 이까지 왔음..
1. Providers
- Service, Repository, Factory, Helper 등등 대부분의 Nest 클래스는 Provider로 취급
- Provider는 Nest에서 의존성 주입이 가능
- Nest에는 Provider간의 관계를 담당하는 내장 IoC(제어역전) 컨테이너 존재 > @Injectable 데코레이터를 사용하여 Nest IoC 컨테이너에서 관리할 수 있는 클래스임을 선언, IoC가 뭔지는 이전 글 참고...
2. 자주 사용되는 Provider
1) value provider - useValue : provide로 제공되는 key 값이 useValue에 제공되는 value에 매칭
- 실제 구현을 모의 객체로 대체 > 테스트 목적
import { CatsService } from './cats.service';
const mockCatsService = {
/* mock implementation
...
*/
};
@Module({
imports: [CatsModule],
providers: [
{
provide: CatsService,
useValue: mockCatsService,
},
],
})
export class AppModule {}
- Nest 컨테이너에 외부 라이브러리를 삽입 : 프로바이더를 다음과 같이 정의 시 아래 방법들로 사용 가능
import { connection } from './connection';
@Module({
providers: [{
provide: 'CONNECTION',
useValue: connection,
}, {
provide: 'MASTER_NAME',
useValue: 'KGH'
}],
})
export class AppModule {}
// DI 방식
@Injectable()
export class CatsRepository {
constructor(@Inject('CONNECTION') connection: Connection) { }
}
// 단순 삽입
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
@Inject('MASTER_NAME') name: string;
}
- 상수 삽입 > provide에 들어갈 값을 constant.js에서 미리 정해두어 사용
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [
AppService,
{
provide: 'PORT',
useValue: 3000
}
],
})
export class AppModule {}
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const port = app.get('PORT')
console.log(port) // -> 3000
await app.listen(port);
}
bootstrap();
2) value provider - useClass : 객체(provider, guard 등)을 재정의할 인스턴스를 제공하기 위해 인스턴스화될 클래스 제공
- 토큰이 확인하는 클래스를 동적으로 결정
- 객체 재정의
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_GUARD,
useClass: RolesGuard,
},
],
})
export class AppModule {}
- 변수나 개발환경에 따른 제공 인스턴스 변경
const configServiceProvider = {
provide: ConfigService,
useClass:
process.env.NODE_ENV === 'development'
? DevelopmentConfigService
: ProductionConfigService,
};
@Module({
providers: [configServiceProvider],
})
export class AppModule {}
3) value porvider - useFactory : 객체를 재정의할 인스턴스를 제공하기 위해 인스턴스화 될 클래스 제공
- 동적으로 provider 생성 가능 ( 그러니까, useClass는 사용함으로써 동적으로 주입하는건데, useFactory는 처음부터 동적인 객체를 넣을 수 있음)
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mysql',
host: configService.get('HOST'),
port: configService.get<number>('PORT'),
username: configService.get('USERNAME'),
password: configService.get('PASSWORD'),
database: configService.get('DATABASE'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
inject: [ConfigService],
});
- async/await을 사용하여 db 연결 등의 비동기 작업에 대한 DI 가능
{
provide: 'ASYNC_CONNECTION',
useFactory: async () => {
const connection = await createConnection(options);
return connection;
},
}
- 인수를 받고 함수로 값을 만드는 것도 가능
'TIL' 카테고리의 다른 글
TIL 240702 - 의존성 주입 문제 해결 (0) | 2024.07.02 |
---|---|
TIL 240701 - javascript/typescript에서 날짜 한국표준시각으로 변경 (0) | 2024.07.01 |
TIL 240627 - TypeORM 적용 (0) | 2024.06.27 |
TIL 240626 - 면접 예상질문 및 답변 모음 (공개모의면접 진행) (0) | 2024.06.26 |
TIL 240625 - Nest.js란? 간단한 코드 해부하기 (0) | 2024.06.25 |