NestJS 의존성 주입 배열로 받기

Tags
Published
Author
NestJS 프로젝트를 진행하면서 의존성 주입을 배열로 받아야 하는 경우가 있었다.
Spring 의 경우 배열로 선언하면 interface 를 구현한 구현체를 알아서 배열로 세팅해주지만 NestJS 에서는 예쁘게 지원이 안된다. 명시적으로 선언하는 방식으로 해야하는데 어떻게 하는지 알아보자.
 
아래와 같은 service 를 만든다.
@Injectable() export class AppService { constructor(@Inject('handlers') private readonly handlers: Handler[]) {} handleRequest(key: string): void { for (const handler of this.handlers) { if (handler.isResponsible(key)) { handler.handle(); } } } }
app.module 파일을 아래와 같이 설정해본다.
@Module({ controllers: [AppController], providers: [ AppService, { provide: 'handlers', useClass: FooHandler, }, { provide: 'handlers', useClass: BarHandler, }, ], }) export class AppModule {}
서버를 실행해 보면 실행이 된다.
notion image
 
그리고 service 에서 handlers 를 찍어보면
notion image
?? handlers 프로퍼티에 왠 BarHandler 하나만 들어와있다. NestJS 의 의존성 컨테이너는 동일한 키로 여러번 등록하는 경우 그냥 덮어쓴다는걸 예상할 수 있다.
 
app module 을 아래와 같이 수정해보자
@Module({ controllers: [AppController], providers: [ AppService, FooHandler, BarHandler, { provide: 'handlers', useFactory: (foo, bar) => [foo, bar], inject: [FooHandler, BarHandler], }, ], }) export class AppModule {}
 
다시 service 에서 handlers 를 찍어보면
notion image
배열로 잘 들어온 것을 확인할 수 있다.
 
결국 배열에 새로운 객체를 추가로 주입하는 경우 use factory 함수를 변경해 줘야하고, provider 배열에 새로 구현된 구현체를 추가해줘야 한다.

Reference

배열로 의존성 주입을 지원하기 위한 core feature PR

기능으로 추가될 듯 하다가 결국 closed 처리 되었다. 구현 상 어려움이 있었고, 명시적인 방법으로 가능해서 그냥 close 처리한 듯 하다.

배열 의존성 주입을 최초로 요청한 것으로 보이는 Issue

배열 의존성 주입을 명시적으로 할 수 있는 방법을 제시한 Issue comment