문자열·Symbol token으로 계약과 구현을 분리합니다.
인터페이스는 런타임에 사라지므로 custom provider token으로 구현을 등록하고 @Inject로 주입합니다. 테스트와 환경별 adapter 교체에 유용합니다.
token은 충돌을 피하도록 Symbol이나 중앙 상수를 사용합니다.
계약은 업무에 필요한 메서드만 노출하고 특정 DB 라이브러리 타입이 상위 계층으로 새지 않게 합니다.
서비스 locator처럼 ModuleRef에서 임의 provider를 찾으면 의존성이 코드에 드러나지 않습니다.
로컬 프로젝트에서 확인해보세요메모리 구현에 save 메서드를 추가하세요.
import "reflect-metadata";
import { Controller, Get, Inject, Module } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
const COURSE_REPOSITORY = Symbol("COURSE_REPOSITORY");
class MemoryCourseRepository {
findAll() {
return [{ id: 1, title: "Token 기반 저장소" }];
}
}
@Controller()
class AppController {
constructor(@Inject(COURSE_REPOSITORY) private readonly repo: MemoryCourseRepository) {}
@Get() home() {
return this.repo.findAll();
}
}
@Module({
controllers: [AppController],
providers: [{ provide: COURSE_REPOSITORY, useClass: MemoryCourseRepository }],
})
class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(4173, "0.0.0.0");
}
bootstrap();