순환 참조(circular dependency)는 두 개 이상의 모듈이나 프로바이더가 서로를 의존하는 상황을 의미한다. 이는 일반적으로 모듈 A가 모듈 B를 의존하고, 동시에 모듈 B가 모듈 A를 의존하는 경우 발생한다. 이런 순환 참조는 애플리케이션의 의존성 그래프를 불완전하게 만들어 런타임 에러를 유발한다.
// user.service.ts
@Injectable()
export class UserService {
constructor(private readonly profileService: ProfileService) {}
}
// profile.service.ts
@Injectable()
export class ProfileService {
constructor(private readonly userService: UserService) {}
}
위와 같은 상황에서는 UserService
가 ProfileService
를 의존하고 있고, 동시에 ProfileService
가 UserService
를 의존하고 있으므로 순환 참조 문제가 발생한다.
NestJS는 forwarRef
함수를 제공하여 순환 참조 문제를 해결할 수 있다. forwarRef
를 사용하면 의존성 주입에서 순환 참조를 해결할 수 있다.
// user.service.ts
@Injectable()
export class UserService {
constructor(
@Inject(forwardRef(() => ProfileService))
private readonly profileService: ProfileService,
) {}
}
// profile.service.ts
@Injectable()
export class ProfileService {
constructor(
@Inject(forwardRef(() => UserService))
private readonly userService: UserService,
) {}
}
이렇게 하면 ProfileService
와 UserService
가 서로 참조할 수 있게 되어 순환 참조 문제가 해결된다.
순환 참조 문제를 해결하는 또 다른 방법은 모듈의 의존성을 재구성하는 것이다. 공통 의존성을 별도의 모듈로 추출하여 해결할 수 있다.
// common.module.ts
@Module({
providers: [UserService, ProfileService],
exports: [UserService, ProfileService],
})
export class CommonModule {}
// user.module.ts
@Module({
imports: [CommonModule],
})
export class UserModule {}
// profile.module.ts
@Module({
imports: [CommonModule],
})
export class ProfileModule {}
이렇게 하면 UserService
와 ProfileService
가 공통 모듈에서 제공되므로 순환 참조 문제를 피할수 있다.
NestJS에서 순환 참조 문제는 일반적인 문제이며, 이를 해결하기 위해
forwarRef
함수, 모듈 분리, 또는 다른 설계 패턴을 사용할 수 있다. 이를 통해 의존성 주입 시스템이 올바르게 작동하고 애플리케이션이 안정적으로 동작할 수 있도록 할 수 있다.