Аурелия имеет реализацию зависимостей инжекционного контейнера, который он использует для создания экземпляра ViewModels и многие из служб приложений, которые являются частью системы или письменными разработчиками. Как правило, вам не нужно использовать контейнер непосредственно, потому что система соглашений Aurelia использует контейнер для создания моделей просмотра и служб от вашего имени, а @inject
и @autoinject
не нужно настраивать контейнер вручную.
Что представляет собой контейнер для инъекций ?Ну контейнер другое слово для инжектора:
Инжектор представляет услуги в клиенте. Часто он также создает клиента. Инжектор может связывать вместе очень сложный граф объектов, обрабатывая объект, подобный клиенту, а затем как услугу для другого клиента. Инжектор может фактически быть множеством объектов, работающих вместе, но не может быть клиентом. На инжектор могут ссылаться другие имена, такие как: сборщик, поставщик, контейнер, завод, строитель, весна, строительный код или основной. - https://en.wikipedia.org/wiki/Dependency_injection
контейнерная система Аурелии является иерархическим, что означает, когда вы @inject
или @autoinject
что-то, текущий контейнер (ребенок) будет произведен поиск элемента и, если он не найден, будет произведен поиск родительского контейнера и так и до тех пор, пока элемент не будет найден или не будет удален корневой контейнер, и в этом случае Aurelia построит новый экземпляр запрашиваемого элемента.
В вашем фрагменте кода у вас есть:
import {PersonService} from 'app-services';
import {Person} from 'models';
import {autoinject} from 'aurelia-framework';
@autoinject
export class PersonList {
constructor(private personService: PersonService) {
}
getPeople(){
return this.personService.getAll();
}
}
Предполагая, что это вид-модель специальный элемент, который вы используете, как это: <person-list></person-list>
, вот что произойдет, когда Аурелия инстанцирует PersonList
.
- Детский контейнер будет создан из текущего контейнера (подробнее о том, что представляет собой «текущий контейнер» позже). Эквивалент вызова
container.createChildContainer()
. Мы будем называть этот дочерний контейнер «childContainer
».
- Контекстные элементы будут зарегистрированы в дочернем контейнере, таком как элемент DOM (представление) для модели представления PersonList. Это эквивалент вызова
childContainer.registerInstance(Element, personListDomElement)
. Зачем? Потому что это позволяет разработчикам @inject(Element)
(или эквивалент @autoinject
).
Как только дочерний контейнер сконфигурирован, он используется для создания экземпляра PersonList
. Эквивалент вызова:
personList = childContainer.invoke(PersonList);
childContainer.registerInstance(PersonList, personList);
Ребенка контейнер не имеет ничего зарегистрированного с помощью клавиши «PersonService
», так что это будет искать родительский контейнер, пока он не найден или не может быть найден, в этом случае Aurelia будет построен новый экземпляр PersonService
и зарегистрируйте его в корневом контейнере, чтобы экземпляр можно было повторно использовать в последующих поисках.
- Список просмотров и вид списка лиц составлены механизмом шаблонов, а события создания, привязки, присоединения и т. Д. Происходят.
Бонус: раньше я упомянул ребенок контейнер будет создан из текущего контейнера ... Каждый Aurelia приложение имеет контейнер «корневой уровень», что каждый ребенок контейнер нисходит из, прямо или косвенно. Основные сервисы Aurelia зарегистрированы в корневом контейнере: BindingEngine
, ObserverLocator
, TaskQueue
и многие другие. Это то, что позволяет разработчикам писать @inject(TaskQueue)
и получить тот же экземпляр TaskQueue, который использует инфраструктура Aurelia внутри. В любом случае, когда создается пользовательский элемент или настраиваемый атрибут, дочерний контейнер используется для создания настраиваемого элемента или настраиваемого атрибута. Если этот пользовательский элемент содержит другой пользовательский элемент, дочерний контейнер будет создан из текущего дочернего контейнера и используется для создания экземпляра дочернего пользовательского элемента и так далее.Другими словами, «текущий контейнер» зависит от того, насколько глубоко ваш компонент находится в иерархии вложенных настраиваемых элементов и пользовательских атрибутов.
Ссылки: