Nest.js - Provider

김세겸·2023년 2월 24일
0

NestJS

목록 보기
6/18
post-thumbnail

프로바이더란?

앱이 제공하고자 하는 핵심 기능, 즉 비즈니스 로직을 수행하는 역할을 한다.

  1. 프로바이더는 서비스, 저장소, 팩터리, 헬퍼등 여러가지 형태로 구현이 가능하다.
  2. 프로바이더는 @Injectable() 데코레이터를 활용하여 선언한다.
  3. 프로바이더의 핵심은 의존성으 주입 할 수 있다는 것이다.
  4. 즉 컨트롤러는 프로바이더에서 의존성을 주입받아 복잡한 작업은 프로바이더에게 위임 해야 한다.

서비스

서비스 생성

// service
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}

서비스 등록

@Module({
	...
  providers: [CatsService]
})
export class CatsModule {}

서비스 사용

//controller
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

프로바이더는 @Injectable() 데코레이터를 활용하여 선언하고, 컨트롤러의 constructor를 활용하여 의존성을 주입 할 수 있다.
단, 의존성을 주입하기 위해서는 module에 등록이 되어있어야 한다.
why? 앱이 실행될 때 Nest에서 등록된 의존성을 주입해 주는데 module에 프로바이더가 등록 되어 있지 않으면 Nest가 의존성 괸계를 찾을 수 없다.
ref) IoC

커스텀 프로바이더

사용하는 경우

  1. Nest 프레임워크가 만들어주는 인스턴스 또는 캐시된 인스턴스 대신 인스턴스를 직접 생성하고 싶은 경우.
  2. 여러 클래스가 의존관계에 있을 때 이미 존재하는 클래스를 재사용하고자 할 때
  3. 테스트를 위해 모의 버전으로 프로바이더를 재정의 하려는 경우

모듈메타데이터

export interface ModuleMetadata {
    /**
     * Optional list of imported modules that export the providers which are
     * required in this module.
     */
    imports?: Array<Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
    /**
     * Optional list of controllers defined in this module which have to be
     * instantiated.
     */
    controllers?: Type<any>[];
    /**
     * Optional list of providers that will be instantiated by the Nest injector
     * and that may be shared at least across this module.
     */
    providers?: Provider[];
    /**
     * Optional list of the subset of providers that are provided by this module
     * and should be available in other modules which import this module.
     */
    exports?: Array<DynamicModule | Promise<DynamicModule> | string | symbol | Provider | ForwardReference | Abstract<any> | Function>;
}

프로바이더를 등록할 때 Provider의 Array를 받는다. 그러면 Provider의 코드를 보자.

Provider

export declare type Provider<T = any> = Type<any> | ClassProvider<T> | ValueProvider<T> | FactoryProvider<T> | ExistingProvider<T>;

export interface ClassProvider<T = any> {

    provide: InjectionToken;

    useClass: Type<T>;

    scope?: Scope;

    inject?: never;

    durable?: boolean;
}

export interface ValueProvider<T = any> {

    provide: InjectionToken;

    useValue: T;

    inject?: never;
}

export interface FactoryProvider<T = any> {
 
    provide: InjectionToken;

    useFactory: (...args: any[]) => T | Promise<T>;

    inject?: Array<InjectionToken | OptionalFactoryDependency>;

    scope?: Scope;

    durable?: boolean;
}
export interface ExistingProvider<T = any> {

    provide: InjectionToken;

    useExisting: any;
}

ClassProvider, ValueProvider, FactoryProvider 등을 받는다.

0개의 댓글