Nest.js를 하면서 Nest can't resolve dependencies of the UserService 와 같은 에러를 자주 보게되어 정리를 하려고 합니다.
“종속성”이란 애플리케이션이 작동하는 동안과 실제 환경에서 애플리케이션이 제대로 작동하는 데 필수적인 소프트웨어 패키지를 말합니다.
A 클래스의 함수를 실행하기 위해서는 B클래스를 필요하다면, B 클래스에 변화가 생기면 이는 A클래스에도 영향을 미치게 된다.
이것을 종속성이라 부릅니다.
에러의 상황은 다음과 같습니다.
AuthService는 constructor에서는 UserService를 주입받습니다.
UserService는 constructor에서는 AuthService를 주입받습니다.
이렇게 되어 TestCode에서 Nest can't resolve dependencies of the
~
같은 에러가 나타났습니다.
처음에는 TestModule에서 mock provider에 문제가 있다고 판단하여 이런저런 시도를 해보았습니다
보이는 모든걸 providers에 집어 넣어봤지만 동작하지 않았고 다른 방식으로 접근을 하였습니다.
index [1]에 초점을 두고 찾아보았습니다. 1번 인덱스라면 인덱스의 번호는 어디서 나오는가를 찾아보았고 생성자에 작성한 순서의 index라는것을 알았습니다.
UserService에서는 AuthService의 index에서 에러가 나왔고 AuthService의 UserService의 index에서 에러가 나온것을 확인하고 검색 결과 순환 종속성 문제라는것을 알았습니다.
순환 종속성
서로 모듈같의 의존 주입을 할 경우 에러가 발생합니다.
이를 해결하기 위한 방법으로는 다음과 같습니다.
// AuthModule.ts
@Module({
imports: [forwardRef(() => UserModule), TypeOrmModule.forFeature([User])],
providers: [AuthService, UserService, UserFactory],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
@Module({
imports: [TypeOrmModule.forFeature([User]), forwardRef(() => AuthModule)],
providers: [
UserService,
UserFactory,
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
},
],
exports: [UserService],
})
export class UserModule {}
와 같이 imports부분에 forwardRef를 작성해줍니다.
export class AuthService {
constructor(@Inject(forwardRef(() => UserService)) private readonly userService: UserService) {}
}
export class UserService {
constructor(
@InjectRepository(User) private userRepository: Repository<User>,
@Inject(forwardRef(() => AuthService)) private readonly authService: AuthService,
private userFactory: UserFactory,
) {}
}
Service의 constructor에도 위와 작성해 주면 circular dependency가 해결됩니다.
댓글