원문: https://docs.nestjs.com/fundamentals/circular-dependency
순환 종속성
순환 종속성은 두 클래스가 서로 종속될 때 발생합니다.
예를 들어 클래스 A에는 클래스 B가 필요하고 클래스 B에도 클래스 A가 필요합니다.
모듈 간 및 공급자 간에 중첩에서 순환 종속성이 발생할 수 있습니다.
순환 종속성은 두 클래스가 서로 종속될 때 발생합니다.
예를 들어 클래스 A에는 클래스 B가 필요하고 클래스 B에는 클래스 A가 필요합니다.
모듈과 공급자 간에 순환 종속성이 발생할 수 있습니다.
가능한 경우 순환 종속성을 피해야 하지만 항상 그렇게 할 수는 없습니다.
이러한 경우 Nest는 두 가지 방법으로 공급자 간의 순환 종속성을 해결할 수 있습니다.
이 장에서는 다음을 사용하여 설명합니다.
전방 참조 하나의 기술로 사용하고 ModuleRef 클래스를 사용하여 DI 컨테이너에서 제공자 인스턴스를 다른 것으로 검색합니다.
순환 종속성은 가능할 때마다 피해야 하지만 항상 그런 것은 아닙니다.
현재 Nest는 두 가지 방법을 사용하여 공급자 간의 순환 종속성을 해결합니다.
이 챕터에서는 전방 참조사용하는 방법 ModuleRef를 사용하여 DI 컨테이너에서 공급자 인스턴스를 검색하는 방법을 설명합니다.
*retrieve: 검색하다, 검색하다, 검색하다
또한 모듈 간의 순환 종속성을 해결하는 방법도 설명합니다.
또한 모듈 간의 순환 종속성을 해결하는 방법도 설명합니다.
다음을 사용할 때 순환 종속성이 발생할 수도 있습니다.
“배럴 파일”/index.ts 가져오기를 그룹화할 파일. Barrel 파일은 모듈/공급자 클래스와 관련하여 생략되어야 합니다.
예를 들어, 배럴 파일과 동일한 디렉터리 내에서 파일을 가져올 때 배럴 파일을 사용하면 안 됩니다.
고양이/고양이.컨트롤러 수입해서는 안된다 고양이 가져오기 고양이/고양이 서비스 파일. 자세한 내용은 이 github 문제도 참조하십시오.
순환 종속성은 “배럴 파일”/index.ts를 사용하여 그룹을 가져올 때도 발생할 수 있습니다.
모듈/공급자 클래스로 가져올 때 Barrel 파일이 누락될 수 있습니다.
예를 들어 동일한 디렉터리 파일 내에서 가져올 때 배럴 파일을 사용할 수 없습니다.
고양이/고양이.컨트롤러~이다 고양이/고양이 서비스파일을 가져오려면 고양이수입되어서는 안됩니다.
자세한 내용은 GitHub 문제를 참조하세요.
전방 참조
ㅏ 전방 참조 Nest가 아직 정의되지 않은 클래스를 참조하도록 허용합니다.
정방향 참조() 유틸리티 기능. 예를 들어 CatsService와 CommonService가 서로 의존하는 경우 관계의 양쪽에서 다음을 사용할 수 있습니다.
@주입() 그리고 정방향 참조() 순환 종속성을 해결하는 유틸리티입니다.
그렇지 않으면 모든 필수 메타데이터를 사용할 수 없기 때문에 Nest에서 인스턴스화하지 않습니다.
예를 들면 다음과 같습니다.
전방 참조중첩 유틸리티 기능입니다.
정방향 참조()아직 정의되지 않은 클래스를 참조할 수 있습니다.
예를 들어 CatsService와 CommonService가 서로 의존하는 경우 두 관계는 @주입()그리고 정방향 참조() 유틸리티를 사용하여 순환 종속성을 해결할 수 있습니다.
그렇지 않으면 필요한 메타데이터가 유효하지 않기 때문에 Nest는 두 서비스의 인스턴스를 생성하지 않습니다.
예를 들어 보겠습니다.
@Injectable()
export class CatsService {
constructor(
@Inject(forwardRef(() => CommonService))
private commonService: CommonService,
) {}
}
힌트 그만큼 정방향 참조() 함수는 @nestjs/공통 패키지.
힌트 정방향 참조() 기능은 @nestjs/공통 패키지에서 가져오기
그것은 관계의 한 측면을 다룹니다.
이제 CommonService에 대해 동일한 작업을 수행해 보겠습니다.
이것은 한쪽의 관계를 해결합니다.
이제 동일한 방식으로 CommonService를 다루겠습니다.
(*CommonService CatService, CatService 측만 정방향 참조())를 사용하여 덮었다는 것을 의미합니다.
@Injectable()
export class CommonService {
constructor(
@Inject(forwardRef(() => CatsService))
private catsService: CatsService,
) {}
}
인스턴스화 순서는 불확실합니다.
코드가 먼저 호출되는 생성자에 의존하지 않는지 확인하십시오. 순환 종속성은 제공자에 따라 다릅니다.
범위.요청 정의되지 않은 종속성이 발생할 수 있습니다.
사용 가능한 추가 정보 여기
인스턴스화 순서는 쉽게 추측할 수 없습니다.
코드가 먼저 호출되는 생성자에 의존하지 않는지 확인해야 합니다.
범위.요청 공급자 및 공급자에 의한 순환 종속성이 있으면 정의되지 않은 종속성이 발생합니다.
자세한 정보는 여기(?)
ModuleRef 클래스 대안
사용에 대한 대안 정방향 참조() 코드를 리팩토링하고 ModuleRef (그렇지 않은 경우) 순환 관계의 한쪽에서 공급자를 검색하는 클래스입니다.
ModuleRef 유틸리티 클래스에 대해 자세히 알아보기 여기.
정방향 참조()를 사용하는 대신 코드를 리팩터링하거나 ModuleRef클래스를 사용하여 순환 관계의 한쪽(다른 쪽)에서 공급자를 검색할 수 있습니다.
모듈 순방향 참조
모듈 간의 순환 종속성을 해결하려면 동일한 정방향 참조() 모듈 연결의 양쪽에 있는 유틸리티 기능. 예를 들어:
다음과 같은 두 모듈 간의 순환 종속성을 해결하려면 정방향 참조()두 모듈 연결 모두에 유틸리티 기능을 사용하십시오. 예:
@Module({
imports: (forwardRef(() => CatsModule)),
})
export class CommonModule {}