Angular 개발을 하다 보면 거의 매번 사용하는 기능이 바로 의존성 주입(Dependency Injection)입니다.
그동안은 보통 컴포넌트나 서비스에서 다음과 같이 생성자 기반 주입을 써왔습니다:
@Component({...})
export class MyComponent {
constructor(private userService: UserService) {}
}
constructor
constructor는 TypeScript/JavaScript 클래스에서 객체가 생성될 때 자동으로 실행되는 특별한 메서드입니다.
Angular에서는 이 constructor를 활용해 서비스나 의존성을 주입합니다.
@Component({...})
export class MyComponent {
constructor(private userService: UserService) {
// 컴포넌트가 생성될 때 Angular가 UserService 인스턴스를 넣어줌
}
}
- 여기서 private userService: UserService는 의존성 주입을 통해 자동으로 할당되는 부분입니다.
- 즉, 개발자가 직접 new UserService()를 호출하지 않아도 Angular DI 컨테이너가 알아서 객체를 제공합니다.
inject()
- inject()는 Angular의 DI 컨테이너에서 특정 토큰(서비스, InjectionToken, Provider 등)을 가져오는 함수입니다.
- 클래스 생성자나 Angular 라이프사이클에 의존하지 않고 순수 함수 레벨에서 DI를 사용할 수 있다는 것이 특징입니다.
사용법
import { inject } from '@angular/core';
const userService = inject(UserService);
- 위 코드를 호출하면 Angular의 DI 시스템에서 UserService 인스턴스를 반환합니다.
- 즉, 클래스 내부가 아니어도, 함수나 팩토리 레벨에서 DI를 할 수 있습니다.
constructor vs inject()
constructor
@Component({...})
export class ProfileComponent {
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.getUser();
}
}
inject()
@Component({...})
export class ProfileComponent {
private userService = inject(UserService);
ngOnInit() {
this.userService.getUser();
}
}
장점
- 생성자 파라미터가 길어지는 문제 해결
- super() 호출 전에도 의존성을 가져올 수 있음
- 함수형 프로바이더(factory provider)에서 사용하기 좋음
예시
서비스 안에서 다른 서비스 주입하기
@Injectable({ providedIn: 'root' })
export class AuthService {
private http = inject(HttpClient);
login() {
return this.http.post('/api/login', { ... });
}
}
- constructor 없이 더 깔끔하게 작성 가능.
InjectionToken과 함께 쓰기
export const API_URL = new InjectionToken<string>('API_URL');
@Injectable({ providedIn: 'root' })
export class ApiService {
private http = inject(HttpClient);
private apiUrl = inject(API_URL);
getData() {
return this.http.get(`${this.apiUrl}/data`);
}
}
라우트 가드에서 사용
기존 가드에서는 constructor를 잘 안 쓰는데, inject() 덕분에 코드가 훨씬 단순해집니다.
import { CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
return authService.isLoggedIn();
};
언제 inject()를 쓰면 좋은가?
- 클래스 생성자 코드가 너무 길 때
- 라이프사이클과 무관하게 의존성이 필요한 경우
- 함수형 프로바이더, 라우트 가드, 인터셉터 등에서 주입이 필요할 때
- 테스트 코드에서 주입 간소화할 때
'개발 공부 > Angular' 카테고리의 다른 글
| 앵귤러 메타데이터 관리 (2) (0) | 2025.12.02 |
|---|---|
| 앵귤러 메타데이터 관리 (1) (0) | 2025.11.30 |
| Signals vs RxJS (0) | 2025.08.23 |
| Angular에서 signal을 써야 하는 이유 (1) | 2025.08.15 |
| Angular의 내장 파이프(Built-in Pipes) (2) - Custom (1) | 2025.07.27 |