[NestJS] custom-providers
https://docs.nestjs.com/fundamentals/custom-providers
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
😀 custom-providers
- Nest가 클래스를 인스턴스화(또는 캐시된 인스턴스 반환) 하는 대신 커스텀 인스턴스 생성하고싶을때
- 두 번째 종속성에서 기존 클래스를 재사용
- 테스트를 위해 모의버전으로 클래스를 재정의
@ useValue()
1. 상수 주입
2. 외부 라이브러리 Nest 컨테이너에 주입
- 외부 라이브러리를 import 로 가져와도 상관 없지만, 외부 라이브러리가 여러 service 에 필요하다고 했을 경우,
useValue()로 외부라이브러리를 주입해서 여러 service에서 공통으로 공유가 가능하다
3. 실제 구현을 모의 개체로 바꾸는데 유용
1. 상수 주입
import { connection } from './connection';
@Module({
providers: [
{
provide: 'CONNECTION',
useValue: connection,
},
],
})
export class AppModule {}
@Injectable()
export class CatsRepository {
constructor(@Inject('CONNECTION') connection: Connection) {}
}
connection 이 예를들어서, db 연결하는 객체라면
유용하게 공통적으로 사용이 가능해보인다.
아래는 DB 연결의 옵션 값이지만, 보통 저 옵션은 다른곳에서 관리하지만, ex) .env
DB와 연결되어있는 객체를 따롭게 생성하고
DB 연결하는 로직을 service 단에서 매번 DB연결 객체를 import 하는것보다
@inject를 통해서 공통적으로 가져왔을경우, 추후 유지보수에 매우 개발 비용과 시간을 줄일 수 있을듯 보인다.
const dbConfig = {
host: 'localhost',
port: '3000',
};
@Module({
providers: [
{
provide: "dbConnect",
useValue: dbConfig,
}
],
})
export class AppModule { }
import { Inject, Injectable } from "@nestjs/common";
@Injectable()
export class CustomProviderService {
constructor(@Inject("dbConnect") private readonly dbConfig) {}
findOne() {
console.log('dbConfig: ', this.dbConfig);
return "hello";
}
}
2. 외부 라이브러리 Nest 컨테이너에 주입
$ npm install dateformat@3
// CommonJS 모듈 버전을 설치
import * as dateFormat from 'dateformat';
@Module({
providers: [
{
provide: "dateFormat",
useValue: dateFormat,
}
],
})
export class AppModule { }
import { Inject, Injectable } from "@nestjs/common";
@Injectable()
export class CustomProviderService {
constructor (@Inject("dateFormat") private readonly dateFormat ) {}
findOne() {
let now = new Date();
console.log(this.dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT"));
return "hello";
}
}
3. 실제 구현을 모의 개체로 바꾸는데 유용
import { CatsService } from './cats.service';
const mockCatsService = {
/* mock implementation
...
*/
};
@Module({
imports: [CatsModule],
providers: [
{
provide: CatsService,
useValue: mockCatsService,
},
],
})
export class AppModule {}
useValue 사용 시, CatsController에서 CatsService 내에 메서드를 호출 시,
mockCatsService에 동일한 메서드가 호출된다.
여기서 중요한건, CatsService에 findOne 의 메서드가 명시되어있다면,
mockCatsService에도 동일한 메서드가 존재해야된다.