Aurelia hat eine Implementierung eines Dependency Injection Container, die sie verwendet Viewmodels zu instanziiert und viele der Anwendungsdienste, die Teil des Rahmens sind oder geschrieben von Entwicklern. In der Regel müssen Sie den Container nicht direkt verwenden, da das Conventions-System von Aurelia den Container zum Erstellen von Ansichtsmodellen und -Diensten in Ihrem Namen verwendet und @inject
und @autoinject
es nicht erforderlich machen, den Container manuell zu konfigurieren.
Was ist ein Abhängigkeitsinjektionsbehälter?Nun ein Behälter ist ein anderes Wort für einen Injektor:
Der Injektor stellt die Dienste in den Client. Oft baut es auch den Client. Ein Injektor kann eine sehr komplexe Objektgrafik verbinden, indem er ein Objekt wie einen Client und später als einen Dienst für einen anderen Client behandelt. Der Injektor kann tatsächlich viele Objekte sein, die zusammenarbeiten, ist aber möglicherweise nicht der Client. Der Injektor kann mit anderen Namen bezeichnet werden, wie zum Beispiel: Assembler, Provider, Container, Fabrik, Builder, Feder, Konstruktionscode oder Haupt. - https://en.wikipedia.org/wiki/Dependency_injection
Aureliens Behältersystem ist hierarchisch aufgebaut, was bedeutet, wenn Sie @inject
oder @autoinject
etwas, der Strom (Kind) Container werden für das Element gesucht werden, und wenn es nicht gefunden wird, wird der übergeordnete Container gesucht und usw., bis das Objekt gefunden oder der Root-Container gefunden wird. In diesem Fall erstellt Aurelia eine neue Instanz des angeforderten Objekts.
In Ihrem Code-Snippet Sie haben:
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();
}
}
Unter der Annahme, das ist ein Blick-Modells individuelle Element ist, das Sie wie folgt verwendet werden: <person-list></person-list>
, hier ist, was passieren wird, wenn Aurelia die PersonList
instanziiert.
- Ein untergeordneter Container wird aus dem aktuellen Container erstellt (mehr zu dem, was der "aktuelle Container" später ist). Entspricht dem Aufruf
container.createChildContainer()
. Wir nennen diesen untergeordneten Container "childContainer
".
- Kontextelemente werden im untergeordneten Container registriert, z. B. das DOM-Element (die Ansicht) für das View-Modell PersonList. Dies entspricht dem Aufruf
childContainer.registerInstance(Element, personListDomElement)
. Warum? Denn dadurch können Entwickler @inject(Element)
(oder @autoinject
gleichwertig).
Sobald der untergeordnete Container konfiguriert ist, wird er verwendet, um eine Instanz der PersonList
zu erstellen. Äquivalent Aufruf:
personList = childContainer.invoke(PersonList);
childContainer.registerInstance(PersonList, personList);
Das Kind Container nichts mit dem Schlüssel registriert hat „PersonService
“, so dass es übergeordneten Container ist durchsucht werden, bis es gefunden oder nicht gefunden werden kann, in welchem Fall Aurelia ein Konstrukt neue Instanz von PersonService
und registrieren Sie sie im Stammcontainer, damit die Instanz in nachfolgenden Suchvorgängen wiederverwendet werden kann.
- Die Personenliste viewmodel und view werden von der Templating-Engine erstellt, und die Lebenszyklusereignisse created, bind, attached etc passieren.
Bonus: ich früher erwähnt ein Kind Behälter aus dem aktuellen Container erstellt werden ... Jede Aurelia Anwendung verfügt über eine „Root-Ebene“ Container, der jedes Kind Container aus, die direkt oder indirekt absteigt. Aurelias Kern-Anwendungsdienste sind im Root-Container registriert: BindingEngine
, ObserverLocator
, TaskQueue
und viele mehr. Dies ermöglicht Entwicklern, @inject(TaskQueue)
zu schreiben und dieselbe TaskQueue-Instanz zu erhalten, die das Aurelia-Framework intern verwendet. Wenn ein benutzerdefiniertes Element oder ein benutzerdefiniertes Attribut instanziiert wird, wird ein untergeordneter Container verwendet, um das benutzerdefinierte Element oder benutzerdefinierte Attribut zu erstellen. Wenn dieses benutzerdefinierte Element ein anderes benutzerdefiniertes Element enthält, wird ein untergeordneter Container aus dem aktuellen untergeordneten Container erstellt und zum Instanziieren des untergeordneten benutzerdefinierten Elements usw. verwendet.Mit anderen Worten, der "aktuelle Container" hängt davon ab, wie tief Ihre Komponente in einer Hierarchie von geschachtelten benutzerdefinierten Elementen und benutzerdefinierten Attributen liegt.
Links: