NestJS 공식 문서 Circular dependency

GGAE99·2023년 7월 11일
0

NestJS 공식 문서

목록 보기
8/33

Circular dependency

의존성 순환은 두 개의 클래스가 서로에게 종속되어 있는 상황을 말합니다. 예를 들어, 클래스 A는 클래스 B가 필요하고, 클래스 B도 클래스 A가 필요한 경우입니다. 원형 종속성은 Nest에서 모듈 간 및 프로바이더 간에 발생할 수 있습니다.

가능한 경우에는 의존성 순환을 피하는 것이 좋지만 항상 그렇게 할 수는 없습니다. 이러한 경우에는 Nest에서 두 가지 방법으로 프로바이더 간의 의존성 순환을 해결할 수 있습니다. 이 장에서는 forward referencing을 사용하는 기술과 ModuleRef 클래스를 사용하여 DI 컨테이너에서 프로바이더 인스턴스를 검색하는 방법 및 모듈간의 의존성 순환을 해결하는 방법에 대해서 설명합니다.

경고
"바렐 파일" 또는 index.ts 파일을 사용하여 가져온 파일들을 그룹화할 때도 의존성 순환이 발생할 수 있습니다. 모듈 또는 프로바이더 클래스에 대해서는 바렐 파일을 사용하지 않아야 합니다. 예를 들어, 바렐 파일 내부와 동일한 디렉토리 내에 있는 파일을 가져올 때 cats/cats.controller는 cats/cats.service 파일을 가져오기 위해 cats를 가져오면 안됩니다. 자세한 내용은 이 GitHub 이슈를 참조하십시오.

Forward reference

전방 참조(Forward reference)는 Nest가 아직 정의되지 않은 클래스를 참조할 수 있게 해주는 forwardRef() 유틸리티 함수를 사용하는 것을 말합니다. 예를 들어, CatsServiceCommonService가 서로에게 종속되어 있는 경우, 관계의 양쪽에서 모두 @Inject()forwardRef() 유틸리티를 사용하여 원형 종속성을 해결할 수 있습니다. 그렇지 않으면 Nest는 필요한 모든 메타데이터가 사용 가능하지 않기 때문에 이들을 인스턴스화하지 않습니다. 다음은 예시입니다:

//cats.service.ts
@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}

CatService의 관계를 다뤘으니, 이제 CommonService도 똑같은 과정을 거쳐줍시다.

//common.service.ts
@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}

forwardRef() 함수는 @nestjs/common 패키지에서 import 합니다.

경고
인스턴스화 순서는 결정되지 않습니다. 코드가 어떤 생성자가 먼저 호출되는지에 의존하지 않도록 주의하십시오. 의존성 순환이 Scope.REQUEST를 가진 프로바이더에 의존하는 경우에는 정의되지 않은 종속성이 발생할 수 있습니다. 자세한 내용은 여기에서 확인할 수 있습니다.

ModuleRef class alternative

forwardRef()를 사용하는 대신 코드를 리팩토링하고 ModuleRef 클래스를 사용하여 (그렇지 않은 경우) 원형 종속성을 가진 관계의 한쪽에서 프로바이더를 검색하는 대안이 있습니다. ModuleRef 유틸리티 클래스에 대한 자세한 내용은 다음 장인 Module reference에서 확인할 수 있습니다.

Module forward reference

모듈 간의 원형 종속성을 해결하기 위해, 모듈 연관성의 양쪽에서 동일한 forwardRef() 유틸리티 함수를 사용하세요.

// common.module.ts
@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}

위의 코드는 관계의 한쪽을 다루고 있습니다. 이제 CatsModule에서도 동일한 방법을 사용해봅시다

// cats.module.ts
@Module({
  imports: [forwardRef(() => CommonModule)],
})
export class CatsModule {}

질문 및 생각

  • barrel files가 뭐야?
  • moduleRef Class란?

0개의 댓글