2026. 5. 11.·base·
NestJS의 useFactory
NestJS DI
DI 컨테이너는 기본적으로 토큰(token) -> 값(value) 매핑을 관리하고 그 value엔 다양한 종류가 할당될 수 있다.
가장 흔하게는 클래스 인스턴스가 있겠고, Redis클라이언트나 DB 커넥션같은 외부 라이브러리 객체도 가능하다.
useFactory는 Nest에서 Provider를 등록할 때, 내가 작성한 팩토리 함수가 값을 만들어서 DI 컨테이너에 등록하도록 하는 방식이다. 따라서 컨테이너에 저장되는 값은 팩토리 함수의 반환 값으로 이건 클래스 인스턴스일 수도 있고, 그냥 객체나 상수일 수도 있다.
{ provide: REDIS_CLIENT, useFactory: () => new Redis(...) } // 외부 객체
{ provide: 'CONFIG', useFactory: () => ({ a: 1, b: 2 }) } // plain objectuseFactory를 통한 provider 등록을 보통 다음과 같은 구조를 따른다. 이때 inject에 적은 의존성들은 Nest가 먼저 준비해 useFactory에 인자로 넣어주게된다.
{
provide: SOME_TOKEN,
inject: [A, B],
useFactory: (a: A, b: B) => {
// 여기서 생성/조립/선택한 값을 return
return something;
},
}useFactory는 주로 외부 라이브러리나 SDK, 클라이언트 인스턴스를 생성할 때 대표적으로 사용된다.
Redis나 DB 커넥션, AWS SDK 클라이언트처럼 Nest가 자동으로 생성할 수 없는 객체를 만들 때, 특히 생성 시점에 host, port, timout같은 옵션을 환경에 따라 다른 값으로 설정해야할 때 쓰인다.
그 외에도 환경변수값 기반으로 인스턴스를 생성할 때나 조건에 따라 다른 구현을 주입해야할 때도 마찬가지로 사용가능하다.
useClass와의 차이점
의존성 주입에 가장 많이 쓰이는 useClass는 내가 선언한 클래스를 Nest가 알아서 new 생성자로 인스턴스를 만들어서 DI로 주입하는 형태다. useFactory는 내가 작성한 팩토리함수가 생성을 책임지기 때문에 이 부분이 가장 큰 차이점이라고 볼 수 있다.
// cache.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class CacheService {
get(key: string) { /* ... */ }
}// app.module.ts
import { Module } from '@nestjs/common';
import { CacheService } from './cache.service';
@Module({
providers: [CacheService], // 사실상 { provide: CacheService, useClass: CacheService } 축약
exports: [CacheService],
})
export class AppModule {}// any.service.ts
constructor(private readonly cacheService: CacheService) {}Join the thread
Leave feedback, ask for clarification, or keep a focused discussion attached to this article.