▶[Angular2 COOKBOOK] @Injectable
이번 글에서는 Angular를 하다보면 쉽게 마주치게되는 @Injectable 이라는 Decorator에 대해서 입문자의 관점에서 정리해보고자한다.
@Injectable 이란?
Angular에는 여러가지 Decorator가 있다.(@Component, @Input ...등등등.) @Injectable도 이 중 하나이다. 그런데 개인적으로는 (왜인지는 모르겠지만) 이 @Injectable 이라는 Decorator가 다른 Decorator보다 더 뭔가 두려운(?)느낌이든다. 발음도 뭔가 "인젝ㅌ..."
그래서 Angular API 에서 @Injectable를 쳤더니, 이것에 대한 친절한 한국어 Document가 나왔다!!! 라고 말하고 싶지만, Dependency Injection 이라는 길고긴 페이지가 나온다. @Injectable을 Finder로 찾아보니 이 페이지에서 총 17번이나 등장한다.
요부분만 살짝 핥고(?) 나오고싶었지만, 이건 아마 정독하라는 Anuglar 개발자들의 의도라고 생각하고 차근차근 접근해보려고한다. 이 문서에서는 Dependency Injection 에서도 @Injectable and nested service dependencies 에 대한 내용이다
만약 이 문서에서 잘못 이해하고있거나, 해석하고있다면 댓글과 방명록으로 도움을 주세요 help us.
@Injectable and nested service dependencies
주입된(Injected) service를 소비하는 곳에서는 해당 Service를 만드는 방법을 알 수 없다. 이것을 걱정하지 않아도 된다. 그것은 Service를 만들고 캐시할 수 있는 의존성 주입(Dependency Injection) 작업이다.
중첩된 서비스 의존성 Nested Service Dependency
뭐라고 정의하는 것도 애매하지만, "중첩된 서비스 의존성" 또는 "서비스 의존성이 중첩적으로 되어있다"라고 생각해볼 수 있겠다. 이것은 우리가 만든 서비스에서 의존성이 있는 어떤 Service를 A라고 할때, 이 A라는 service도 의존중인 service가 있을 수 있다. 이러한 의존관계를 여기서는 Nested Service Dependency라고 말하는 것이다.
이렇게 중첩적으로 서비스 간 의존성이 있는 경우, framework의 일은 중첩된 종속성을 올바르게 해결(또는 정리하는 것)하는 것이다.
이를 위해, 각 단계에서 종속적인 처리가 이루어지는 consumer는, 필요한 부분에 대해서만 간단히 constructor에서 선언(declare)하고, framework는 이것을 이어받아(take over)처리한다.
다음 예시를 통해 이 개념에 대해서 생각해보자.
app/app.component.ts
constructor(logger: LoggerService, public userContext: UserContextService){
userContext.loadUser(this.userId);
logger.logInfo('AppComponent initialized');
}
위 코드에서는 LoggerService와 UserContext 를 AppComponent에 주입(inject)하고 있다.
UserContext는 각 사용자에대한 정보를 모으기 위해 LoggerService (again) 과 UserService 에 의존한다.
user-context.service.ts (injection)
@Injectable()
export class UserContextService {
constructor(private userService: UserService, private loggerService: LoggerService){ }
}
Angular가 AppComponent를 생성할 때, 의존성 주입(Dependency Injection) Framework는 LoggerService와 UserContextService의 인스턴스를 생성하기 시작한다.
UserContextService는 LoggerService, 그리고 이 것을 만들기위해 필요한 UserService가 필요하다. 그런데 UserContextService가 이 두 Service가 필요로할 때 이것들은 아직 생성되지않은 상태이다.
UserService는 의존성(dependencies)가 없다. The UserService
has no dependencies so the dependency injection framework can just new
one into existence.
왜 Dependency Injection을 알아야하지?
의존성주입(dependency injection)의 아름다움
AppComponent의 author는 이러한 모든 것들에 대한 걱정을 할 필요가 없다는 데에 있다. author는 단순히 생성자(Logger Service 및 UserContextService)에 필요했던 것 들을 선언(declare)하고 프레임워크에서 나머지 작은 일들을 처리하도록 한다.
이러한 결과로, AppComponent는 모든 의존성(dependency)이 자리를 잘 잡은다음, 사용자정보를 (우리가 설정한대로) 화면에 표현한다.
이미지 : 사용자정보 표현화면 예시
(angular.io > cookbook > dependency injection)
@Injectable
Injectable을 어떻게 실제 사용하고있는지 다음 코드에서 살펴보자.
@Injectable() decorator는 UserContextService class위에 위치하고있음을 기억하자.
user-context.service.ts(@Injectable)
@Injectable()
export class UserContextService {
}
위 코드에서 @Injectable() decorator가 있음으로, Angular는 이 두가지 의존성(LoggerService, UserService)의 type을 식별할 수 있게된다.
기술적으로, @Injectable() decorator는 service class 자체적으로 종속성이 있을 때 필요하다. 그런데 LoggerService는 아무런 의존성이 없다. 우리가 @Injectable()을 생략해도 logger가 동작할 것이다. 그리고 생성된 코드도 약간 더 작다.
Technically, the
@Injectable()
decorator is only required for a service class that hasits own dependencies. TheLoggerService
doesn't depend on anything. The logger would work if we omitted@Injectable()
and the generated code would be slightly smaller.
그러나 service는 우리가 의존성을 주는 순간 break 할 것이며, 우리는 다시 돌아가서 @Injectable()을 추가함으로써 이를 fix 해야한다. 일관성을 위해서, 여기서는 처음부터 @Injectable()을 추가하여 시간이 지난 후 발생할 상황을 피하기로한다.
Angular에서는 모든 Service Class에 @Injectable 을 적용할 것을 권장한다. 그리고 필요한 경우에만 선택적으로 추가하는 방법도 합리적인 방법이라고 말하고 있다.
(@Injectable을 모든 Service class에 필수적으로 적용 해야한다는 것은아니다.)
AppComponent는 @Injectable 이 필요하지 않았다. 왜냐하면 component class 는 @Component decorator를 가지고있었기 때문이다. Angular가 TypeScript로 작성될 때, single decorator ― any decorator ― 는 의존성 타입을 식별하기에 충분하다.
'AngularJS > AngularJS' 카테고리의 다른 글
▶ [Angular2 Tutorial] 5. Service (5) | 2016.09.23 |
---|---|
▶[Angular Guide] 2. Architecture - (3) Template (2) | 2016.09.21 |
▶[Angular Guide] 2. Architecture - (2) Component (0) | 2016.09.20 |
▶[Angular Guide] 2. Architecture - Intro (0) | 2016.09.20 |
▶[Angular Guide] 2. Architecture - (1) modules (0) | 2016.09.20 |