Angular 의존성 해결의 흐름
6357 단어 Angular
서비스의
@Injectable
데코레이터로 providedIn: 'root'
올거야.주입물은 도대체 어디에서 오는가
동작을 확인하기 위해 이런 느낌의 샘플을 준비합니다.
AppModule ─────┐
│ AppComponent │
└─┬────────────┘
└ ParentModule ─────┐
│ ParentComponent │
└─┬───────────────┘
└ ChildModule ─────┐
│ ChildComponent │
└────────────────┘
각 모듈, 각 컴퍼넌트에는 각각 프로바이더를 가지게 해, 주입물의 출자가 알 수 있도록(듯이) 합니다.
app.module.ts@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, ParentModule],
providers: [{ provide: AnyService, useValue: { injectLevel: 'root' } }],
bootstrap: [AppComponent]
})
export class AppModule {}
app.component.ts@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [
{ provide: AnyService, useValue: { injectLevel: 'root component' } }
]
})
export class AppComponent {
constructor(public anyService: AnyService) {}
}
각 컴퍼넌트에서는 constructor 로 anyService
를 주입해 injectLevel
(서비스가 제공되는 계층)를 View 에 표시시킵니다.
app.component.html<div>root: {{ anyService.injectLevel }}</div>
<app-parent></app-parent>
parent.component.html<div>parent: {{ anyService.injectLevel }}</div>
<app-child></app-child>
결과는 다음과 같습니다.
당연하네요. 자신의 컴퍼넌트 클래스에서 원하는 것이 제공되고 있기 때문에, 물론 그대로 주입되고 있습니다.
그럼, ChildComponent -> ParentComponent -> AppComponent 와 차례로 컴퍼넌트 클래스의 프로바이더를 삭제해 가면 어떻게 되겠지요.
자신의 컴퍼넌트 클래스내에 주입 대상이 제공되어 있지 않은 경우, Angular는 부모 클래스에 거슬러 공급자를 찾습니다.
루트 컴포넌트(여기서는 AppComponent)로 거슬러 올라가고, 찾을 수 없다면 루트 모듈(여기서는 AppModule)을 찾으러 간다.
그렇다면 루트 모듈에도 공급자가 없으면 Angular는 오류를 반환합니까?
한층 더 프로바이더를 삭제해 가면, 다음과 같이 됩니다.
root 모듈에 프로바이더가 없었던 경우, Angular는 root 모듈의 imports
(을)를 따라 더 프로바이더를 찾습니다.
루트 모듈이 출발점이기 때문에 ParentModule -> ChildModule 의 순서가 되고 있습니다.
모든 모듈을 스캔하여 공급자를 찾을 수 없으면 NullInjector
가 오류를 반환합니다.
요약
Angular가 DI를 요구한 클래스에서 출발하여 의존성을 해결해 나가는 흐름을 쫓았습니다.
AppModule ─────┐
│ AppComponent │
└─┬────────────┘
└ ParentModule ─────┐
│ ParentComponent │
└─┬───────────────┘
└ ChildModule ─────┐
│ ChildComponent │
└────────────────┘
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, ParentModule],
providers: [{ provide: AnyService, useValue: { injectLevel: 'root' } }],
bootstrap: [AppComponent]
})
export class AppModule {}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [
{ provide: AnyService, useValue: { injectLevel: 'root component' } }
]
})
export class AppComponent {
constructor(public anyService: AnyService) {}
}
<div>root: {{ anyService.injectLevel }}</div>
<app-parent></app-parent>
<div>parent: {{ anyService.injectLevel }}</div>
<app-child></app-child>
Angular가 DI를 요구한 클래스에서 출발하여 의존성을 해결해 나가는 흐름을 쫓았습니다.
프로바이더의 위치를 고안하는 것으로, DI 토큰(여기에서는
AnyService
클래스)이 동일해도 완전히 다른 것을 주입시키거나, 주입 가능한 범위를 제한하거나 할 수 있습니다.하지만 특별한 이유가 없으면
providedIn: 'root'
로 좋지 않을까 개인적으로는 생각합니다.Reference
이 문제에 관하여(Angular 의존성 해결의 흐름), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/aqlwah/items/c90f1a7803349349da7f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)