Angular 2 Hierarchical Dependency Injection - Объявление зависимостей корневого провайдера вне root?
(Обратите внимание, я использую Angular 2 RC5)
Для простоты у меня есть такое приложение:
app.module.ts
@NgModule({
providers: [
RootService
],
entryComponents: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
root.service.ts
import Dependency1 from './somewhere'
import Dependency2 from './somewhere-else'
@Component({
providers: [Dependency1, Dependency2]
})
@Injectable()
export class RootService {
constructor(
private dep1: Dependency1,
private dep2: Dependency2
) {...}
}
Пример зависимости:
dependency1.ts
@Injectable()
export class Dependency1{
public doGroundbreakingSciencyStuff() {...}
}
Мой вопрос: почему, с учетом вышесказанного, меня встретили с ошибкой, говорящей:No provider for PouchSync!
,
Я могу решить проблему, добавив Dependency1 и Dependency2 к providers
массив в app.module.ts примерно так:
app.module.ts (исправлено)
@NgModule({
providers: [
RootService,
Dependency1,
Dependency2
],
entryComponents: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Это только кажется очень уродливым. Только RootService
нужно знать об этих зависимостях. Я что-то здесь не так делаю? Или кто-то может объяснить, почему так должно быть? Конечно, при введении RootService
, инжектор может видеть, что это зависит от Dependency1
а также Dependency2
и, следовательно, должны вводить их тоже, и, следовательно, они также будут синглетами широкого применения.
2 ответа
Сервисы не являются компонентами, поэтому они не могут иметь @Component decorator (что означает - невозможно добавить массив провайдеров для класса сервиса). Заключение? Этот код неверен:
@Component({
providers: [PouchSync, PouchArraySync]
})
@Injectable()
export class RootService {
constructor(
private dep1: Dependency1,
private dep2: Dependency2
) {...}
}
Но твой второй пример сделан в угловом 2-х направлениях.
Вы написали, что только RootService
нужно знать о зависимостях. Поэтому, если эти зависимости не являются объектами многократного использования, которые должны быть внедрены в несколько частей вашего приложения, но доступны только в этом классе (!) - вы должны просто создать их экземпляры внутри вашего сервиса.
Любая служба, которую вы хотите использовать в своем приложении, должна быть добавлена в массив провайдеров. Добавление службы в корневой каталог ngModule буквально делает их доступными во всем приложении.
Когда вы говорите: "Конечно, при внедрении RootService инжектор может видеть, что он зависит от Dependency1 и Dependency2, и, следовательно, должен вводить их тоже, и, следовательно, они также будут синглетонами широкого применения".
Ни один инжектор не добавит Dependency1 и Dependency2 автоматически, только добавив RootService. Они должны быть специально добавлены в массив провайдеров