* a → b : a에 b를 주입시킴 / a에 b를 import 함
- 모듈 소개
MainModule : 서비스와 관련된 모듈, 컨트롤러, DB 데이터 등을 관리
UserModule : 사용자 정보를 처리하는 모듈
DataModule : DB와 통신하며 데이터를 처리하는 모듈
UtilModule: Util성 코드 및 서비스들 모음
SomeUtil : <문제> DB데이터를 활용하여 특정 영역과 관련된 처리를 하는 서비스
- 배경
위 모듈소개와 같이 DB데이터를 활용하여 특정 데이터를 처리할 Util성 서비스가 필요해졌다. 이때 SomeUtil은 MainModule 아래에 있는 UserModule에 쓰여야 했다. UserModule은 DataModule을 사용하고 있었고, 두 모듈 모두 UtilModule을 import 하고 있었다. 정리하자면, SomeUtil은 DataModule을 사용하고, DataModule은 SomeUtil의 부모 UtilModule을 사용하고 있다.
- DataModule <-> UtilModule(祖) - SomeModule(母)- SomeUtil(子)
- UserModule <-> UtilModule(祖) - SomeModule(母) - SomeUtil(子)
NestJS 공식문서의 예제와 다른점이 있다. 공식문서는 모듈과 모듈, 서비스와 서비스를 사용시 발생하는 순환 종속성 발생 케이스이다. 하지만 내 케이스는 다른 모듈, 서비스들에 주입할 SomeUtil의 조부모 모듈(UtilModule)을 사용할 때 순환 종속성 발생하는 것.
- 기존 코드
@Module({
imports: [ UtilModule, DataModule ],
providers: [ UserService ],
exports: [ ... ],
})
export class UserModule {}
@Injectable()
class UserService {
constructor (
private readonly someUtil : SomeUtil
) {}
}
@Module({
imports: [ UtilModule ],
providers: [ DataService ],
exports: [ ... ],
})
export class DataModule {}
@Injectable()
class DataService {
constructor (
private readonly someUtil : SomeUtil
) {}
}
@Module({
imports: [ SomeModule ],
exports: [ SomeModule ],
})
export class UtilModule {}
@Module({
imports : [ DataModule ],
providers: [ SomeUtil ],
exports : [ SomeUtil ],
})
export class SomeModule {}
@Injectable()
export class SomeUtil {
constructor(
private readonly dataService: DataService
) {}
}
처음엔 단순히 기존에 사용하던 방식 그대로 Module을 구성했다. 하지만 실행하자마자 Circular dependency 오류가 발생...
- 에러 해결 forwardRef()
이 글과 같이, 순환 종속성에 대해 먼저 알아보았다. 즉 서로 모듈이 종속될 (=사용할) 경우 어떤 모듈은 아직 정의가 되기 전 일 수 있기 때문에 Nest는 순환 종속성 오류를 발생시킨다. 그렇담 공식 문서에 맞게 forwardRef() 유틸리티 함수를 사용해보자! 해결책이 아주아주 간단했다... 서로 사용하는 모듈만 forwardRef() 처리해주면 된다.
@Module({
imports: [ UtilModule, DataModule ],
providers: [ UserService ],
exports: [ ... ],
})
export class UserModule {}
@Injectable()
class UserService {
constructor (
private readonly someUtil : SomeUtil
) {}
}
@Module({
imports: [ forwardRef(() => UtilModule) ],
providers: [ DataService ],
exports: [ ... ],
})
export class DataModule {}
class DataService {
constructor (
private readonly someUtil : SomeUtil
) {}
}
@Module({
imports: [ SomeModule ],
exports: [ SomeModule ],
})
export class UtilModule {}
@Module({
imports : [ forwardRef(() => DataModule) ],
providers: [ SomeUtil ],
exports : [ SomeUtil ],
})
export class SomeModule {}
@Injectable()
export class SomeUtil {
constructor(
private readonly dataService: DataService
) {}
}
- 착각...
난 처음에 DataModule과 SomeModule 안에 이미 순환 종속성이 발생했기 때문에 두 모듈을 사용하는 모든 모듈에 forwardRef처리를 해야하는 줄 알았다. 그러나, 순환 종속은 서로 종속될, 즉 서로 사용할 경우이기 때문에 화살표가 양방향으로 되는 (오렌지색) 경우만 처리해주면 되었다.
Nest에 대해 더 잘 이해하게된 느낌..ㅎㅎ
'Dev > 트러블슈팅, 오류해결록' 카테고리의 다른 글
Nest.js) 의존성, 주입 관련오류 / Error: Nest can't resolve dependencies of ... 아무리해도 해결이 안될때 (Feat. chatGPT) (0) | 2023.04.16 |
---|---|
nCloud ) Load Balancer & Auto Scaling 으로 유연한 서버 관리하기 - 로드밸런서에서 생긴 오류 해결기 (0) | 2021.12.26 |
React ) 컴포넌트 안 바뀜, 안 사라짐, 쌓임 현상 디버깅 (0) | 2021.09.30 |
Docker ) Nodejs Build process.dlopen 오류 해결 (0) | 2021.09.04 |
React ) React 이벤트 버블링 막기 (0) | 2021.07.24 |