본문 바로가기

개발 공부/Angular

Angular inject()

 

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()를 쓰면 좋은가?

  • 클래스 생성자 코드가 너무 길 때
  • 라이프사이클과 무관하게 의존성이 필요한 경우
  • 함수형 프로바이더, 라우트 가드, 인터셉터 등에서 주입이 필요할 때
  • 테스트 코드에서 주입 간소화할 때