Нужны ли [провайдеры] при внедрении зависимости от конструктора?
Проходя этот учебник todo, он имеет следующее:
import {TodoDataService} from './todo-data.service';
@Component({
// ...
providers: [TodoDataService]
})
constructor(private todoDataService: TodoDataService) {
}
IIUC мы должны объявить TodoDataService
в массиве провайдеров. Это кажется излишним. Может ли Angular DI прочитать сгенерированные метаданные для компонента и автоматически внедрить TodoDataService
используя конструктор инъекций?
Обновить
Angular реализовал это до некоторой степени сейчас. Я попросил их удалить providedIn:root
а также, и они сказали, что у них есть вещи на дорожной карте для этого.
1 ответ
Барботаж инжектора
Когда компонент запрашивает зависимость, Angular пытается удовлетворить эту зависимость с помощью поставщика, зарегистрированного в собственном инжекторе этого компонента. Если у инжектора компонента отсутствует поставщик, он передает запрос до инжектора родительского компонента. Если этот инжектор не может удовлетворить запрос, он передает его родительскому инжектору. Запросы продолжают пузыриться до тех пор, пока Angular не найдет инжектор, который может обработать запрос, или не исчерпает инжекторов-предков. Если у него кончаются предки, Angular выдает ошибку.
Насколько я понимаю, если ваш компонент предоставляет услугу, вы получаете один экземпляр этой службы для каждого компонента. Если это не так, он идет вверх по дереву компонентов, пока не найдет что-то, что обеспечивает его. Так что что-то должно обеспечить это.
Я думаю, что он на самом деле проверяет сгенерированные метаданные, но использует его только для того, чтобы увидеть, какой сервис нужен компоненту, а не откуда сервис (откуда providers:[TodoDataService]
для).
В моем приложении большинство моих услуг предоставляются в моем app.module.ts
Таким образом, я получаю один экземпляр каждого сервиса во всем приложении.