최근 DDD 개발을 진행중에 있는데 생각보다 이 개념을 디테일하게 설명해주는 글을 찾기 쉽지 않고 사용법을 제대로 알지 못하고 그냥 복사 붙이기해서 사용하는 사람들이 있어서 작성하게 됐다!
NestJS에서 useClass
, useFactory
, useValue
의 차이와 용도
NestJS에서 의존성 주입(Dependency Injection)을 위해 제공하는 useClass
, useFactory
, useValue
는 providers
설정에서 사용되는 여러 방법들이다. 각각의 방법은 서비스나 값을 주입하기 위해 사용하는 방식이 조금씩 다르다. 이들이 어떻게 다른지와 각자의 용도를 설명하고, 실제로 사용되는 방법까지 예시를 통해 알아보자!
1. useClass
사용 예시
useClass
는 특정 클래스를 주입하고, 다른 클래스나 서비스에서 이를 주입받아 사용하는 방법입니다. 아래 예시에서 LoggerService
대신 CustomLoggerService
를 주입하고 사용합니다.
코드 예시
서비스 정의 (logger.service.ts
)
export class LoggerService {
log(message: string) {
console.log('Log:', message);
}
}
export class CustomLoggerService {
log(message: string) {
console.log('Custom Log:', message);
}
}
모듈 설정 (app.module.ts
)
import { Module } from '@nestjs/common';
import { LoggerService, CustomLoggerService } from './logger.service';
import { AppService } from './app.service';
@Module({
providers: [
AppService,
{
provide: LoggerService,
useClass: CustomLoggerService, // LoggerService 대신 CustomLoggerService를 주입
},
],
})
export class AppModule {}
서비스 사용 (app.service.ts
)
import { Injectable } from '@nestjs/common';
import { LoggerService } from './logger.service';
@Injectable()
export class AppService {
constructor(private readonly logger: LoggerService) {}
performTask() {
this.logger.log('Performing a task'); // CustomLoggerService의 log 메서드가 호출됨
}
}
실행 시 로그 출력
Custom Log: Performing a task
AppService
에서LoggerService
를 주입받고 있지만, 실제로는CustomLoggerService
의 인스턴스가 주입되기 때문에Custom Log: Performing a task
가 출력됩니다.
2. useFactory
사용 예시
useFactory
는 동적으로 의존성을 생성하여 주입하는 방법입니다. 이 방법을 통해 의존성을 생성할 때 환경 변수나 외부 설정에 따라 다르게 처리할 수 있습니다.
코드 예시
서비스 정의 (logger.service.ts
)
export class LoggerService {
constructor(private readonly prefix: string) {}
log(message: string) {
console.log(`${this.prefix}: ${message}`);
}
}
모듈 설정 (app.module.ts
)
import { Module } from '@nestjs/common';
import { LoggerService } from './logger.service';
import { AppService } from './app.service';
@Module({
providers: [
AppService,
{
provide: LoggerService,
useFactory: () => {
const prefix = process.env.LOG_PREFIX || 'DefaultPrefix';
return new LoggerService(prefix); // 동적으로 LoggerService 인스턴스 생성
},
},
],
})
export class AppModule {}
서비스 사용 (app.service.ts
)
import { Injectable } from '@nestjs/common';
import { LoggerService } from './logger.service';
@Injectable()
export class AppService {
constructor(private readonly logger: LoggerService) {}
performTask() {
this.logger.log('Performing a task'); // 환경 변수에 따라 다른 prefix가 사용됨
}
}
실행 시 로그 출력 (환경 변수 LOG_PREFIX
에 따라 다름)
DefaultPrefix: Performing a task
- 만약 환경 변수
LOG_PREFIX
가 설정되지 않았다면, 기본값인"DefaultPrefix"
가 사용됩니다. useFactory
를 통해 동적으로 인스턴스를 생성하면서, 설정에 따라 로그의 접두사를 달리합니다.
3. useValue
사용 예시
useValue
는 특정 값이나 객체를 직접 제공하여 주입하는 방법입니다. 주로 상수, 설정 객체 또는 테스트용 Mock 객체를 주입할 때 사용됩니다.
코드 예시
Mock 객체 정의
const MOCK_LOGGER = {
log: (message: string) => console.log('Mock Log:', message),
};
모듈 설정 (app.module.ts
)
import { Module } from '@nestjs/common';
import { AppService } from './app.service';
@Module({
providers: [
AppService,
{
provide: 'LoggerService',
useValue: MOCK_LOGGER, // 특정 값(객체)을 직접 제공
},
],
})
export class AppModule {}
서비스 사용 (app.service.ts
)
import { Injectable, Inject } from '@nestjs/common';
@Injectable()
export class AppService {
constructor(
@Inject('LoggerService') private readonly logger: { log: (message: string) => void },
) {}
performTask() {
this.logger.log('Performing a task'); // MOCK_LOGGER의 log 메서드 호출
}
}
실행 시 로그 출력
Mock Log: Performing a task
MOCK_LOGGER
객체가LoggerService
로 제공되었기 때문에,Mock Log: Performing a task
가 출력됩니다.- 테스트 환경이나 간단한 상수 제공에 유용하게 사용됩니다.
요약
제공 방식 | 설명 | 사용 예시 | 사용 결과 |
---|---|---|---|
useClass |
특정 클래스를 사용하여 의존성 주입 | useClass: CustomLoggerService |
요청한 클래스 대신 CustomLoggerService 가 주입됨 |
useFactory |
팩토리 함수로 동적 생성 및 설정 | useFactory: () => new LoggerService |
환경 변수 등 설정에 따라 동적으로 인스턴스 생성 |
useValue |
특정 값이나 객체를 직접 주입 | useValue: MOCK_LOGGER |
고정된 값 또는 Mock 객체가 주입됨 |
'개발 > NestJS' 카테고리의 다른 글
[NestJS] TypeORM Pagination: 설치, 사용법, 직접 구현과의 비교 with nestjs-paginate (1) | 2024.11.05 |
---|---|
TypeORM 트랜잭션: typeorm-transactional 사용 전후 비교 (0) | 2024.10.29 |
[NestJS] CORS default의 함정 (0) | 2024.03.10 |
[NestJS] swagger 보안(잠금) (0) | 2023.04.24 |
SQL injection(Feat. TypeORM) (0) | 2023.02.15 |
댓글