Za każdym razem, gdy ktoś do mnie dociera i prosi, abym w sposób koncepcyjny zdefiniował wtrysk zależności i wyjaśnił prawdziwe zalety i wady używania DI w projektowaniu oprogramowania. Przyznaję, że mam trudności z wyjaśnieniem koncepcji DI. Za każdym razem muszę im opowiedzieć historię o zasadzie pojedynczej odpowiedzialności, składzie nad spadkiem itp.
Czy ktoś może mi pomóc w wyjaśnieniu najlepszego sposobu opisania DI dla programistów?
design
design-patterns
software
Tiago Sampaio
źródło
źródło
Odpowiedzi:
Dependency Injection to okropna nazwa (IMO) 1 dla dość prostej koncepcji. Oto przykład:
DbContext
). Ten wewnętrzny zasób nazywany jest zależnościąDbContext
) Z metody i nakładasz na osobę wywołującą obowiązek zapewnienia tego zasobu (jako parametru metody lub przy tworzeniu wystąpienia klasy)[1] : Pochodzę z niższego poziomu i zajęło mi miesiące usiąść i nauczyć się wstrzykiwania zależności, ponieważ nazwa sugeruje, że byłoby to coś znacznie bardziej skomplikowanego, na przykład DLL Injection . Fakt, że Visual Studio (i my ogólnie programiści) odnosi się do bibliotek .NET (bibliotek DLL lub zestawów ), od których zależy projekt, ponieważ zależności wcale nie pomaga. Istnieje nawet coś takiego jak Dependency Walker (depends.exe) .
[Edytuj] Pomyślałem, że jakiś kod demo przydałby się dla niektórych, więc oto jeden (w C #).
Bez iniekcji zależności:
Twój konsument zrobiłby wtedy coś takiego:
Ta sama klasa zaimplementowana z wzorcem wstrzykiwania zależności wyglądałaby następująco:
Teraz to osoba dzwoniąca jest odpowiedzialna za utworzenie wystąpienia
DbContext
i przekazanie (errm, wstrzyknięcie ) swojej klasie:źródło
Pojęcia abstrakcyjne są często lepiej wyjaśniane za pomocą analogii z prawdziwego świata. Oto moja analogia:
Nie jest idealny, ale podkreśla kluczową funkcję: kontrolę konsumenta . Nieodłączną korzyścią dla obu stron jest to, że nie musisz już nabywać własnych zależności, a konsumentowi nie przeszkadza wybór zależności.
źródło
Prosta odpowiedź na to:
.Net Core jest całkiem dobrym przykładem, który możesz podać, ponieważ ten framework używa dużo wstrzykiwania zależności. Zasadniczo usługi, które chcesz wstrzyknąć, znajdują się w
startup.cs
pliku.Jasne, uczeń powinien być świadomy niektórych pojęć, takich jak polimorfizm, interfejsy i zasady projektowania OOP.
źródło
Wokół tego, co jest w zasadzie prostą koncepcją, jest dużo puchu i bunkum.
Bardzo łatwo jest też zagłębić się w „ jakiego frameworku powinienem użyć ”, kiedy można to zrobić po prostu w kodzie.
Oto definicja, której osobiście używam:
Niektóre przykłady mogą być takie, gdzie Y jest połączeniem systemu plików lub bazy danych.
Frameworki, takie jak moq, umożliwiają definiowanie dubletów (udawanie wersji Y) za pomocą interfejsu, dzięki czemu możliwe jest wstrzyknięcie w instancję Y, gdzie Y jest na przykład połączeniem z bazą danych.
Łatwo wpaść w pułapkę przekonania, że jest to wyłącznie kwestia testowania jednostkowego, ale jest to bardzo użyteczny wzorzec dla każdego fragmentu kodu, w którym oczekuje się zmiany i prawdopodobnie dobrej praktyki.
źródło
Zapewniamy zachowanie funkcji w czasie wykonywania poprzez metodę wstawiania tego zachowania do funkcji za pomocą parametru.
Wzorzec strategii jest doskonałym przykładem zastrzyku zależności.
źródło
Aby zrobić to dobrze, musimy najpierw zdefiniować zależności i zastrzyk.
Podstawowym przykładem byłaby metoda, która dodaje dwie wartości. Oczywiście metody te wymagają dodania wartości. Jeśli zostaną dostarczone przez przekazanie ich jako argumentów, byłby to już przypadek wstrzyknięcia zależności. Alternatywą byłoby zaimplementowanie argumentów jako właściwości lub zmiennych globalnych. W ten sposób nie zostałyby wstrzyknięte żadne zależności, zależności byłyby dostępne z zewnątrz z góry.
Załóżmy, że zamiast tego używasz właściwości i nadajesz im nazwy A i B. Jeśli zmienisz nazwy na Op1 i Op2, przerwiesz metodę Add. Lub twoje IDE zaktualizuje dla ciebie wszystkie nazwy, chodzi o to, że metoda również musiałaby zostać zaktualizowana, ponieważ ma zależności od zasobów zewnętrznych.
Ten przykład jest prosty, ale możesz sobie wyobrazić bardziej złożone przykłady, w których metoda wykonuje operację na obiekcie, takim jak obraz lub gdzie odczytuje ze strumienia pliku. Czy chcesz, aby metoda sięgnęła po obraz, wymagając, aby wiedział, gdzie on jest? Nie. Czy chcesz, aby metoda otworzyła sam plik, wymagając od niego wiedzy, gdzie szukać pliku, a nawet wiedząc, że będzie on czytał z pliku? Nie.
Chodzi o to, aby zredukować funkcjonalność metody do jej podstawowego zachowania i oddzielić metodę od środowiska. Otrzymujesz pierwszy, robiąc drugi, możesz uznać to za definicję wstrzykiwania zależności.
Korzyści: ponieważ wyeliminowano zależności dla środowiska metody, zmiany w metodzie nie będą miały wpływu na środowisko i odwrotnie. => Aplikacja staje się łatwiejsza w utrzymaniu (modyfikacji).
źródło