Obecnie tworzę eksperymentalne projekty z nodejs. Z Springem zaprogramowałem wiele aplikacji Java EE i doceniam łatwość wstrzykiwania zależności.
Teraz jestem ciekawy: jak wykonać wstrzyknięcie zależności za pomocą węzła? Lub: Czy w ogóle go potrzebuję? Czy istnieje koncepcja zastępująca, ponieważ styl programowania jest inny?
Mówię o prostych rzeczach, jak na przykład udostępnianie obiektu połączenia z bazą danych, ale nie znalazłem rozwiązania, które mnie zadowoli.
Odpowiedzi:
Krótko mówiąc, nie potrzebujesz kontenera wstrzykiwania zależności ani lokalizatora usług, tak jak w języku C # / Java. Ponieważ Node.js wykorzystuje
module pattern
, nie jest konieczne wprowadzanie konstruktora lub właściwości. Chociaż nadal możesz.Wspaniałą rzeczą w JS jest to, że możesz modyfikować praktycznie wszystko, aby osiągnąć to, co chcesz. Jest to przydatne przy testowaniu.
Oto mój bardzo kiepski wymyślony przykład.
MyClass.js
:MyClass.test.js
:Zauważ, jak to
MyClass
zależy odfs
modułu? Jak wspomniano w @ShatyemShekhar, rzeczywiście można wykonać iniekcję konstruktora lub właściwości, tak jak w innych językach. Ale nie jest to konieczne w Javascript.W takim przypadku możesz zrobić dwie rzeczy.
Możesz usunąć
fs.readdirSync
metodę lub możesz zwrócić zupełnie inny moduł podczas wywoływaniarequire
.Metoda 1:
Metoda 2:
Kluczem jest wykorzystanie siły Node.js i Javascript. Uwaga: jestem facetem CoffeeScript, więc moja składnia JS może być gdzieś niepoprawna. Nie mówię też, że to najlepszy sposób, ale taki jest sposób. Guru JavaScript mogą być w stanie wejść do innych rozwiązań.
Aktualizacja:
To powinno odpowiedzieć na twoje konkretne pytanie dotyczące połączeń z bazą danych. Stworzę osobny moduł do kapsułkowania logiki połączenia z bazą danych. Coś takiego:
MyDbConnection.js
: (pamiętaj, aby wybrać lepszą nazwę)Następnie każdy moduł, który wymaga połączenia z bazą danych, po prostu zawiera Twój
MyDbConnection
moduł.SuperCoolWebApp.js
:Nie podążaj za tym przykładem dosłownie. To kiepski przykład próby komunikowania, że używasz
module
wzorca do zarządzania swoimi zależnościami. Mam nadzieję, że to pomoże trochę więcej.źródło
require('my_logger_library')
, osoby korzystające z mojego komponentu będą musiały zastąpić wymóg korzystania z własnej biblioteki. Zamiast tego mogę pozwolić ludziom na przekazanie wywołania zwrotnego, które otacza implementację programu rejestrującego do metody „konstruktor” lub „init”. Taki jest cel DI.require
jest sposobem zarządzania zależnościami w node.js i pewnie to jest intuicyjny i skuteczny, ale ma też swoje ograniczenia.Radzę rzucić okiem na niektóre z dostępnych dziś pojemników do wstrzykiwania zależności, aby Node.js zorientował się, jakie są ich zalety / wady. Niektórzy z nich są:
Żeby wymienić tylko kilka.
Teraz prawdziwe pytanie brzmi: co można osiągnąć za pomocą kontenera DI Node.js w porównaniu do prostego
require
?Plusy:
Cons:
require
zdecydowanie sprawia wrażenie odbiegającego od sposobu myślenia Node.Podobnie jak w przypadku wszystkich elementów związanych z tworzeniem oprogramowania, wybór pomiędzy DI lub
require
zależy od wymagań, złożoności systemu i stylu programowania.źródło
Wiem, że ten wątek jest w tym momencie dość stary, ale pomyślałem, że włączy się z moimi przemyśleniami na ten temat. TL; DR jest taki, że ze względu na nietypowy, dynamiczny charakter JavaScript, możesz naprawdę zrobić wiele bez uciekania się do wzorca wstrzykiwania zależności (DI) lub korzystania z frameworku DI. Ponieważ jednak aplikacja staje się większa i bardziej złożona, DI może zdecydowanie pomóc w utrzymaniu kodu.
DI w C #
Aby zrozumieć, dlaczego DI nie jest tak potrzebna w JavaScript, warto przyjrzeć się silnie napisanemu językowi, np. C #. (Przepraszam tych, którzy nie znają języka C #, ale powinno być wystarczająco łatwe do naśladowania.) Załóżmy, że mamy aplikację opisującą samochód i jego klakson. Zdefiniowałbyś dwie klasy:
Istnieje kilka problemów z pisaniem kodu w ten sposób.
Car
Klasa jest ściśle sprzężony z konkretnego wdrożenia róg wHorn
klasie. Jeśli chcemy zmienić rodzaj klaksonu używanego przez samochód, musimy zmodyfikowaćCar
klasę, nawet jeśli jego użycie nie zmieni się. Utrudnia to również testowanie, ponieważ nie możemy przetestowaćCar
klasy w oderwaniu od jej zależności,Horn
klasy.Car
Klasa jest odpowiedzialna za cykl życiaHorn
klasy. W prostym przykładzie, takim jak ten, nie jest to duży problem, ale w rzeczywistych aplikacjach zależności będą miały zależności, które będą miały zależności itp.Car
Klasa musiałaby być odpowiedzialna za utworzenie całego drzewa swoich zależności. Jest to nie tylko skomplikowane i powtarzalne, ale narusza „pojedynczą odpowiedzialność” klasy. Powinien koncentrować się na byciu samochodem, a nie na tworzeniu instancji.Refaktoryzujmy to, aby zastosować wzorzec wstrzykiwania zależności.
Zrobiliśmy tutaj dwie kluczowe rzeczy. Po pierwsze, wprowadziliśmy interfejs, który
Horn
implementuje nasza klasa. To pozwala nam kodowaćCar
klasę do interfejsu zamiast konkretnej implementacji. Teraz kod może wziąć wszystko, co implementujeIHorn
. Po drugie, usunęliśmy instancję klaksonuCar
i przekazaliśmy ją zamiast tego. To rozwiązuje powyższe problemy i pozostawia głównej funkcji aplikacji zarządzanie konkretnymi instancjami i ich cyklami życia.Oznacza to, że mógłby wprowadzić nowy rodzaj klaksonu do użycia w samochodzie bez dotykania
Car
klasy:Main może
FrenchHorn
zamiast tego wstrzyknąć instancję klasy. To również znacznie upraszcza testowanie. Możesz utworzyćMockHorn
klasę do wstrzyknięcia doCar
konstruktora, aby upewnić się, że testujesz tylkoCar
klasę w izolacji.Powyższy przykład pokazuje ręczne wstrzykiwanie zależności. Zazwyczaj DI odbywa się za pomocą frameworka (np. Unity lub Ninject w świecie C #). Ramy te wykonają wszystkie okablowanie zależności, przechodząc po wykresie zależności i tworząc instancje zgodnie z potrzebami.
Standardowy sposób Node.js
Teraz spójrzmy na ten sam przykład w Node.js. Prawdopodobnie podzielilibyśmy nasz kod na 3 moduły:
Ponieważ JavaScript jest bez typu, nie mamy takiego samego ścisłego sprzężenia, jakie mieliśmy wcześniej. Interfejsy nie są potrzebne (ani one nie istnieją), ponieważ
car
moduł będzie próbował wywołaćhonk
metodę niezależnie od tego, cohorn
moduł eksportuje.Dodatkowo, ponieważ Node
require
buforuje wszystko, moduły są zasadniczo singletonami przechowywanymi w kontenerze. Każdy inny moduł, który wykonuje arequire
nahorn
module, otrzyma dokładnie to samo wystąpienie. To sprawia, że udostępnianie pojedynczych obiektów, takich jak połączenia z bazą danych, jest bardzo łatwe.Teraz nadal istnieje problem, że
car
moduł jest odpowiedzialny za pobieranie własnej zależnościhorn
. Jeśli chcesz, aby samochód używał innego modułu dla klaksonu, musisz zmienićrequire
instrukcję wcar
module. Nie jest to zbyt powszechne, ale powoduje problemy z testowaniem.Zwykle ludzie radzą sobie z problemem testowania za pomocą proxyquire . Ze względu na dynamiczny charakter JavaScript, proxyquire przechwytuje wywołania wymagające i zwraca zamiast tego wszystkie kody pośredniczące / próbne.
To więcej niż wystarcza dla większości aplikacji. Jeśli działa w Twojej aplikacji, idź z nią. Jednak z mojego doświadczenia wynika, że aplikacje stają się większe i bardziej złożone, utrzymanie takiego kodu staje się trudniejsze.
DI w JavaScript
Node.js jest bardzo elastyczny. Jeśli powyższa metoda nie jest zadowalająca, możesz napisać moduły przy użyciu wzorca wstrzykiwania zależności. W tym wzorze każdy moduł eksportuje funkcję fabryki (lub konstruktora klasy).
Jest to bardzo analogiczne do wcześniejszej metody C #, ponieważ
index.js
moduł jest odpowiedzialny za np. Cykle życia i okablowanie. Testowanie jednostkowe jest dość proste, ponieważ można po prostu przekazać symulacje / kody pośredniczące do funkcji. Ponownie, jeśli jest to wystarczająco dobre dla twojej aplikacji, idź z nim.Bolus DI Framework
W przeciwieństwie do C #, nie ma ustalonych standardowych ram DI, które mogłyby pomóc w zarządzaniu zależnościami. Istnieje wiele struktur w rejestrze npm, ale żadna z nich nie jest szeroko rozpowszechniona. Wiele z tych opcji cytowano już w innych odpowiedziach.
Nie byłem szczególnie zadowolony z żadnej z dostępnych opcji, więc napisałem własną, zwaną bolusem . Bolus został zaprojektowany do pracy z kodem napisanym powyżej w stylu DI i stara się być bardzo SUCHY i bardzo prosty. Używając dokładnie tego samego
car.js
ihorn.js
powyższych modułów, możesz przepisaćindex.js
moduł bolusem jako:Podstawową ideą jest to, że tworzysz wtryskiwacz. Rejestrujesz wszystkie swoje moduły we wtryskiwaczu. Następnie po prostu rozwiązujesz to, czego potrzebujesz. Bolus przejdzie po wykresie zależności i w razie potrzeby utworzy i wstrzykuje zależności. Nie oszczędzasz dużo w takim przykładzie zabawki, ale w dużych aplikacjach ze skomplikowanymi drzewami zależności oszczędności są ogromne.
Bolus obsługuje wiele fajnych funkcji, takich jak opcjonalne zależności i globalne testy, ale są dwie kluczowe korzyści, które widziałem w porównaniu ze standardowym podejściem do Node.js. Po pierwsze, jeśli masz wiele podobnych aplikacji, możesz utworzyć prywatny moduł npm dla swojej bazy, który tworzy wtryskiwacz i rejestruje na nim przydatne obiekty. Następnie określone aplikacje mogą dodawać, zastępować i rozwiązywać w razie potrzeby, podobnie jak w AngularJSwtryskiwacz działa. Po drugie, możesz użyć bolusa do zarządzania różnymi kontekstami zależności. Na przykład można użyć oprogramowania pośredniego do utworzenia wtryskiwacza potomnego na żądanie, zarejestrować identyfikator użytkownika, identyfikator sesji, rejestrator itp. We wtryskiwaczu wraz z dowolnymi modułami zależnymi od nich. Następnie określ, czego potrzebujesz, aby obsłużyć żądania. Daje to instancje modułów na żądanie i zapobiega przekazywaniu rejestratora itp. Do każdego wywołania funkcji modułu.
źródło
proxyquire
takich,sinon
które pozwalają na wykonywanie bardzo zwięzłych prób, np.let readFileStub = sinon.stub(fs, 'readFile').yields(new Error('something went wrong'));
wtedy kolejne wywołaniafs.readFile
zwrócą błąd, dopóki nie cofniesz kodu pośredniczącegoreadFileStub.restore()
. Osobiście uważam, że DI ma wątpliwe zastosowanie, ponieważ wydaje mi się, że prawie wymaga użycia klas / obiektów, co jest wątpliwe, biorąc pod uwagę funkcjonalne pochodzenie javascript.jest
,rewire
,proxyquire
, itd.? Dzięki.Napisałem również moduł, aby to osiągnąć, nazywa się to rewire . Wystarczy użyć,
npm install rewire
a następnie:Zainspirował mnie aplikator Nathana MacInnesa, ale zastosowałem inne podejście. Nie używam
vm
do ewaluacji modułu testowego, w rzeczywistości używam własnych wymagań węzła. W ten sposób twój moduł zachowuje się dokładnie tak samo jak przy użyciurequire()
(z wyjątkiem twoich modyfikacji). Debugowanie jest również w pełni obsługiwane.źródło
Właśnie w tym celu zbudowałem elektrolit . Inne dostępne rozwiązania iniekcji zależności były zbyt inwazyjne dla moich upodobań, a bałagan w świecie
require
jest moim szczególnym zarzutem.Electrolyte obejmuje moduły, w szczególności te, które eksportują funkcję „konfiguracji”, jak widać w oprogramowaniu pośrednim Connect / Express. Zasadniczo tego typu moduły są tylko fabrykami dla niektórych zwracanych obiektów.
Na przykład moduł, który tworzy połączenie z bazą danych:
Na dole są adnotacje , dodatkowy kawałek metadanych, które Electrolyte wykorzystuje do tworzenia instancji i wstrzykiwania zależności, automatycznie łącząc ze sobą elementy aplikacji.
Aby utworzyć połączenie z bazą danych:
Elektrolit przechodzi tranzytowo
@require
zależności i wprowadza instancje jako argumenty do eksportowanej funkcji.Kluczem jest to, że jest to minimalnie inwazyjne. Ten moduł jest całkowicie użyteczny, niezależnie od samego elektrolitu. Oznacza to, że twoje testy jednostkowe mogą przetestować tylko testowany moduł , przekazując pozorowane obiekty bez potrzeby dodatkowych zależności w celu ponownego połączenia wewnętrznych.
Podczas uruchamiania pełnej aplikacji Electrolyte wkracza na poziomie między modułami, łącząc elementy bez potrzeby globalizacji, singletonów lub nadmiernej hydrauliki.
źródło
connect()
? Chociaż nie jestem zaznajomiony z MySql API dla Węzła, oczekiwałbym, że to wywołanie będzie asynchroniczne, więc ilustracja nie jest do końca jasna.ioc.create
z testu jednostkowego. Test jednostkowy powinien testować tylko testowany moduł i nie powinien wprowadzać innych zależności, w tym elektrolitu. Postępując zgodnie z tą radą, zrobiłbyśobjToTest = require('modulename')(mockObj1, mockObj2);
Sam na to spojrzałem. Nie podoba mi się wprowadzanie bibliotek narzędzi zależnych od magii, które zapewniają mechanizmy przejmowania importu moich modułów. Zamiast tego opracowałem „wytyczne projektowe” dla mojego zespołu, aby raczej wyraźnie określić, jakie zależności można wyśmiewać, wprowadzając eksport funkcji fabrycznych w moich modułach.
W dużym stopniu korzystam z funkcji ES6 w zakresie parametrów i destrukcji, aby uniknąć jakiejś płyty kotłowej i zapewnić nazwany mechanizm zastępowania zależności.
Oto przykład:
A oto przykład jego użycia
Przepraszam za składnię ES6 dla tych, którzy jej nie znają.
źródło
Niedawno sprawdziłem ten wątek z tego samego powodu, co OP - większość bibliotek, które napotkałem, tymczasowo przepisuje instrukcję request. Z tą metodą miałem mieszane stopnie sukcesu, więc skończyło się na następującym podejściu.
W kontekście aplikacji ekspresowej - zawijam app.js w pliku bootstrap.js:
Mapa obiektów przekazana do modułu ładującego wygląda następująco:
Wtedy zamiast bezpośredniego połączenia wymagają ...
Jeśli w module ładującym nie ma aliasu - domyślnie będzie to zwykłe wymaganie. Ma to dwie zalety: mogę zamieniać w dowolnej wersji klasy i eliminuje to konieczność używania względnych nazw ścieżek w całej aplikacji (więc jeśli potrzebuję niestandardowej biblioteki poniżej lub powyżej bieżącego pliku, nie muszę przechodzić , i polecenie spowoduje buforowanie modułu pod tym samym kluczem). Pozwala mi również określić symulacje w dowolnym momencie aplikacji, a nie w bezpośrednim pakiecie testowym.
Właśnie dla wygody opublikowałem mały moduł npm:
https://npmjs.org/package/nodejs-simple-loader
źródło
W rzeczywistości możesz przetestować plik node.js bez kontenera IoC, ponieważ JavaScript jest naprawdę dynamicznym językiem programowania i możesz modyfikować prawie wszystko w czasie wykonywania.
Rozważ następujące:
Możesz więc zastąpić sprzężenie między komponentami w czasie wykonywania. Lubię myśleć, że powinniśmy dążyć do oddzielenia naszych modułów JavaScript.
Jedynym sposobem na osiągnięcie rzeczywistego oddzielenia jest usunięcie odniesienia do
UserRepository
:Oznacza to, że gdzieś indziej będziesz musiał zrobić kompozycję obiektu:
Podoba mi się pomysł przekazania kompozycji obiektu do kontenera IoC. Możesz dowiedzieć się więcej o tym pomyśle w artykule Aktualny stan inwersji zależności w JavaScript . Artykuł próbuje obalić niektóre „mity o kontenerach IoC JavaScript”:
Jeśli podoba Ci się pomysł użycia kontenera IoC, możesz zajrzeć do InversifyJS. Najnowsza wersja (2.0.0) obsługuje wiele przypadków użycia:
Możesz dowiedzieć się więcej na ten temat w InversifyJS .
źródło
Dla ES6 opracowałem ten kontener https://github.com/zazoomauro/node-dependency-injection
Następnie możesz ustawić na przykład wybór transportu w kontenerze:
Ta klasa jest teraz znacznie bardziej elastyczna, ponieważ oddzieliłeś wybór transportu od implementacji do kontenera.
Teraz, gdy usługa pocztowa znajduje się w kontenerze, możesz wstrzyknąć ją jako zależność od innych klas. Jeśli masz taką klasę NewsletterManager:
Podczas definiowania usługi newsletter_manager usługa pocztowa jeszcze nie istnieje. Użyj klasy referencyjnej, aby powiedzieć kontenerowi, aby wstrzyknął usługę pocztową podczas inicjowania menedżera biuletynu:
Możesz również skonfigurować kontener z plikami konfiguracyjnymi, takimi jak pliki Yaml, Json lub JS
Kontener serwisowy można skompilować z różnych powodów. Przyczyny te obejmują sprawdzanie potencjalnych problemów, takich jak odwołania cykliczne i zwiększanie wydajności kontenera.
źródło
To zależy od projektu twojej aplikacji. Możesz oczywiście wykonać zastrzyk podobny do java, w którym tworzysz obiekt klasy z zależnością przekazywaną w konstruktorze w ten sposób.
Jeśli nie robisz OOP w javascript, możesz utworzyć funkcję init, która wszystko konfiguruje.
Istnieje jednak inne podejście, które można zastosować częściej w systemie opartym na zdarzeniach, takim jak node.js. Jeśli możesz wymodelować swoją aplikację, aby działała (tylko przez większość czasu) na zdarzeniach, wszystko, co musisz zrobić, to skonfigurować wszystko (co zwykle robię przez wywołanie funkcji init) i emitować zdarzenia z kodu pośredniczącego. To sprawia, że testowanie jest łatwiejsze i czytelniejsze.
źródło
Zawsze podobała mi się prostota koncepcji IoC - „Nie musisz nic wiedzieć o środowisku, ktoś zadzwoni w razie potrzeby”
Ale wszystkie implementacje IoC, które widziałem, robiły dokładnie odwrotnie - zaśmiecają kod jeszcze większą liczbą rzeczy niż bez niego. Tak więc stworzyłem własny IoC, który działa tak, jak chciałbym - pozostaje ukryty i niewidoczny przez 90% czasu .
Jest używany w frameworku internetowym MonoJS http://monojs.org
Robi się to w ten sposób - zarejestruj komponent raz w konfiguracji.
I używaj go w dowolnym miejscu
Pełny kod definicji komponentu (z DB Connection i innymi komponentami) można zobaczyć tutaj https://github.com/sinizinairina/mono/blob/master/mono.coffee
Jest to jedyne miejsce, w którym musisz powiedzieć IoC, co ma robić, po czym wszystkie te komponenty zostaną utworzone i okablowane automatycznie i nie będziesz już musiał widzieć kodu aplikacji IoC.
Samo IoC https://github.com/alexeypetrushin/miconjs
źródło
Myślę, że nadal potrzebujemy Wstrzykiwania zależności w Nodejs, ponieważ rozluźnia on zależności między usługami i sprawia, że aplikacja jest bardziej przejrzysta.
Zainspirowany przez Spring Framework , implementuję również własny moduł do obsługi wstrzykiwania zależności w Nodejs. Mój moduł jest w stanie wykryć
code changes
iauto reload
usługi bez ponownego uruchomienia aplikacji.Odwiedź mój projekt na: Buncha - kontener IoC
Dziękuję Ci!
źródło
Spójrz na spadki (prosta, ale potężna platforma do wstrzykiwania zależności i zarządzania jednostkami (plikami) dla Node.js)
https://github.com/devcrust/node-dips
źródło
Długo pracowałem z .Net, PHP i Javą, dlatego też chciałem mieć wygodne NendJS. Ludzie mówili, że wbudowane DI w NodeJS jest wystarczające, ponieważ możemy go uzyskać za pomocą Module. Ale nie zadowoliło mnie to dobrze. Chciałem zachować moduł nie więcej niż klasę. Dodatkowo chciałem, aby DI miał pełną obsługę zarządzania cyklem życia modułu (moduł singleton, moduł przejściowy itp.), Ale z modułem Node musiałem bardzo często pisać kod manualny. Wreszcie chciałem ułatwić test jednostkowy. Dlatego stworzyłem dla siebie Zastrzyk Zależności.
Jeśli szukasz DI, spróbuj. Można go znaleźć tutaj: https://github.com/robo-creative/nodejs-robo-container . Jest w pełni udokumentowany. Zajmuje się także niektórymi typowymi problemami związanymi z DI i sposobem ich rozwiązywania w sposób OOP. Mam nadzieję, że to pomoże.
źródło
Niedawno utworzyłem bibliotekę o nazwie circuitbox, która umożliwia używanie wstrzykiwania zależności w pliku node.js. Wykonuje prawdziwy zastrzyk zależności w porównaniu do wielu bibliotek opartych na wyszukiwaniu zależności, które widziałem. Circuitbox obsługuje również asynchroniczne procedury tworzenia i inicjowania. Poniżej znajduje się przykład:
Załóżmy, że następujący kod znajduje się w pliku o nazwie consoleMessagePrinter.js
Załóżmy, że w pliku main.js znajduje się następujący element
Circuitbox pozwala definiować komponenty i deklarować ich zależności jako moduły. Po zainicjowaniu umożliwia odzyskanie komponentu. Circuitbox automatycznie wstrzykuje wszystkie komponenty, których potrzebuje komponent docelowy, i przekazuje go do użycia.
Projekt jest w wersji alfa. Twoje komentarze, pomysły i opinie są mile widziane.
Mam nadzieję, że to pomoże!
źródło
Myślę, że inne posty wykonały świetną robotę w argumentach za użyciem DI. Dla mnie powody są
Wstrzykuj zależności bez znajomości ich ścieżek. Oznacza to, że jeśli zmienisz lokalizację modułu na dysku lub zamienisz go na inny, nie musisz dotykać każdego zależnego od niego pliku.
Ułatwia to kpiny z zależności w celu testowania bez konieczności nadpisywania
require
funkcji globalnej w sposób, który działa bez problemów.Pomaga uporządkować i uzasadnić twoją aplikację jako luźno powiązane moduły.
Ale bardzo ciężko mi było znaleźć środowisko DI, które mój zespół i ja możemy łatwo zastosować. Niedawno zbudowałem framework o nazwie deppie w oparciu o te funkcje
require
modułyźródło
Powinien być elastyczny i prosty w następujący sposób:
Napisałem artykuł o Wstrzykiwaniu Zależności w node.js.
Mam nadzieję, że ci to pomoże.
źródło
Node.js wymaga DI tak samo, jak każdej innej platformy. Jeśli budujesz coś dużego, DI ułatwi wyśmiewanie się z zależności twojego kodu i dokładne przetestowanie kodu.
Na przykład moduły warstwy bazy danych nie powinny być po prostu wymagane w modułach kodu biznesowego, ponieważ podczas testowania tych modułów kodu jednostki daos ładuje się i łączy z bazą danych.
Jednym rozwiązaniem byłoby przekazanie zależności jako parametrów modułu:
W ten sposób zależności można łatwo i naturalnie wyśmiewać, a Ty możesz skupić się na testowaniu kodu, bez korzystania z trudnej biblioteki innej firmy.
Istnieją inne rozwiązania (broadway, architekt itp.), Które mogą ci w tym pomóc. chociaż mogą robić więcej, niż chcesz lub używać więcej bałaganu.
źródło
Opracowałem bibliotekę, która w prosty sposób obsługuje wstrzykiwanie zależności, co zmniejsza kod płyty wzorcowej. Każdy moduł jest zdefiniowany przez unikalną nazwę i funkcję kontrolera. Parametry kontrolera odzwierciedlają zależności modułu.
Czytaj więcej na KlarkJS
Krótki przykład:
myModuleName1
to nazwa modułu.$nodeModule1
jest biblioteką zewnętrzną znode_module
. Nazwa rozwiązuje się nanode-module1
. Prefiks$
oznacza, że jest to moduł zewnętrzny.myModuleName2
to nazwa modułu wewnętrznego.myModuleName1
.źródło
Odkryłem to pytanie, odpowiadając na problem na moim własnym module DI, pytając, dlaczego kiedykolwiek potrzebny jest system DI do programowania w NodeJS.
Odpowiedź wyraźnie dotyczyła odpowiedzi podanych w tym wątku: to zależy. Istnieją kompromisy dla obu podejść, a czytanie odpowiedzi na to pytanie daje dobry ich kształt.
Tak więc prawdziwa odpowiedź na to pytanie powinna być taka, że w niektórych sytuacjach użyłbyś systemu DI, w innych nie.
To powiedziawszy, to, czego chcesz jako programista, to nie powtarzać się i nie wykorzystywać ponownie swoich usług w różnych aplikacjach.
Oznacza to, że powinniśmy napisać usługi gotowe do użycia w systemie DI, ale niepowiązane z bibliotekami DI. Dla mnie oznacza to, że powinniśmy pisać takie usługi:
W ten sposób Twoja usługa nie ma znaczenia, jeśli korzystasz z niej z narzędziem DI lub bez niego.
źródło
TypeDI jest najsłodszym ze wszystkich wymienionych tutaj, spójrz na ten kod w TypeDI
Spójrz też na ten kod:
źródło