Heim  >  Artikel  >  Web-Frontend  >  Implementierung der JavaScript-Abhängigkeitsinjektion

Implementierung der JavaScript-Abhängigkeitsinjektion

黄舟
黄舟Original
2017-02-21 11:53:181752Durchsuche



Mit der Popularität von AngularJS hat die Abhängigkeitsinjektion im JavaScript-Bereich zunehmend an Aufmerksamkeit gewonnen. Der wichtigste Vorteil von DI ist die Entwicklung wiederverwendbarer und testbarer Codeeinheiten. In diesem Artikel wird der Implementierungsmechanismus von DI anhand von einfachem Code erläutert. Weitere Informationen zu den Vor- und Nachteilen von DI finden Sie unter: Wann sollten Sie die Abhängigkeitsinjektion verwenden?

Ein grundlegender DI-Anwendungsfall

Jedes Modul deklariert seine eigenen Abhängigkeiten und stellt seine eigenen Dienste bereit. Beispiel:

di.service('foo', ['bar'], function foo(bar){ function Foo(){ this.bar = bar;
    } this.prototype.greeting = function(){ console.log('hello, world');
    } return Foo;
}); var foo = di.container.get('foo');
foo.greeting();

Beachten Sie den Unterschied zwischen Abhängigkeitsinjektion und CommonJS (oder AMD). foo muss nur seine Abhängigkeitsleiste deklarieren und muss sie nicht aktiv abrufen. Dies führt dazu, dass die Funktion foo den Speicherort und die Konstruktionsmethode von Abhängigkeiten überhaupt nicht kennt, wodurch die Funktion foo zu einer testbaren und wiederverwendbaren Codeeinheit wird.

Design des DI-Frameworks

Die Registrierung von Diensten und die Nutzung von Diensten sollten zu unterschiedlichen Zeiten erfolgen. Als spezielles Tool zur Abhängigkeitsauflösung unterteilt das DI-Framework den Lebenszyklus einer Softwareeinheit in eine Registrierungsphase und eine Ausführungsphase. Im obigen Beispiel werden Foo- und Bar-Dienste während der Registrierungsphase bereitgestellt und diese Dienste werden während der Laufzeitphase abgerufen und verwendet. Die meisten DI-Frameworks verfolgen eine Lazy-Construction-Strategie, wodurch auch die Schwierigkeit der Konstruktion während der Registrierungsphase vermieden wird.

Die Serviceanpassung kann nach der Registrierungsphase und vor der Ausführungsphase erfolgen. AngularJS 1 führt die Konfigurationsphase zur Anpassung dieser Dienste ein, und sein Anbieter kann als spezialisiertes Factory-Objekt verstanden werden. BottleJS verwendet Dekoratoren und Middleware, um die Anpassung von Diensten zu unterstützen.

Verwenden Sie einen IoC-Container, um Dienstinstanzen zu indizieren oder Dienstanbieter zu speichern. Wenn jemand einen Dienst bereitstellt, wird er dem Container hinzugefügt. Wenn jemand den Dienst nutzt, wird der Anbieter im Container gefunden und eine Dienstinstanz generiert. Oft können Dienstinstanzen zwischengespeichert werden.

Implementierung des DI-Frameworks

Zunächst implementieren wir die gebräuchlichste Schnittstellenfunktion .service(), die zum Registrieren des Konstruktors eines Dienstes verwendet wird. Die übergebene Funktion wird neu ausgeführt.

var di = {
    container: {}
};

di.service = function(name, Constructor) {
    defineLazyProperty(name, () => new Constructor());
}; function defineLazyProperty(name, getter){ Object.defineProperty(di.container, name, {
        configurable: true,
        get: function() { var obj = getter(container); Object.defineProperty(di.container, name, {
                configurable: false value: obj
            }); return obj;
        }
    });
}

Object.defineProperty wird hier für das Service-Caching verwendet. Der Konstruktor wird nur beim ersten Erstellen des Dienstes aufgerufen und nachfolgende Zugriffe lesen direkt die Eigenschaften des IoC-Containers. Es ist eine Standardmethode von ES5 und weist eine sehr gute Kompatibilität auf. Mit der Methode defineLazyProperty() ist die Implementierung dieser häufig verwendeten Registrierungsschnittstellen sehr intuitiv:

di.factory = function(name, factory) { return defineLazyProperty(name, factory);
};

di.provider = function(name, Provider) { return defineLazyProperty(name, function(){ var provider = new Provider(); return provider.$get();
    });
};

di.value = function(name, val) { return defineLazyProperty(name, () => val);
};

Die benutzerdefinierte Schnittstelle des Dienstes wird nicht im Detail beschrieben. Es ist erwähnenswert, dass eine einheitliche Dienstanpassung erforderlich ist Unified Services. Konstruktor statt .defineLazyProperty() direkt aufzurufen, um Eigenschaften zu generieren. Diese Strategien in AngularJS werden vom Anbieter implementiert, und alle anderen Dienstregistrierungsmethoden werden vom Anbieter implementiert.

Das Obige ist der Inhalt der Implementierung der JavaScript-Abhängigkeitsinjektion. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn