Ich erstelle gerade einige experimentelle Projekte mit nodejs. Ich habe viele Java EE-Webanwendungen mit Spring programmiert und die einfache Möglichkeit der Abhängigkeitsinjektion dort geschätzt.
Jetzt bin ich neugierig: Wie mache ich eine Abhängigkeitsinjektion mit einem Knoten? Oder: Brauche ich es überhaupt? Gibt es ein Ersatzkonzept, weil der Programmierstil anders ist?
Ich spreche bisher über einfache Dinge, wie das Teilen eines Datenbankverbindungsobjekts, aber ich habe keine Lösung gefunden, die mich zufriedenstellt.
Antworten:
Kurz gesagt, Sie benötigen keinen Abhängigkeitsinjektionscontainer oder Service-Locater wie in C # / Java. Da Node.js das nutzt
module pattern
, ist es nicht erforderlich, eine Konstruktor- oder Eigenschaftsinjektion durchzuführen. Obwohl du es immer noch kannst.Das Tolle an JS ist, dass Sie fast alles ändern können, um das zu erreichen, was Sie wollen. Dies ist praktisch, wenn es um Tests geht.
Siehe mein sehr lahmes erfundenes Beispiel.
MyClass.js
::MyClass.test.js
::Beachten Sie, wie
MyClass
abhängig vomfs
Modul? Wie @ShatyemShekhar erwähnt hat, können Sie tatsächlich Konstruktor- oder Eigenschaftsinjektionen wie in anderen Sprachen durchführen. In Javascript ist dies jedoch nicht erforderlich.In diesem Fall können Sie zwei Dinge tun.
Sie können die
fs.readdirSync
Methode stubben oder beim Aufruf ein völlig anderes Modul zurückgebenrequire
.Methode 1:
Methode 2:
Der Schlüssel besteht darin, die Leistung von Node.js und Javascript zu nutzen. Beachten Sie, dass ich ein CoffeeScript-Typ bin, daher ist meine JS-Syntax möglicherweise irgendwo falsch. Ich sage auch nicht, dass dies der beste Weg ist, aber es ist ein Weg. Javascript-Gurus können möglicherweise mit anderen Lösungen mithalten.
Aktualisieren:
Dies sollte Ihre spezifische Frage bezüglich Datenbankverbindungen beantworten. Ich würde ein separates Modul für Sie erstellen, um Ihre Datenbankverbindungslogik zu kapseln. Etwas wie das:
MyDbConnection.js
: (Achten Sie darauf, einen besseren Namen zu wählen)Dann würde jedes Modul, das eine Datenbankverbindung benötigt, nur Ihr
MyDbConnection
Modul enthalten.SuperCoolWebApp.js
::Folgen Sie diesem Beispiel nicht wörtlich. Es ist ein lahmes Beispiel für den Versuch zu kommunizieren, dass Sie das
module
Muster nutzen, um Ihre Abhängigkeiten zu verwalten. Hoffentlich hilft das ein bisschen mehr.quelle
require('my_logger_library')
, müssen Benutzer, die meine Komponente verwenden, die Anforderung überschreiben, ihre eigene Bibliothek zu verwenden. Stattdessen kann ich zulassen, dass Benutzer einen Rückruf übergeben, der eine Logger-Implementierung in die Komponentenmethode "Konstruktor" oder "Init" einschließt. Das ist der Zweck von DI.require
ist die Art und Weise, Abhängigkeiten in Node.js zu verwalten, und sicherlich intuitiv und effektiv, hat aber auch seine Grenzen.Mein Rat ist, einen Blick auf einige der heute für Node.js verfügbaren Dependency Injection-Container zu werfen, um eine Vorstellung von ihren Vor- und Nachteilen zu bekommen. Einige von ihnen sind:
Nur um ein paar zu nennen.
Die eigentliche Frage ist nun, was Sie mit einem Node.js DI-Container im Vergleich zu einem einfachen erreichen können
require
.Vorteile:
Nachteile:
require
Wenn Sie nicht verwenden, fühlen Sie sich definitiv so, als würden Sie von der Node.-Denkweise abweichen.Wie bei allem, was mit Softwareentwicklung zu tun hat,
require
hängt die Wahl zwischen DI oder von Ihren Anforderungen, Ihrer Systemkomplexität und Ihrem Programmierstil ab.quelle
Ich weiß, dass dieser Thread zu diesem Zeitpunkt ziemlich alt ist, aber ich dachte, ich würde mich mit meinen Gedanken dazu einmischen. Das TL; DR ist, dass Sie aufgrund der untypisierten, dynamischen Natur von JavaScript tatsächlich ziemlich viel tun können, ohne auf das DI-Muster (Dependency Injection) zurückzugreifen oder ein DI-Framework zu verwenden. Wenn eine Anwendung jedoch größer und komplexer wird, kann DI definitiv zur Wartbarkeit Ihres Codes beitragen.
DI in C #
Um zu verstehen, warum DI in JavaScript nicht so dringend benötigt wird, ist es hilfreich, eine stark typisierte Sprache wie C # zu betrachten. (Entschuldigung an diejenigen, die C # nicht kennen, aber es sollte leicht zu befolgen sein.) Angenommen, wir haben eine App, die ein Auto und seine Hupe beschreibt. Sie würden zwei Klassen definieren:
Es gibt nur wenige Probleme beim Schreiben des Codes auf diese Weise.
Car
Klasse ist eng an die jeweilige Implementierung des Horns in derHorn
Klasse gekoppelt . Wenn wir die Art der vom Auto verwendeten Hupe ändern möchten, müssen wir dieCar
Klasse ändern , obwohl sich die Verwendung der Hupe nicht ändert. Dies macht das Testen auch schwierig, da wir dieCar
Klasse nicht isoliert von ihrer Abhängigkeit, derHorn
Klasse, testen können .Car
Klasse ist für den Lebenszyklus derHorn
Klasse verantwortlich. In einem einfachen Beispiel wie diesem ist dies kein großes Problem, aber in realen Anwendungen haben Abhängigkeiten Abhängigkeiten, Abhängigkeiten usw. DieCar
Klasse müsste für die Erstellung des gesamten Baums ihrer Abhängigkeiten verantwortlich sein. Dies ist nicht nur kompliziert und wiederholt, sondern verstößt auch gegen die "Einzelverantwortung" der Klasse. Es sollte sich darauf konzentrieren, ein Auto zu sein und keine Instanzen zu erstellen.Lassen Sie uns dies nun umgestalten, um ein Abhängigkeitsinjektionsmuster zu verwenden.
Wir haben hier zwei wichtige Dinge getan. Zuerst haben wir eine Schnittstelle eingeführt, die unsere
Horn
Klasse implementiert. Auf diese Weise können wir dieCar
Klasse anstelle der jeweiligen Implementierung für die Schnittstelle codieren . Jetzt könnte der Code alles aufnehmen, was implementiert wirdIHorn
. Zweitens haben wir die Horninstanziierung herausgenommenCar
und stattdessen weitergegeben. Dies behebt die oben genannten Probleme und überlässt es der Hauptfunktion der Anwendung, die spezifischen Instanzen und ihre Lebenszyklen zu verwalten.Dies bedeutet, dass eine neue Art von Hupe für das Auto eingeführt werden könnte, ohne die
Car
Klasse zu berühren :Der Main könnte
FrenchHorn
stattdessen einfach eine Instanz der Klasse einfügen. Dies vereinfacht auch das Testen erheblich. Sie können eineMockHorn
Klasse erstellen , die in denCar
Konstruktor eingefügt werden soll, um sicherzustellen, dass Sie nur dieCar
Klasse isoliert testen .Das obige Beispiel zeigt die manuelle Abhängigkeitsinjektion. Normalerweise wird DI mit einem Framework durchgeführt (z. B. Unity oder Ninject in der C # -Welt ). Diese Frameworks übernehmen die gesamte Abhängigkeitsverdrahtung für Sie, indem sie Ihr Abhängigkeitsdiagramm durchlaufen und nach Bedarf Instanzen erstellen.
Der Standard Node.js Weg
Schauen wir uns nun dasselbe Beispiel in Node.js an. Wir würden unseren Code wahrscheinlich in 3 Module aufteilen:
Da JavaScript untypisiert ist, haben wir nicht die gleiche enge Kopplung wie zuvor. Schnittstellen sind nicht erforderlich (und existieren auch nicht), da das
car
Modul nur versucht, diehonk
Methode für allehorn
Exporte des Moduls aufzurufen .Da Node
require
alles zwischenspeichert, sind Module im Wesentlichen Singletons, die in einem Container gespeichert sind. Jede andere Modul , das eine führtrequire
auf demhorn
Modul genau die gleiche Instanz erhalten. Dies macht das Teilen von Singleton-Objekten wie Datenbankverbindungen sehr einfach.Jetzt gibt es immer noch das Problem, dass das
car
Modul für das Abrufen seiner eigenen Abhängigkeit verantwortlich isthorn
. Wenn Sie möchten, dass das Auto ein anderes Modul für die Hupe verwendet, müssen Sie dierequire
Anweisung imcar
Modul ändern . Dies ist nicht sehr häufig, führt jedoch zu Problemen beim Testen.Die übliche Art und Weise, wie Benutzer mit dem Testproblem umgehen, ist die Verwendung von Proxyquire . Aufgrund der Dynamik von JavaScript fängt Proxyquire Aufrufe ab, die erforderlich sind, und gibt stattdessen alle von Ihnen bereitgestellten Stubs / Mocks zurück.
Dies ist für die meisten Anwendungen mehr als ausreichend. Wenn es für Ihre App funktioniert, gehen Sie damit. Nach meiner Erfahrung, wenn Anwendungen größer und komplexer werden, wird es jedoch schwieriger, solchen Code zu verwalten.
DI in JavaScript
Node.js ist sehr flexibel. Wenn Sie mit der obigen Methode nicht zufrieden sind, können Sie Ihre Module mithilfe des Abhängigkeitsinjektionsmusters schreiben. In diesem Muster exportiert jedes Modul eine Factory-Funktion (oder einen Klassenkonstruktor).
Dies ist sehr ähnlich zu der früheren C # -Methode, da das
index.js
Modul beispielsweise für Lebenszyklen und Verkabelung verantwortlich ist. Unit-Tests sind recht einfach, da Sie nur Mocks / Stubs an die Funktionen übergeben können. Auch wenn dies für Ihre Anwendung gut genug ist, machen Sie mit.Bolus DI Framework
Im Gegensatz zu C # gibt es keine etablierten Standard-DI-Frameworks, die Sie beim Abhängigkeitsmanagement unterstützen. Es gibt eine Reihe von Frameworks in der npm-Registrierung, aber keines ist weit verbreitet. Viele dieser Optionen wurden bereits in den anderen Antworten zitiert.
Ich war mit keiner der verfügbaren Optionen besonders zufrieden und schrieb meinen eigenen Bolus . Bolus wurde entwickelt, um mit Code zu arbeiten, der im obigen DI-Stil geschrieben wurde, und versucht, sehr trocken und sehr einfach zu sein. Mit genau demselben
car.js
und denhorn.js
oben genannten Modulen können Sie dasindex.js
Modul mit Bolus wie folgt umschreiben :Die Grundidee ist, dass Sie einen Injektor erstellen. Sie registrieren alle Ihre Module im Injektor. Dann lösen Sie einfach, was Sie brauchen. Bolus geht durch das Abhängigkeitsdiagramm und erstellt und fügt nach Bedarf Abhängigkeiten ein. In einem solchen Spielzeugbeispiel sparen Sie nicht viel, aber in großen Anwendungen mit komplizierten Abhängigkeitsbäumen sind die Einsparungen enorm.
Bolus unterstützt eine Reihe von nützlichen Funktionen wie optionale Abhängigkeiten und Testglobale, aber es gibt zwei Hauptvorteile, die ich im Vergleich zum Standardansatz von Node.js gesehen habe. Wenn Sie viele ähnliche Anwendungen haben, können Sie zunächst ein privates npm-Modul für Ihre Basis erstellen, das einen Injektor erstellt und nützliche Objekte darauf registriert. Dann können Ihre spezifischen Apps nach Bedarf hinzufügen, überschreiben und auflösen, ähnlich wie AngularJSInjektor funktioniert. Zweitens können Sie mit Bolus verschiedene Abhängigkeitskontexte verwalten. Sie können beispielsweise Middleware verwenden, um pro Anforderung einen untergeordneten Injektor zu erstellen, die Benutzer-ID, die Sitzungs-ID, den Logger usw. auf dem Injektor zusammen mit allen davon abhängigen Modulen zu registrieren. Lösen Sie dann, was Sie benötigen, um Anfragen zu bearbeiten. Dies gibt Ihnen Instanzen Ihrer Module pro Anforderung und verhindert, dass Sie den Logger usw. an jeden Modulfunktionsaufruf weitergeben müssen.
quelle
proxyquire
solchen gibt,sinon
die es Ihnen ermöglichen, sehr präzise Verspottungen durchzuführen, z. B.let readFileStub = sinon.stub(fs, 'readFile').yields(new Error('something went wrong'));
und nachfolgende Aufrufe vonfs.readFile
geben Fehler zurück, bis Sie den Stub über zurücksetzenreadFileStub.restore()
. Persönlich finde ich DI von fragwürdigem Nutzen, weil ich das Gefühl habe, dass es fast die Verwendung von Klassen / Objekten erfordert, was angesichts der funktionalen Neigungen von Javascript eine zweifelhafte Annahme ist.jest
,rewire
,proxyquire
etc.? Vielen Dank.Ich habe auch ein Modul geschrieben, um dies zu erreichen. Es heißt rewire . Einfach benutzen
npm install rewire
und dann:Ich habe mich von Nathan MacInnes 'Injektion inspirieren lassen, aber einen anderen Ansatz gewählt. Ich benutze nicht,
vm
um das Testmodul zu evaluieren, sondern ich benutze die eigenen Anforderungen des Knotens. Auf diese Weise verhält sich Ihr Modul genau wie die Verwendungrequire()
(mit Ausnahme Ihrer Änderungen). Auch das Debuggen wird vollständig unterstützt.quelle
Ich habe Elektrolyt nur für diesen Zweck gebaut. Die anderen Abhängigkeitsinjektionslösungen da draußen waren für meinen Geschmack zu invasiv, und das Durcheinander mit dem Globalen
require
ist eine besondere Beschwerde von mir.Elektrolyt umfasst Module, insbesondere solche, die eine "Setup" -Funktion exportieren, wie Sie sie in der Connect / Express-Middleware sehen. Im Wesentlichen sind diese Modultypen nur Fabriken für ein Objekt, das sie zurückgeben.
Beispiel: Ein Modul, das eine Datenbankverbindung erstellt:
Was Sie unten sehen, sind Anmerkungen , ein zusätzliches Stück Metadaten, das Electrolyte verwendet, um Abhängigkeiten zu instanziieren und einzufügen, wobei die Komponenten Ihrer Anwendung automatisch miteinander verbunden werden.
So erstellen Sie eine Datenbankverbindung:
Der Elektrolyt durchläuft transitiv die
@require
'd-Abhängigkeiten und fügt Instanzen als Argumente in die exportierte Funktion ein.Der Schlüssel ist, dass dies minimal invasiv ist. Dieses Modul ist unabhängig vom Elektrolyten selbst vollständig verwendbar. Das bedeutet, dass Ihre Komponententests nur das zu testende Modul testen können und Scheinobjekte übergeben, ohne dass zusätzliche Abhängigkeiten erforderlich sind, um Interna neu zu verdrahten.
Wenn die vollständige Anwendung ausgeführt wird, greift Electrolyte auf der Ebene zwischen den Modulen ein und verdrahtet die Dinge, ohne dass Globals, Singletons oder übermäßige Leitungen erforderlich sind.
quelle
connect()
Werfen gepostet haben ? Obwohl ich mit der MySql-API für Node nicht vertraut bin, würde ich erwarten, dass dieser Aufruf asynchron ist, sodass die Abbildung nicht ganz klar ist.ioc.create
von einem Unit-Test anrufen . Ein Komponententest sollte nur das zu testende Modul testen und keine anderen Abhängigkeiten, einschließlich Elektrolyt, berücksichtigen. Wenn Sie diesem Rat folgen, würden Sie tunobjToTest = require('modulename')(mockObj1, mockObj2);
Ich habe das selbst untersucht. Ich mag es nicht, magische Abhängigkeits-Utils-Bibliotheken einzuführen, die Mechanismen zum Entführen meiner Modulimporte bereitstellen. Stattdessen habe ich eine "Konstruktionsrichtlinie" für mein Team erstellt, in der ziemlich explizit angegeben wird, welche Abhängigkeiten verspottet werden können, indem ein Factory-Funktionsexport in meine Module eingeführt wird.
Ich verwende ES6-Funktionen in großem Umfang für Parameter und Destrukturierung, um einige Boilerplates zu vermeiden und einen benannten Mechanismus zum Überschreiben von Abhängigkeiten bereitzustellen.
Hier ist ein Beispiel:
Und hier ist ein Beispiel für die Verwendung
Entschuldigen Sie die ES6-Syntax für diejenigen, die damit nicht vertraut sind.
quelle
Ich habe diesen Thread kürzlich aus dem gleichen Grund wie das OP überprüft - die meisten Bibliotheken, auf die ich gestoßen bin, haben die require-Anweisung vorübergehend neu geschrieben. Ich hatte gemischte Erfolge mit dieser Methode und habe daher den folgenden Ansatz gewählt.
Im Kontext einer Express-Anwendung - ich verpacke app.js in eine bootstrap.js-Datei:
Die an den Loader übergebene Objektzuordnung sieht folgendermaßen aus:
Dann, anstatt direkt anzurufen, benötigen ...
Wenn sich im Loader kein Alias befindet, wird standardmäßig eine reguläre Anforderung verwendet. Dies hat zwei Vorteile: Ich kann jede Version der Klasse austauschen, sodass keine relativen Pfadnamen in der gesamten Anwendung verwendet werden müssen. Wenn ich also eine benutzerdefinierte Bibliothek unter oder über der aktuellen Datei benötige, muss ich nicht durchlaufen , und require wird das Modul gegen denselben Schlüssel zwischenspeichern). Außerdem kann ich Mocks an jedem Punkt in der App und nicht in der unmittelbaren Testsuite angeben.
Ich habe gerade ein kleines npm-Modul veröffentlicht:
https://npmjs.org/package/nodejs-simple-loader
quelle
Die Realität ist, dass Sie Ihre node.js ohne IoC-Container testen können, da JavaScript eine sehr dynamische Programmiersprache ist und Sie fast alles zur Laufzeit ändern können.
Folgendes berücksichtigen:
So können Sie die Kopplung zwischen Komponenten zur Laufzeit überschreiben. Ich denke gerne, dass wir versuchen sollten, unsere JavaScript-Module zu entkoppeln.
Die einzige Möglichkeit, eine echte Entkopplung zu erreichen, besteht darin, den Verweis auf Folgendes zu entfernen
UserRepository
:Dies bedeutet, dass Sie irgendwo anders die Objektkomposition durchführen müssen:
Ich mag die Idee, die Objektzusammensetzung an einen IoC-Container zu delegieren. Weitere Informationen zu dieser Idee finden Sie im Artikel Der aktuelle Status der Abhängigkeitsinversion in JavaScript . Der Artikel versucht, einige "JavaScript IoC Container Mythen" zu entlarven:
Wenn Ihnen auch die Idee gefällt, einen IoC-Container zu verwenden, können Sie sich InversifyJS ansehen. Die neueste Version (2.0.0) unterstützt viele Anwendungsfälle:
Weitere Informationen finden Sie unter InversifyJS .
quelle
Für ES6 habe ich diesen Container https://github.com/zazoomauro/node-dependency-injection entwickelt
Dann können Sie zum Beispiel die Wahl des Transports im Container einstellen:
Diese Klasse ist jetzt viel flexibler, da Sie die Auswahl des Transports von der Implementierung in den Container getrennt haben.
Nachdem sich der Mailer-Dienst im Container befindet, können Sie ihn als Abhängigkeit von anderen Klassen einfügen. Wenn Sie eine NewsletterManager-Klasse wie diese haben:
Bei der Definition des Dienstes newsletter_manager ist der Mailer-Dienst noch nicht vorhanden. Verwenden Sie die Referenzklasse, um den Container anzuweisen, den Mailer-Service zu injizieren, wenn er den Newsletter-Manager initialisiert:
Sie können den Container auch mit Konfigurationsdateien wie Yaml-, Json- oder JS-Dateien einrichten
Der Service-Container kann aus verschiedenen Gründen zusammengestellt werden. Zu diesen Gründen gehört es, nach potenziellen Problemen wie Zirkelverweisen zu suchen und den Container effizienter zu gestalten.
quelle
Dies hängt vom Design Ihrer Anwendung ab. Sie können natürlich eine Java-ähnliche Injektion ausführen, bei der Sie ein Objekt einer Klasse mit der im Konstruktor übergebenen Abhängigkeit erstellen.
Wenn Sie OOP nicht in Javascript ausführen, können Sie eine Init-Funktion erstellen, die alles einrichtet.
Es gibt jedoch einen anderen Ansatz, der in einem ereignisbasierten System wie node.js üblicher ist. Wenn Sie Ihre Anwendung so modellieren können, dass sie nur (meistens) auf Ereignisse reagiert, müssen Sie lediglich alles einrichten (was ich normalerweise durch Aufrufen einer Init-Funktion mache) und Ereignisse von einem Stub ausgeben. Dies macht das Testen ziemlich einfacher und lesbarer.
quelle
Die Einfachheit des IoC-Konzepts hat mir immer gefallen: "Sie müssen nichts über die Umgebung wissen, Sie werden bei Bedarf von jemandem angerufen."
Aber alle IoC-Implementierungen, die ich gesehen habe, haben genau das Gegenteil bewirkt - sie überladen den Code mit noch mehr Dingen als ohne. Also habe ich mein eigenes IoC erstellt, das so funktioniert, wie ich es gerne hätte - es bleibt 90% der Zeit verborgen und unsichtbar .
Es wird im MonoJS-Webframework http://monojs.org verwendet
Es geht so - registrieren Sie die Komponente einmal in der Konfiguration.
Und überall verwenden
Den vollständigen Komponentendefinitionscode (mit DB Connection und anderen Komponenten) finden Sie hier https://github.com/sinizinairina/mono/blob/master/mono.coffee
Dies ist der einzige Ort, an dem Sie IoC mitteilen müssen, was zu tun ist. Danach werden alle diese Komponenten automatisch erstellt und verkabelt, und Sie müssen keinen IoC-spezifischen Code mehr in Ihrer Anwendung sehen.
Das IoC selbst https://github.com/alexeypetrushin/miconjs
quelle
Ich denke, wir brauchen immer noch Dependency Injection in Nodejs, weil es die Abhängigkeiten zwischen Diensten löst und die Anwendung klarer macht.
Inspiriert von Spring Framework implementiere ich auch mein eigenes Modul, um die Abhängigkeitsinjektion in Nodejs zu unterstützen. Mein Modul kann auch die
code changes
undauto reload
die Dienste erkennen, ohne Ihre Anwendung neu zu starten.Besuchen Sie mein Projekt unter: Buncha - IoC Container
Danke dir!
quelle
Schauen Sie sich dips an (Ein einfaches, aber leistungsstarkes Framework für die Abhängigkeitsinjektion und die Verwaltung von Entitäten (Dateien) für Node.js).
https://github.com/devcrust/node-dips
quelle
Ich habe lange mit .Net, PHP und Java gearbeitet, daher wollte ich auch in NodeJS eine bequeme Abhängigkeitsinjektion haben. Die Leute sagten, dass die in NodeJS integrierte DI ausreicht, da wir sie mit Module erhalten können. Aber es hat mich nicht gut befriedigt. Ich wollte ein Modul nicht mehr als eine Klasse behalten. Außerdem wollte ich, dass der DI die Verwaltung des Modullebenszyklus (Singleton-Modul, Transient-Modul usw.) vollständig unterstützt, aber mit dem Node-Modul musste ich sehr oft manuellen Code schreiben. Zuletzt wollte ich Unit Test einfacher machen. Deshalb habe ich mir eine Abhängigkeitsinjektion erstellt.
Wenn Sie nach einem DI suchen, probieren Sie es aus. Es kann hier gefunden werden: https://github.com/robo-creative/nodejs-robo-container . Es ist vollständig dokumentiert. Es werden auch einige häufig auftretende Probleme mit DI und deren Lösung auf OOP-Weise behandelt. Ich hoffe es hilft.
quelle
Ich habe kürzlich eine Bibliothek namens Circuitbox erstellt , mit der Sie die Abhängigkeitsinjektion mit node.js verwenden können. Es macht echte Abhängigkeitsinjektion im Vergleich zu vielen der auf Abhängigkeitssuche basierenden Bibliotheken, die ich gesehen habe. Circuitbox unterstützt auch Routinen zur asynchronen Erstellung und Initialisierung. Unten ist ein Beispiel:
Angenommen, der folgende Code befindet sich in einer Datei namens consoleMessagePrinter.js
Angenommen, in der Datei main.js befindet sich Folgendes
Mit Circuitbox können Sie Ihre Komponenten definieren und ihre Abhängigkeiten als Module deklarieren. Nach der Initialisierung können Sie eine Komponente abrufen. Circuitbox injiziert automatisch alle Komponenten, die die Zielkomponente benötigt, und gibt sie Ihnen zur Verwendung.
Das Projekt ist in der Alpha-Version. Ihre Kommentare, Ideen und Rückmeldungen sind willkommen.
Ich hoffe es hilft!
quelle
Ich denke, andere Beiträge haben bei der Argumentation für die Verwendung von DI großartige Arbeit geleistet. Für mich sind die Gründe
Injizieren Sie Abhängigkeiten, ohne ihre Pfade zu kennen. Dies bedeutet, dass Sie nicht jede davon abhängige Datei berühren müssen, wenn Sie einen Modulspeicherort auf der Festplatte ändern oder durch einen anderen austauschen.
Es macht es viel einfacher, Abhängigkeiten zum Testen zu verspotten, ohne die globale
require
Funktion auf eine Weise überschreiben zu müssen, die problemlos funktioniert.Es hilft Ihnen, Ihre Anwendung als lose gekoppelte Module zu organisieren und zu begründen.
Es fiel mir jedoch sehr schwer, ein DI-Framework zu finden, das mein Team und ich problemlos übernehmen können. Deshalb habe ich kürzlich ein Framework namens deppie erstellt, das auf diesen Funktionen basiert
require
Modulenquelle
Es sollte so flexibel und einfach sein:
Ich habe einen Artikel über Abhängigkeitsinjektion in node.js geschrieben.
Ich hoffe es kann dir dabei helfen.
quelle
Node.js benötigt DI genauso wie jede andere Plattform. Wenn Sie etwas Großes erstellen, wird DI es einfacher machen, die Abhängigkeiten Ihres Codes zu verspotten und Ihren Code gründlich zu testen.
Beispielsweise sollten Ihre Datenbankschichtmodule nicht nur für Ihre Geschäftscodemodule erforderlich sein, da beim Testen dieser Geschäftscodemodule durch die Einheit die Daos geladen werden und eine Verbindung zur Datenbank hergestellt wird.
Eine Lösung wäre, die Abhängigkeiten als Modulparameter zu übergeben:
Auf diese Weise können Abhängigkeiten einfach und natürlich verspottet werden und Sie können sich weiterhin auf das Testen Ihres Codes konzentrieren, ohne eine knifflige Bibliothek von Drittanbietern zu verwenden.
Es gibt andere Lösungen (Broadway, Architekt usw.), die Ihnen dabei helfen können. obwohl sie mehr tun können, als Sie wollen, oder mehr Unordnung verwenden.
quelle
Ich habe eine Bibliothek entwickelt, die die Abhängigkeitsinjektion auf einfache Weise handhabt und den Boilerplate-Code verringert. Jedes Modul wird durch einen eindeutigen Namen und eine Steuerungsfunktion definiert. Die Parameter der Steuerung spiegeln die Abhängigkeiten des Moduls wider.
Lesen Sie mehr über KlarkJS
Kurzes Beispiel:
myModuleName1
ist der Name des Moduls.$nodeModule1
ist eine externe Bibliothek vonnode_module
. Der Name wird in aufgelöstnode-module1
. Das Präfix$
gibt an, dass es sich um ein externes Modul handelt.myModuleName2
ist der Name eines internen Moduls.myModuleName1
.quelle
Ich habe diese Frage bei der Beantwortung eines Problems entdeckt in meinem eigenen DI-Modul geantwortet habe, warum man jemals ein DI-System für die NodeJS-Programmierung benötigen würde.
Die Antwort tendierte eindeutig zu den in diesem Thread angegebenen: Es kommt darauf an. Es gibt Kompromisse für beide Ansätze, und das Lesen der Antworten dieser Frage gibt ihnen eine gute Form.
Die eigentliche Antwort auf diese Frage sollte also sein, dass Sie in einigen Situationen ein DI-System verwenden würden, in anderen nicht.
Als Entwickler möchten Sie sich jedoch nicht wiederholen und Ihre Dienste in Ihren verschiedenen Anwendungen wiederverwenden.
Dies bedeutet, dass wir Dienste schreiben sollten, die zur Verwendung im DI-System bereit sind, aber nicht an DI-Bibliotheken gebunden sind. Für mich bedeutet das, dass wir Dienste wie diesen schreiben sollten:
Auf diese Weise funktioniert Ihr Dienst unabhängig davon, ob Sie ihn mit oder ohne DI-Tool verwenden.
quelle
TypeDI ist das süßeste von allen hier genannten, schauen Sie sich diesen Code in TypeDI an
Schauen Sie sich auch diesen Code an:
quelle