import { Injectable, Module } from ‘@nestjs/common’; import { CoffeesController } from ‘./coffees.controller’; import { CoffeesService } from ‘./coffees.service’; import { TypeOrmModule } from ‘@nestjs/typeorm’; import { Coffee } from ‘./entities/coffee.entity’; import { Flavor } from ‘./entities/flavor.entity’; import { Event } from ‘src/events/entities/event.entity’; import { COFFEE_BRANDS } from ‘./coffees.constants’;

@Injectable() export class CoffeeBrandsFactory { create() { return [‘buddy brew’, ‘nescafe’]; } }

@Module({ imports: [TypeOrmModule.forFeature([Coffee, Flavor, Event])], controllers: [CoffeesController], providers: [ CoffeesService, { provide: COFFEE_BRANDS, useFactory: (brandsFactory: CoffeeBrandsFactory) brandsFactory.create(), inject: [CoffeeBrandsFactory], }, ], exports: [CoffeesService], }) export class CoffeesModule {}

CoffeeBrandsFactory, useFactory, inject 가 뭐를 하는건지 알려줘.

편집

이 코드에서 CoffeeBrandsFactoryuseFactoryinject는 NestJS의 의존성 주입(Dependency Injection) 시스템에서 팩토리 패턴을 구현하는 요소들입니다.

CoffeeBrandsFactory

typescript

@Injectable()
export class CoffeeBrandsFactory {
  create() {
    return ['buddy brew', 'nescafe'];
  }
}
  • @Injectable() 데코레이터가 붙은 클래스로, DI 컨테이너에서 관리되는 서비스입니다
  • create() 메서드를 통해 커피 브랜드 배열을 생성하는 팩토리 역할을 합니다
  • 복잡한 객체 생성 로직이나 동적 값 생성이 필요할 때 사용됩니다

useFactory

typescript

{
  provide: COFFEE_BRANDS,
  useFactory: (brandsFactory: CoffeeBrandsFactory) => brandsFactory.create(),
  inject: [CoffeeBrandsFactory],
}
  • NestJS에서 커스텀 프로바이더를 정의하는 방법 중 하나입니다
  • useFactory는 함수를 실행해서 그 결과값을 프로바이더로 제공합니다
  • 여기서는 CoffeeBrandsFactory의 create() 메서드를 호출한 결과인 ['buddy brew', 'nescafe'] 배열을 COFFEE_BRANDS 토큰에 바인딩합니다

inject

  • useFactory 함수가 실행될 때 필요한 의존성들을 주입받기 위해 사용됩니다
  • [CoffeeBrandsFactory]를 지정했으므로, 팩토리 함수의 첫 번째 매개변수로 CoffeeBrandsFactory 인스턴스가 주입됩니다

전체 동작 흐름

  1. CoffeeBrandsFactory가 DI 컨테이너에 등록됩니다
  2. COFFEE_BRANDS 프로바이더가 생성될 때, CoffeeBrandsFactory를 주입받습니다
  3. useFactory 함수가 실행되어 brandsFactory.create()를 호출합니다
  4. 결과적으로 COFFEE_BRANDS 토큰에는 ['buddy brew', 'nescafe'] 배열이 바인딩됩니다

이렇게 하면 다른 서비스에서 @Inject(COFFEE_BRANDS)를 통해 이 배열을 주입받아 사용할 수 있습니다.

  • 25/07/2025, 9:25:18 am LOG [NestFactory] Starting Nest application… [Nest] 12428 - 25/07/2025, 9:25:18 am LOG [InstanceLoader] TypeOrmModule dependencies initialized +44ms [Nest] 12428 - 25/07/2025, 9:25:18 am ERROR [ExceptionHandler] UnknownDependenciesException [Error]: Nest can’t resolve dependencies of the COFFEE_BRANDS (?). Please make sure that the argument CoffeeBrandsFactory at index [0] is available in the CoffeesModule context. Potential solutions:
  • Is CoffeesModule a valid NestJS module?
  • If CoffeeBrandsFactory is a provider, is it part of the current CoffeesModule?
  • If CoffeeBrandsFactory is exported from a separate @Module, is that module imported within CoffeesModule? @Module({ imports: [ /* the Module containing CoffeeBrandsFactory */ ] }) at Injector.lookupComponentInParentModules (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:262:19) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Injector.resolveComponentInstance (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:215:33) at async resolveParam (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:129:38) at async Promise.all (index 0) at async Injector.resolveConstructorParams (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:144:27) at async Injector.loadInstance (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:70:13) at async Injector.loadProvider (C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\injector.js:98:9) at async C:\Users\USER\dev\NestJS_Learning_Repository\nestjs-fundamentals\ilovecoffee\node_modules.pnpm@nestjs+core@11.1.3_@nestjs_f00a9328469ae70f8dd89f51e4455422\node_modules@nestjs\core\injector\instance-loader.js:56:13 at async Promise.all (index 4)

왜 이런 에러가 나는거야 근데?

편집

에러가 발생하는 이유는 CoffeeBrandsFactory가 providers 배열에 등록되지 않았기 때문입니다.

현재 코드를 보면:

typescript

@Module({
  imports: [TypeOrmModule.forFeature([Coffee, Flavor, Event])],
  controllers: [CoffeesController],
  providers: [
    CoffeesService,
    {
      provide: COFFEE_BRANDS,
      useFactory: (brandsFactory: CoffeeBrandsFactory) =>
        brandsFactory.create(),
      inject: [CoffeeBrandsFactory], // 여기서 CoffeeBrandsFactory를 주입받으려고 하는데
    },
  ],
  exports: [CoffeesService],
})

inject: [CoffeeBrandsFactory]에서 CoffeeBrandsFactory를 주입받으려고 하지만, CoffeeBrandsFactory 자체가 providers 배열에 등록되어 있지 않습니다.

해결방법

providers 배열에 CoffeeBrandsFactory를 추가해야 합니다:

typescript

@Module({
  imports: [TypeOrmModule.forFeature([Coffee, Flavor, Event])],
  controllers: [CoffeesController],
  providers: [
    CoffeesService,
    CoffeeBrandsFactory, // 👈 이것을 추가해야 합니다!
    {
      provide: COFFEE_BRANDS,
      useFactory: (brandsFactory: CoffeeBrandsFactory) =>
        brandsFactory.create(),
      inject: [CoffeeBrandsFactory],
    },
  ],
  exports: [CoffeesService],
})
export class CoffeesModule {}

왜 이런 일이 발생하나요?

NestJS의 의존성 주입 시스템에서는:

  1. 클래스에 @Injectable() 데코레이터가 있어도
  2. 해당 모듈의 providers 배열에 등록되지 않으면
  3. DI 컨테이너가 그 클래스의 인스턴스를 생성하거나 주입할 수 없습니다

따라서 useFactory에서 CoffeeBrandsFactory를 주입받으려면, 먼저 CoffeeBrandsFactory가 같은 모듈의 프로바이더로 등록되어 있어야 합니다.

내가 첨부했던 로그의 어느 부분을 보면 provider 가 누락되었다고 판단이 될지 집어주라

편집

로그에서 이 부분을 보면 provider가 누락되었다고 판단할 수 있습니다:

ERROR [ExceptionHandler] UnknownDependenciesException [Error]: Nest can't resolve dependencies of the COFFEE_BRANDS (?). Please make sure that the argument CoffeeBrandsFactory at index [0] is available in the CoffeesModule context.

Potential solutions:
- Is CoffeesModule a valid NestJS module?
- If CoffeeBrandsFactory is a provider, is it part of the current CoffeesModule?  👈 이 부분!
- If CoffeeBrandsFactory is exported from a separate @Module, is that module imported within CoffeesModule?

특히 “Please make sure that the argument CoffeeBrandsFactory at index [0] is available in the CoffeesModule context” 이 부분이 핵심입니다.

이 메시지는:

  • COFFEE_BRANDS 프로바이더를 생성하려고 할 때
  • inject: [CoffeeBrandsFactory]의 첫 번째 인덱스([0])에 있는 CoffeeBrandsFactory를 찾을 수 없다는 의미입니다
  • “CoffeesModule context에서 사용할 수 없다”는 것은 해당 모듈의 providers 배열에 등록되지 않았다는 뜻입니다

그리고 NestJS가 친절하게 제공하는 **“Potential solutions”**의 두 번째 항목인 **“If CoffeeBrandsFactory is a provider, is it part of the current CoffeesModule?”**이 정확히 이 문제를 지적하고 있습니다.