프로젝트를 진행 중 아래와 같은 에러가 발생하였다.
Error: Nest cannot create the ReservationsModule instance.
Potential causes:
https://docs.nestjs.com/fundamentals/circular-dependency
A circular dependency between modules 즉 서로의 모듈간 상호 순환 의존성이 발생하였고, forwardRef()를 써서 방지해라. 라는 뜻이다.
NestJS공식문서의 Circular dependency 페이지로 가서 내용을 확인했다.
//cats.service.ts
@Injectable()
export class CatsService {
constructor(
@Inject(forwardRef(() => CommonService))
private commonService: CommonService,
) {}
}
//common.service.ts
@Injectable()
export class CommonService {
constructor(
@Inject(forwardRef(() => CatsService))
private catsService: CatsService,
) {}
}
공식페이지에서는 forwardRef()
를 @nestjs/common
에서 끌고와서 위와같이 서로 참조하는 부분에 사용하면 해결할 수 있다고 적혀있어서 그대로 진행해보았다.
//house.service.ts
@Injectable()
export class HousesService {
constructor(
@InjectRepository(House) private houseRepository: Repository<House>,
private dataSource: DataSource,
@Inject(forwardRef(() => ReservationsService))
private reservationService: ReservationsService,
) {}
//....//
}
//reservation.service.ts
@Injectable()
export class ReservationsService {
constructor(
@InjectRepository(Reservation)
private reservationRepository: Repository<Reservation>,
@Inject(forwardRef(() => HousesService))
private housesService: HousesService,
) {}
//....//
}
하지만 똑같은 에러를 반환하였다. 공식페이지의 내용을 더 읽어보니 모듈간 순환 종속성을 해결하기 위해서 모듈에서 아래와 같이 작성해야한다고 적혀있었다.
//common.module.ts
@Module({
imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
마찬가지로 해당 내용을 적용해 보았더니 해결되었다.
//house.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([House]),
forwardRef(() => ReservationsModule),
],
controllers: [HousesController],
providers: [HousesService],
exports: [HousesService],
})
//reservation.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([Reservation]),
AuthModule,
forwardRef(() => HousesModule),
],
controllers: [ReservationsController],
providers: [ReservationsService],
exports: [ReservationsService],
})
혹시나 싶어 먼저 진행했던 Service에서 사용된 forwardRef()
를 기존 방식으로 변경해 보았는데, 다시 에러를 뿜었다. 결국 Service에서도 Module에서도 모두 사용해 줘야만 해결되는 방식이었다.
해결은 하였지만 이해가 도통가지 않았다. forwardRef()
를 step-in 해보면 아래와 같다.
import { ForwardReference } from '../interfaces/modules/forward-reference.interface';
/**
* @publicApi
*/
export declare const forwardRef: (fn: () => any) => ForwardReference;
export interface ForwardReference<T = any> {
forwardRef: T;
}
대체 이 함수가 뭘.. 할 수 있는거지? 어째서 순환참조를 해결해 주는건지 알 수 없었다.. 찜찜한데 찾아봐도 잘 안나와서 일단은 해결은 됬으니 넘어는 간다.. ㅠㅠ