Custom providers

Custom providers

컨트롤 컨테이너의 Nest 반전에 무언가를 직접 바인딩하려는 경우가 많이 있습니다. 예를 들어, 상수 값, 현재 환경을 기반으로 작성된 구성 오브젝트, 외부 라이브러리 또는 정의된 다른 제공자에 거의 의존하지 않는 사전 계산된 값. 또한 기본 구현을 재정의할 수 있습니다. 예: 필요할 때 다른 클래스를 사용하거나 다양한 테스트 복식 (테스트 목적으로)을 사용하십시오.

Nest가 항상 명심해야 할 한 가지는 Nest가 토큰을 사용하여 종속성을 식별한다는 것입니다. 일반적으로 자동 생성된 토큰은 클래스와 같습니다. 사용자 지정 공급자를 만들려면 토큰을 선택해야 합니다. 대부분의 사용자 정의 토큰은 일반 문자열 또는 기호로 표시됩니다. 모범 사례를 따르면, 해당 토큰을 분리된 파일 (예: constants.ts)에 보관해야 합니다.

사용 가능한 옵션을 살펴 보겠습니다.

Use value

useValue 구문은 상수 값을 정의하거나 외부 라이브러리를 Nest 컨테이너에 넣거나 실제 구현을 모의 객체로 대체 할 때 유용합니다.

import { connection } from './connection';

const connectionProvider = {
  provide: 'CONNECTION',
  useValue: connection,
};

@Module({
  providers: [connectionProvider],
})
export class ApplicationModule {}

커스텀 프로 바이더를 주입하기 위해 @Inject()데코레이터를 사용합니다. 이 데코레이터는 토큰이라는 단일 인수를 취합니다.

@@filename()
@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
@@switch
@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}

info 힌트 @Inject() 데코레이터는 @nestjs/common 패키지에서 가져옵니다.

기본 제공 업체의 값을 재정의 하려는 경우 테스트 목적으로 Nest가 모의 CatsService를 사용하도록 강요하고 싶을 때 기존 클래스를 토큰으로 사용하면 됩니다.

import { CatsService } from './cats.service';

const mockCatsService = {};
const catsServiceProvider = {
  provide: CatsService,
  useValue: mockCatsService,
};

@Module({
  imports: [CatsModule],
  providers: [catsServiceProvider],
})
export class ApplicationModule {}

위의 예에서 CatsService는 전달 된 mockCatsService 모의 객체로 재정의됩니다. 즉, CatsService인스턴스를 수동으로 생성하는 대신 Nest가이 공급자를 이미 해결된 것으로 간주하고mockCatsService를 대표 값으로 사용합니다.

Use class

useClass 구문을 사용하면 선택한 요소마다 다른 클래스를 사용할 수 있습니다. 예를 들어, 추상 (또는 기본) ConfigService 클래스가 있습니다. 현재 환경에 따라 Nest는 다른 구성 서비스 구현을 사용해야 합니다.

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class ApplicationModule {}

warning 알림 커스텀 토큰 대신 ConfigService 클래스를 사용했으므로 기본 구현을 재정의했습니다.

이 경우 클래스가 ConfigService에 종속되어 있더라도 Nest는 제공된 클래스 (DevelopmentConfigService 또는 ProductionConfigService)의 인스턴스를 대신 주입합니다.

Use factory

useFactory는 제공자를 동적으로 만드는 방법입니다. 실제 공급자는 팩토리 함수의 반환 값과 같습니다. 팩토리 기능은 여러 다른 제공자에 의존하거나 완전히 독립된 상태를 유지할 수 있습니다. 이는 팩토리가 인수를 허용할 수 있음을 의미하며, 인스턴스화 프로세스 중에 Nest가 분석하여 전달합니다. 또한 이 함수는 비동기 적으로 값을 반환할 수 있습니다. 여기에 더 자세히 설명되어 있습니다. 공급자를 동적으로 계산해야 하거나 비동기 작업을 해결하려는 경우에 사용하십시오.

@@filename()
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class ApplicationModule {}
@@switch
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class ApplicationModule {}

info 힌트 팩토리에 다른 제공자가 필요한 경우, inject 배열 안에 토큰을 전달해야 합니다. Nest는 인스턴스를 동일한 순서로 함수의 인수로 전달합니다.

Use existing

useExisting을 사용하면 기존 공급자의 별칭을 만들 수 있습니다. 예를 들어, AliasedLoggerService 토큰은 LoggerService의 별명입니다.

@Injectable()
class LoggerService {}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class ApplicationModule {}

info 힌트 LoggerService 인스턴스는 AliasedLoggerService 토큰에 의해 정의된 인스턴스와 동일합니다.

Export custom provider

사용자 지정 공급자를 내보내려면 토큰 또는 전체 개체를 사용할 수 있습니다. 다음 예제는 토큰 케이스를 보여줍니다.

@@filename()
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class ApplicationModule {}
@@switch
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class ApplicationModule {}

그러나 전체 객체를 사용할 수도 있습니다.

@@filename()
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class ApplicationModule {}
@@switch
const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class ApplicationModule {}

Last updated