TIL_171120 Angular Service

Service

  • Service는 Component와 Service를 사용할 수 있음
  • 서비스는 의존성 주입이 가능한 클래스로 작성함
  • 서비스를 사용한다는 이야기는 서비스 클래스가 생성한 인스턴스를 사용한다는 것

의존성 주입

  • 구성 요소 간의 의존관계가 코드 내부가 아닌 외부의 설정파일 등을 통해 정의하는 패턴
  • 구성 요소 간 결합도를 낮추고 재사용성을 높임

@Injectable 데코레이터

  • 자신의 아래에 정의된 클래스가 주입가능한 클래스임을 나타냄
  • 순수한 자바스크립트 클래스가 다른 자바스크립트 클래스 내에 주입 가능한 상태가 되었음을 의미

왜 new를 사용한 의존성 주입은 비추천 되는가?

컴포넌트 내에서 constructor내부에 new를 사용하여 의존성을 주입한다면, 컴포넌트가 사용하는 서비스(의존성)가 구현하는 내용의 변경이 요구됐을때에

  • 긴밀한 결합관계로 인한 손수 코드 수정이 불가피
  • 즉, 컴포넌트 내 변경해줘야 할 사항이 많음을 의미
  • new를 사용한 주입방법은 해당 서비스의 인스턴스 생성방법을 알고 있어야만 사용 가능

해결방안

의존성 주입

  • 컴포넌트가 사용하는 서비스(의존성)의 인스턴스를 컴포넌트에서 new로 생성하는 것이 아니라,
    서비스에서 생성하여 그것을 컴포넌트에 주입하여 사용
  • 제어권의 역전
  • 다만, 필요한 의존성의 인스턴스를 어떻게 생성하는지 앵귤러에게 알려주기 위해 providers 프로퍼티 작성

    1
    2
    3
    4
    5
    6
    providers: [{
    // 의존성으로 주입될 객체의 타입(토큰, Token)
    provide: GreetingService,
    // 의존성으로 주입될 객체의 인스턴스를 생성할 클래스
    useClass: GreetingService
    }]
  • providers에는 constructor 에 매개변수로 선언한 서비스의 인스턴스가, 사용한 클래스 명을 적어줌.

  • 즉, 해당 컴포넌트의 constructor 매개변수(생성될 인스턴스)의 타입은, providers에 적어준 클래스를 사용해서 만드는 것이라 알려주는 것
  • constructor 내에 private을 써주지 않으면, 멤버변수화가 되지 않아 컨스트럭터 내부에서만 사용할 수 있으므로 써주어야함 (타입스크립트)
1
2
// 의존성 주입
constructor(private greetingService: GreetingService) {}

Injector

  • 컴포넌트가 생성될때 앵귤러가 컴포넌트에 필요한 인스턴스를 인젝터에 요청
  • 이미 생성한 인스턴스를 담고 있는 컨테이너 관리자
  • 요청된 인스턴스가 존재하지 않으면 새로 생성하고 컨테이너에 추가
  • 요청된 인스턴스를 컴포넌트 생성자의 인자로 주입
  • 인젝터는 컴포넌트별로 하나씩 가지고 있음

Provider

  • 모듈에 프로바이더를 설정한 경우, 컴포넌트에 프로바이더를 또 설정하면 X
  • -> 싱글턴이 유지되지 않음 (서비스가 두개 생성됨)
  • 모듈레벨 등록한 프로바이더: 하나의 인스턴스 공유
  • 컴포넌트레벨 등록한 프로바이더: 컴포넌트가 생성될때마다 새로운 인스턴스 취득

HttpClient

  • module에 import해주어야함
  • 첫번째 콜백에는 성공했을때,
  • 두번째 콜백에는 실패했을때 로직을 써준다
    1
    2
    3
    4
    5
    6
    7
    8
    import { HttpClientModule } from '@angular/common/http';
    @NgModule({
    declarations: [AppComponent],
    imports: [
    BrowserModule,
    // HttpClientModule을 임포트한다.
    HttpClientModule
    ],