Bağımlılığı enjeksiyon nedir?

Bir çox suallar, məsələn, istifadə edərkən və bunun üçün hansı çərçivələr mövcud olduğuna dair asılılıq mülahizəsi ilə bağlı xüsusi suallar verilmişdir. Bununla belə

Bağımlılıq müalicəsi nədir və nə vaxt / niyə istifadə edilməli və ya istifadə edilməməlidir?

2749
ar qurdular . 25 Sentyabr 2008-09-25 03:28 '08 at 3:28 2008-09-25 03:28
@ 35 cavab
  • 1
  • 2

Əslində, obyektlərinizin bir asılılıq yaradaraq və ya bir zavod obyektini onlara vermək istəməsi əvəzinə, lazımlı bağımlılıkları kənardan obyektə keçirirsiniz və onu xarici bir problem halına gətirirsiniz. Bu "kimsə" ya bağımlılık grafiği boyunca ya da bir bağımlılık grafiği oluşturan bağımlılığın bir enjektörü (çerçeve) boyunca bir obyektdir. Bağımlılık, burada istifadə etdiyim kimi, mövcud obyektin bir keçid içində olması lazım olan hər hansı bir obyektdir.

Bağımlılığı enjeksiyonun əsas üstünlüklərindən biri testin sadələşdirilməsidir. Onun konstruktoruna bənzər bir şey edən bir obyektiniz var deyək:

 public SomeClass (MyClass myObject) { this.myObject = myObject; } 

Quruluşçu vasitəsilə bu bir asılılıq müdaxiləsi stilidir. Bir neçə mexanizm mümkündür.

  • Şərhdə qeyd edildiyi kimi, alternativlərdən biri qeyri-konstruktorun təsviri və əmlak ayarları vasitəsi (h / t @MikeVella) vasitəsilə təqdim olunmuş bağımlılığın mövcudluğudır.
  • Martin Fowler , üçüncü seçim (h / t @MarcDix) sənədlərini təqdim edir, burada dərslər əlavə etmək istədikləri asılılıqlara interfeys açıq şəkildə tətbiq olunur.

Bağımlılıq müalicəsi (məsələn, onların qurucularında çox işləyən siniflərdə və s.) İstifadə etmirsinizsə, vahid sınaq zamanı komponentləri təcrid etmək daha çətindir.

2013-cü ildə bu cavabı yazdığımda, bu, Google Test Blogunda əsas mövzudur. Mənim üçün ən böyük üstünlük bu qalır, çünki iş müddətinizdə (məsələn, xidmət axtarışçı və ya oxşar şablonlarda) dizaynınızda hər zaman əlavə rahatlıq tələb etmirsiniz, amma tez-tez sınaq zamanı dərslərinizi ayırmaq lazımdır.

1720
25 сент. Sep 25 verildi 2008-09-25 03:49 '08 at 3:49 2008-09-25 03:49

Bu günə qədər gördüyüm ən yaxşı tərif , James Shore'dən biridir :

"Depozit Enjeksiyonu" 5 cent konsepsiyası üçün 25 dollardır. [...] Nümunə dəyişənlərinin obyektini təmin edən bir enjeksiyon vasitəsi. [...].

Martin Fowler tərəfindən hazırlanmış bir məqalə var, bu da faydalı ola bilər.

border=0

Depozit inyeksiyası əsasən obyektin öz ehtiyaclarına (özünəməxsusluqlarına) ehtiyacı olan obyektləri təmin edir, bunları özü ilə qurur. Sınaq üçün çox faydalı bir üsuldur, çünki bu bağımlılığı aldatmaq və ya aradan qaldırmağa imkan verir.

Depozitlər bir çox cəhətdən (məsələn, konstruktor inyeksiya və ya quraşdırıcı inyeksiya) obyektlərə daxil edilə bilər. Bunu etmək üçün hətta xüsusi asılılıq müdaxilə sxemlərini (məsələn, Bahar) istifadə edə bilərsiniz, lakin əlbəttə ki, tələb olunmur. Bağımlılıq üçün bu çərçivəyə ehtiyac yoxdur. Aydındır ki, obyektlərin yaradılması və ötürülməsi (asılılıq) iskelet inyeksiyası kimi yaxşıdır.

2126
26 сент. Cavab Thiago Arrais tərəfindən verilir . 2008-09-26 19:50 '08 saat 19:50 'da 2008-09-26 19:50

Pulsuz kommunikasiya baxımından bu məzəli nümunəni tapdım:

Hər hansı bir tətbiq bir sıra faydalı əşyalar yerinə yetirmək üçün qarşılıqlı bir sıra obyektlərdən ibarətdir. Ənənəvi olaraq, hər bir obyekt onunla əlaqəli asılı obyektlərə (müstəqilliyə) öz əlaqələrini əldə etmək üçün məsuliyyət daşıyır. Bu, çox bağlı siniflərə və kompleks kod testinə gətirib çıxarır.

Məsələn, Car obyektini nəzərdən keçirin.

Car təkərlərdən, mühərrikdən, yanacaqdan, batareyadan və s. Çalışmaq üçün. Ənənəvi olaraq, Car obyektinin tərifi ilə yanaşı, belə asılı obyektlərin markasını müəyyənləşdiririk.

Bağımlılığı olmayan injection olmadan (DI):

 class Car{ private Wheel wh = [Inject an Instance of Wheel (dependency of car) at runtime] private Battery bt = [Inject an Instance of Battery (dependency of car) at runtime] Car(Wheel wh,Battery bt) { this.wh = wh; this.bt = bt; } //Or we can have setters void setWheel(Wheel wh) { this.wh = wh; } } 

Mənbə: Enjeksiyon Bağımlılığı anlama

536
22 мая '11 в 7:01 2011-05-22 07:01 cavab gtiwari333 tərəfindən verilir 22 May '11 at 7:01 am 2011-05-22 07:01

Bağımlılık enjeksiyonu, obyektlərin digər kod parçalarından nümunələr götürdükləri yerlərdə qurmaqdan başqa bir şəkildə yaradıldığı bir tətbiqdir. Bu, bir obyekt tərəfindən tələb olunan bir interfeysi tətbiq edən hər hansı bir obyektin kodu dəyişdirmədən dəyişdirə biləcəyini, testin asanlaşdırılmasını və izolyasiyanın yaxşılaşdırılmasını nəzərdə tutur.

Məsələn, bu dərsləri nəzərdən keçirin:

237
25 сент. Cavab Adam Ness tərəfindən verilir . 2008-09-25 09:49 '08 at 9:49 2008-09-25 09:49

Qəbul edilən cavab yaxşıdır, amma bu əlavə etmək istərdim ki, DI kodu klassik birinə çox oxşardı, kodda sabit kodlu sabitləri qaçırdılar.

Bəzi bir verilənlər bazası adı kimi sabit istifadə etdiyiniz zaman, onu bir neçə konfiqurasiya faylına köçürə və bu dəyəri olan dəyişdirən lazım olduğu yerə keçir. Bunun səbəbi bu sabitlərin adətən kodun qalan hissəsindən daha tez-tez dəyişir. Məsələn, bir test verilənlər bazasında kodu sınamaq istəsəniz.

DI obyekt-yönümlü proqramlaşdırma dünyasında bununla bənzəyir. Orada daimi ədədlər yerinə dəyərlər bütün obyektlərdir, amma onları kodun kodundan əmələ gətirən kodu bir-birinə bənzəyir - obyektlər onları istifadə edən koddan daha tez-tez dəyişir. Belə dəyişikliyin zəruri olduğu vacib hadisələrdən biri testdir.

147
06 янв. Cavab yanvarın 06- dək verilir 2011-01-06 21:33 '11 at 21:33 2011-01-06 21:33

Balıq ovuna getmək istədiyini düşünün:

  • Bağımlılıq mülahizəsi olmadan hər şeyə diqqət yetirməliyik. Bir qayıq tapmaq, bir balıqçı çubuğunu almaq, yemi axtarmaq və s. Əlbəttə ki, bu mümkündür, ancaq sizin üzərinizdə böyük məsuliyyət daşıyır. Proqram baxımından, bu, bütün bunları axtarmaq lazımdır deməkdir.

  • Bağımlılık mübadiləsi ilə başqası bütün hazırlıqlara diqqət yetirir və sizə lazım olan avadanlıqları təmin edir. Bir qayıq, bir balıqçı çubuq və yem alacaqsınız - hamısı istifadə üçün hazırdır.

99
22 окт. Cavab 22 oktyabrda Olivier Liechti tərəfindən verildi . 2012-10-22 07:47 '12 at 7:47 am 2012-10-22 07:47

AvtomobilMühərrikin sadə bir nümunəsini sınaqdan keçirin , hər hansı bir avtomobil heç bir yerə getmək üçün bir mühərrikə ehtiyac duyur. Beləliklə, aşağıda kodu asılılıq olmadan injection kimi görünəcək.

 Car car = new Car(); 

Problem GasEngine ilə yaxından əlaqəli olan bu kodla və biz Elektrik Mühəndisinə dəyişdirməyi qərara alsaq, Car sinfi yenidən yazılmalıdır. Və tətbiqi daha böyük, daha çox problem və baş ağrısı yeni bir mühərrik növü əlavə etmək və istifadə etmək məcburiyyətində qalacağıq.

Başqa sözlə, bu yanaşma ilə bizim yüksək səviyyəli Car sinifimiz aşağı səviyyədə olan GasEngine sinifinə bağlıdır və bu, SOLID-də qarışıqlıq çevrilmə prinsipini (DIP) pozur. DİP konkret dərslərə deyil, abstraksiyalara asılı olmağımızı təklif edir. Bunu təmin etmək üçün, IEngine interfeysini daxil edin və kodu aşağıda göstərildiyi kimi yenidən yazırıq:

  Car gasCar = new Car(new GasEngine()); gasCar.Run(); Car electroCar = new Car(new ElectricityEngine()); electroCar.Run(); 

Burada əsasən bizim asılılığımızı (Motor nüsxəsini) Avtomobil konstruktoruna təqdim edirik. İndi dərslərimiz obyektlər və onların bağımlılıkları arasında pulsuz bir əlaqəyə sahibdir və biz Avtomobil sinfini dəyişdirmədən yeni növ mühərrikləri asanlıqla əlavə edə bilərik.

Enjeksiyon bağımlılığının əsas üstünlüyü şagirdlərin sabit kodlu bağımlılıkları olmadığından, siniflərin daha gevşek birleştirildiğidir. Bu, yuxarıda göstərilən asılılıq törətməsinin prinsipinə əsaslanır. Xüsusi tətbiqlərə istinad etmək əvəzinə, siniflər sinif yaratarkən özlərinə verilən abstraksiyalar (adətən interfeyslər ) tələb edir.

Beləliklə, sonunda bir injection asılılığının obyektlər və onların bağımlılıkları arasında pulsuz bir əlaqə təmin etmək üçün bir üsuldur. Sinifin öz hərəkətlərini yerinə yetirmək üçün ehtiyac duyduqları bağımlılıkları birbaşa yaratmaq yerine, bağımlılıkları bir yapıcı inyeksiya yolu ilə (ən çox) sinifə verilir.

Ayrıca, bir çox bağımlılığımız olduğunda, bütün bağımlılıklarımız üçün hansı uygulamalara hansı arabirimlerin eşlenmesi gerektiğini belirleyebildiğimiz Kontrol Denetimi (IoC) konteynırlarını istifadə etmək çox faydalıdır ve bu bağımlılıkları nesnemizi oluşturduğumuzda çözebilir . Məsələn, bir IoC konteynerinin Xəritəçəkmə üçün IEngine bağımlılığının GasEngine sınıfına eşlenmesi gerektiğini belirleyebiliriz ve Otomobilimizin bir örneğine bir IoC konteyner istediğimizde, otomotiv sınıfını avtomatik olaraq GasEngine iletimiyle oluşturur .

YENİLƏNİB: Bu yaxınlarda mən Julie Lerman-dən EF Core kursunu nəzərdən keçirdim və DI ilə bağlı qısa təsvirini də sevdim.

Bağımlılıkların daxil olması, başvurunuzun, bu nesnelerden sorumlu olan sınıfları zorlamadan, onlara ihtiyaç duyduğu sınıflara "uçakta" nesnelleştirmeye imkan veren şablondur. Bu, kodunuzun daha rahat birləşməsinə imkan verir və Entity Framework Core eyni saxlanma sisteminə qoşulur.

90
06 июля '17 в 12:42 2017-07-06 12:42 cavab user2771704 tərəfindən 06 iyul '07 saat 12:42 2017-07-06 12:42 'də verilir

Bu Bağımlılık Enjeksiyon ve Bağımlılık Enjeksiyon Konteynerinin en basit açıklamasıdır. Mən gördüm:

Bağımlılığın olmaması

  • Ərizə Foo tələb edir (məsələn, bir nəzarətçi), beləliklə:
  • Ərizə foo yaradır
  • Ərizə Foo çağırır
    • Foo bir bara ehtiyac duyur (məsələn, bir xidmət) belədir:
    • Foo Bar yaratır
    • Foo çubuğu çağırır
      • Çubuğun Bim (xidmət, depolar, ...) ehtiyacı var:
      • Panel bim yaradır
      • Bar bir şey edir.

asılılıq müalicəsi

  • Tətbiqə ehtiyac duyan Foo, ehtiyacı olan Bar, buna görə:
  • Ərizə Bim'i yaradır
  • Ərizə bir Bar yaratır və onu Bimə verir.
  • Ərizə Foo yaratır və ona Bar verir.
  • Ərizə Foo çağırır
    • Foo çubuğu çağırır
      • Bar bir şey edir.

Enjeksiyon bağımlılığı üçün bir konteynerin istifadə edilməsi

  • Ərizə foo belə lazımdır:
  • Tətbiq konteynerdən Foo alır:
    • Konteyner Bim yaratır
    • Konteyner Bar yaratır və ona Bim verir
    • Konteyner foo yaradır və onu bir bar verir
  • Ərizə Foo çağırır
    • Foo çubuğu çağırır
      • Bar bir şey edir.

Bağımlılık EnjeksiyonuEnjeksiyon Konteynerləri iki fərqli şeydir:

  • Enjeksiyon Bağlılığı - daha yaxşı kod yazma metodu.
  • DI Konteyner bir Enjeksiyon Bağımlılığı Aracıdır.

Enjeksiyon bağımlılıkları üçün bir konteynere ehtiyac yoxdur. Lakin, konteyner sizə kömək edə bilər.

84
05 мая '16 в 14:53 2016-05-05 14:53 cavab Trix 05 May '16 saat 14:53 'də verilir 2016-05-05 14:53

"Bağımlılığı enjeksiyon" parametrelendirilmiş yapıcıları ve ictimai ayarlayıcıları kullanmak anlamına gelmez mi?

James Shore məqaləsi müqayisə üçün aşağıdakı nümunələri təqdim edir .

Bağımsız olaraq injection olmadan qurucu:

 public class Example { private DatabaseThingie myDatabase; public Example(DatabaseThingie useThisDatabaseInstead) { myDatabase = useThisDatabaseInstead; } public void doStuff() { ... myDatabase.getData(); ... } } 
47
02 мая '13 в 3:40 2013-05-02 03:40 Cavab JaneGoodall tərəfindən verilir 02 May '13 3:40 2013-05-02 03:40

Bağımlılığı enjeksiyon (DI) nedir?

Başqalarının dediyinə görə, Injection Dependency (DI), maraqların sinifinin (istehlakçı sinfi) bağlı olduğu ( UML mənasında ) digər obyektlərin ömrünü birbaşa yaratmaq və idarə etmək məsuliyyətini azaldır . Bu nümunələr əvəzinə konstruktor parametrləri və ya mülkiyyət anlayışları (istehlakçı sinifinin köçürülməsi və istehlakçı sinifinə köçürülməsi adətən İdarə Təcrübəsi (IoC) konteyner tərəfindən aparılır, lakin bu fərqli bir mövzu) olaraq istifadə olunur.

DI, DIP və SOLID

Xüsusilə, Robert C Martin SOLID paradiqmasında, obyekt yönümlü dizayn prinsipləri , DI , Inverse Dependences (DIP) prinsipinin mümkün tətbiqlərindən biridir. DIP, SOLID D mantranıdır - digər DIP tətbiqləri xidmət lokatoru və plug-in şablonlarını ehtiva edir.

DİP-in məqsədi dərslər arasında sıx, konkret müstəqilliyi ayırmaq və əvəzinə dil və yanaşma dilinə əsasən interface , abstract class və ya pure virtual class istifadə etməklə əldə edilə bilən abstraksiya vasitəsilə əlaqəni zəiflətməkdir.

DIP olmadan bizim kodumuz (bu "istehlakçı sinfi" adlandırdım) birbaşa xüsusi bir asılılıq ilə əlaqəli və həm də bu bağımlılığın bir nümunəsini almaq və idarə etmək üçün necə bilmək üçün məsuliyyətlə yüklənir, yəni. konseptual:

 "I need to create/use a Foo and invoke method `GetBar()`" 

DİP tətbiqindən sonra, tələblər rahatdır və Foo ömrünü əldə etmək və idarə etmək problemi aradan qaldırılıb:

 "I need to invoke something which offers `GetBar()`" 

Niyə DIP (və DI) istifadə edirsiniz?

Bu şəkildə siniflər arasındakı bağımlı bağımlılıklar, bu bağımlılık sınıflarını, soyutlama önkoşullarını yerine getiren diğer uygulamalarla değiştirmekte kolaylaştırır (məsələn, bağımlılık eyni arabirimin farklı bir uygulaması ile değiştirilebilir). Bundan başqa, başqaları qeyd etdiyimiz kimi, DİP vasitəsilə dərslərin ayrılmasının ən ümumi səbəbi istehlak sinfini test etməyə imkan verməkdir, eyni müstəqilliyin artıq zəruriliyi və / və ya istehza edilməsi mümkündür.

DI-nin nəticələrindən biri asılılıq obyektinin nümunələrinin həyat dövrü artıq istehlakçı sinfi tərəfindən yoxlanılmadığından, asılılıq obyekti artıq istehlakçı sinifinə (konstruktor və ya setterin quraşdırılması vasitəsilə) keçirilir.

Bu müxtəlif yollarla baxıla bilər:

  • İstehlakçı sinfi üçün həyat dövrünə nəzarət etmək lazımdırsa, istehlakçı sinifindəki asılılıq sinifinin nümunələrini yaratmaq üçün bir (mücərrəd) fabrikin daxil edilməsi ilə nəzarət bərpa edilə bilər. İstehlakçı lazım olduqda zavod Create və başa çatdıqdan sonra bu hallardan xilas olmaq üçün nümunələr əldə edə biləcək.
  • Bundan əlavə, asılılıq nümunələrinin həyat dövrü idarə olunması IoC konteynerində (aşağıda daha ətraflı) rədd edilə bilər.

DI istifadə edərkən?

  • Yəqin ki, ekvivalent bir tətbiq üçün asılılığı əvəz etməli olduqda,
  • Bağımlılığını təcrid etmək üçün vahid test sinfi üsullarına ehtiyacınız varsa,
  • Если неопределенность срока службы зависимости может гарантировать экспериментирование (например, Hey, MyDepClass является потокобезопасным - что, если мы сделаем его синглом и введем один и тот же экземпляр всем потребителям?)

Misal

Здесь простая реализация С#. Учитывая нижний класс потребления:

 public class MyLogger { public void LogRecord(string somethingToLog) { Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog); } } 

Несмотря на кажущееся безобидное, он имеет две зависимости static от двух других классов: System.DateTime и System.Console , которые не только ограничивают параметры вывода журнала (вход в консоль бесполезен, если никто не смотрит), но хуже того, трудно автоматически проверить, учитывая зависимость от недетерминированных системных часов.

Однако мы можем применить DIP к этому классу, абстрагируясь от привязки timestamping как зависимости и связывая MyLogger только с простым интерфейсом:

 public interface IClock { DateTime Now { get; } } 

Мы также можем ослабить зависимость от Console до абстракции, такой как a TextWriter . Инъекция зависимостей обычно реализуется как либо constructor инъекция (передача абстракции зависимости в качестве параметра для конструктора потребляющего класса), так и Setter Injection (передача зависимости с помощью установщика setXyz() или .Net Property с {set;} ). Предпочтительным является инжектор конструктора, так как это гарантирует, что после построения класс будет в правильном состоянии и позволит поля внутренней зависимости быть помечены как readonly (С#) или final (Java). Поэтому, используя инъекцию конструктора в приведенном выше примере, это оставляет нам:

 public class MyLogger : ILogger // Others will depend on our logger. { private readonly TextWriter _output; private readonly IClock _clock; // Dependencies are injected through the constructor public MyLogger(TextWriter stream, IClock clock) { _output = stream; _clock = clock; } public void LogRecord(string somethingToLog) { // We can now use our dependencies through the abstraction // and without knowledge of the lifespans of the dependencies _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog); } } 

(Необходимо предоставить конкретный Clock , который, конечно, может вернуться к DateTime.Now , и две зависимости должны быть предоставлены контейнером IoC через впрыск конструктора)

Может быть создан автоматизированный unit test, что окончательно доказывает, что наш регистратор работает правильно, так как теперь мы имеем контроль над зависимостями - время, и мы можем отслеживать записанный вывод:

 [Test] public void LoggingMustRecordAllInformationAndStampTheTime() { // Arrange var mockClock = new Mock<IClock>(); mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45)); var fakeConsole = new StringWriter(); // Act new MyLogger(fakeConsole, mockClock.Object) .LogRecord("Foo"); // Assert Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString()); } 

Следующие шаги

Инъекция зависимостей неизменно связана с Inversion of Control container (IoC) , чтобы вводить (предоставлять) конкретные экземпляры зависимостей и управлять сроки жизни. Во время процесса конфигурирования/начальной загрузки контейнеры IoC допускают следующее:

  • между каждой абстракцией и сконфигурированной конкретной реализацией (например, "в любое время, когда потребитель запрашивает IBar , возвращает экземпляр ConcreteBar )
  • политики могут быть настроены для управления продолжительностью жизни каждой зависимости, например. для создания нового объекта для каждого экземпляра потребителя, для совместного использования экземпляра зависимостей singleton для всех пользователей, для совместного использования одного и того же экземпляра зависимостей только через один и тот же поток и т.д.
  • В .Net контейнеры IoC знают о протоколах, таких как IDisposable , и берут на себя ответственность за зависимости Disposing в соответствии с настроенным управлением продолжительностью жизни.

Как правило, после того, как контейнеры IoC были сконфигурированы/загружены, они легко работают в фоновом режиме, позволяя кодеру сосредоточиться на коде, а не беспокоиться о зависимостях.

Ключ к дружественному DI коду заключается в том, чтобы избежать статической связи классов, а не использовать new() для создания зависимостей

В соответствии с вышеприведенным примером, развязка зависимостей требует определенных усилий по разработке, а для разработчика существует сдвиг парадигмы, необходимый для того, чтобы нарушать привычку new зависимых зависимостей напрямую и вместо этого доверять контейнеру для управления зависимостями.

Но преимуществ много, особенно в способности тщательно протестировать ваш класс интересов.

Примечание : создание/отображение/проецирование (через new ..() ) POCO/POJO/сериализации DTO/диаграммы сущностей/анонимные прогнозы JSON и др. - т.е. классы или записи только для данных - используемые или возвращенные из методов, не рассматриваются как Зависимости (в смысле UML) и не подлежат DI. Использование new для проецирования их просто отлично.

35
ответ дан StuartLC 28 апр. '15 в 23:17 2015-04-28 23:17

Сделать концепцию инжекции зависимостей понятной. Возьмем пример кнопки переключателя для переключения (включения/выключения) лампочки.

Без инъекции зависимостей

Коммутатор должен заранее знать, с какой лампой подключаюсь (жестко закодированная зависимость). Beləliklə,

Switch → PermanentBulb//переключатель напрямую подключен к постоянной лампочке, тестирование невозможно легко

2019

ответ дан wakqasahmed 28 окт. '16 в 23:30 2016-10-28 23:30

Весь смысл Injection Dependency (DI) заключается в том, чтобы сохранить исходный код приложения чистый и стабильный :

  • чистый код инициализации зависимостей
  • стабильный , независимо от используемой зависимости

Практически каждый шаблон дизайна отделяет проблемы, чтобы изменения в будущем влияли на минимальные файлы.

Конкретным доменом DI является делегирование конфигурации зависимостей и инициализации.

Пример: DI с оболочкой script

Если вы иногда работаете за пределами Java, вспомните, как source часто используется во многих языках сценариев (Shell, Tcl и т.д. или даже import в Python неправильно используется для этой цели).

Рассмотрим простой dependent.sh script:

 #!/bin/sh # Dependent touch "one.txt" "two.txt" archive_files "one.txt" "two.txt" 

script зависит: он не будет успешно выполнен сам по себе ( archive_files не определен).

Вы определяете archive_files в archive_files_zip.sh реализации script (используя zip в этом случае):

 #!/bin/sh # Dependency function archive_files { zip files.zip "$@" } 

Вместо source -я реализации script непосредственно в зависимом, вы используете контейнер injector.sh , который обертывает оба "компонента":

 #!/bin/sh # Injector source ./archive_files_zip.sh source ./dependent.sh 

Зависимость archive_files только что была введена в зависимый script.

Вы могли бы вводить зависимость, которая реализует archive_files , используя tar или xz .

Пример: удаление DI

Если dependent.sh script использовать зависимости напрямую, этот подход будет называться поиском зависимостей (который отличается от инъекции зависимостей):

 #!/bin/sh # Dependent # dependency look-up source ./archive_files_zip.sh touch "one.txt" "two.txt" archive_files "one.txt" "two.txt" 

Теперь проблема заключается в том, что зависимый "компонент" должен выполнять инициализацию самостоятельно.

Исходный код "компонента" не является ни чистым , ни стабильным , потому что для каждого изменения в инициализации зависимостей требуется новая версия для файла исходного кода "компонентов".

Последние слова

DI не так сильно подчеркивается и популяризируется, как в Java-инфраструктурах.

Но это общий подход для разделения проблем:

  • приложение разработка ( одиночный жизненный цикл выпуска исходного кода)
  • приложение развертывание ( несколько целевых сред с независимыми жизненными циклами)

Использование конфигурации только с поиском зависимостей не помогает, поскольку количество параметров конфигурации может изменяться на каждую зависимость (например, новый тип аутентификации), а также количество поддерживаемых типов зависимостей (например, новый тип базы данных).

23
ответ дан uvsmtid 23 сент. '13 в 19:28 2013-09-23 19:28

Что такое зависимость Инъекция?

Инъекция зависимостей (DI) означает отделить объекты, которые зависят друг от друга. Скажем, объект A зависит от объекта B, поэтому идея состоит в том, чтобы отделить этот объект друг от друга. Нам не нужно жестко закодировать объект, используя новое ключевое слово, а не общие зависимости к объектам во время выполнения, несмотря на время компиляции. Если мы говорим о

Как работает инжекция зависимостей в Spring:

Нам не нужно жестко закодировать объект, используя новое ключевое слово, скорее определите зависимость bean в файле конфигурации. Контейнер spring будет отвечать за подключение всех.

Инверсия управления (IOC)

IOC является общей концепцией, и ее можно выразить многими различными способами, а Injection Dependency - это один конкретный пример IOC.

Два типа инъекций зависимостей:

  • Инъекция конструктора
  • Инъекция сеттера

1. Инъекция зависимостей на основе конструктора:

DI на основе конструктора выполняется, когда контейнер вызывает конструктор класса с множеством аргументов, каждый из которых представляет зависимость от другого класса.

 public class Triangle { private String type; public String getType(){ return type; } public Triangle(String type){ //constructor injection this.type=type; } } <bean id=triangle" class ="com.test.dependencyInjection.Triangle"> <constructor-arg value="20"/> </bean> 

2. Нагрузка зависимостей на основе сеттера:

Integer DI выполняется с помощью методов вызова контейнера на вашем beans после вызова конструктора no-argument или без аргумента static factory для создания экземпляра bean.

 public class Triangle{ private String type; public String getType(){ return type; } public void setType(String type){ //setter injection this.type = type; } } <!-- setter injection --> <bean id="triangle" class="com.test.dependencyInjection.Triangle"> <property name="type" value="equivialteral"/> 

Примечание: Хорошим правилом является использование аргументов конструктора для обязательных зависимостей и сеттеров для необязательных зависимостей. Обратите внимание, что если мы используем аннотацию, основанную на @Required аннотации на сеттер, можно использовать для создания сеттеров в качестве необходимых зависимостей.

17
ответ дан Harleen 04 дек. '15 в 8:50 2015-12-04 08:50

Лучшей аналогией, о которой я могу думать, является хирург и его помощник (ов) в операционном зале, где хирург - главный человек и его помощник, который предоставляет различные хирургические компоненты, когда он ему нужен, чтобы хирург мог сконцентрироваться по одной вещи он делает лучше всего (операция). Без помощника хирург должен получать компоненты самостоятельно каждый раз, когда ему это нужно.

DI для краткости - это метод, позволяющий устранить общую дополнительную ответственность (нагрузку) на компоненты для извлечения зависимых компонентов, предоставив их ему.

DI приближает вас к принципу единой ответственности (SR), как surgeon who can concentrate on surgery .

Когда использовать DI: я ​​бы рекомендовал использовать DI почти во всех производственных проектах (малый/большой), особенно в постоянно меняющихся бизнес-средах:)

Почему: потому что вы хотите, чтобы ваш код был легко проверяемым, макетируемым и т.д., чтобы вы могли быстро протестировать свои изменения и вывести его на рынок. Кроме того, почему бы вам не сделать, когда у вас есть множество потрясающих бесплатных инструментов/фреймворков, которые помогут вам в вашем пути к кодовой базе, где у вас больше контроля.

15
ответ дан Anwar Husain 05 апр. '16 в 19:15 2016-04-05 19:15

Все вышеприведенные ответы хороши, моя цель - объяснить концепцию простым способом, чтобы любой, кто не обладает знаниями в области программирования, также мог понять концепцию.

Внедрение зависимостей является одним из шаблонов проектирования, которые помогают нам создавать сложные системы более простым способом.

Мы можем видеть широкое применение этого шаблона в нашей повседневной жизни. Некоторые из примеров: магнитофон, VCD, CD-привод и т.д.

2019

ответ дан Samuel J Mathew 03 нояб. '17 в 10:36 2017-11-03 10:36

Это означает, что объекты должны иметь только столько зависимостей, сколько необходимо для выполнения своей работы, а зависимости должны быть немногочисленными. Кроме того, зависимости объектов должны быть от интерфейсов, а не от "конкретных" объектов, когда это возможно. (Конкретный объект - это любой объект, созданный с ключевым словом new.) Свободное соединение способствует большей повторности, упрощению ремонтопригодности и позволяет вам легко создавать "макетные" объекты вместо дорогостоящих услуг.

"Инъекция зависимостей" (DI) также известна как "Инверсия управления" (IoC), которая может использоваться как способ поощрения этой свободной связи.

Существует два основных подхода к реализации DI:

  • Ввод конструктора
  • Узел установки

Ввод конструктора

Его метод передачи объектов зависит от его конструктора.

Обратите внимание, что конструктор принимает интерфейс, а не конкретный объект. Также обратите внимание, что исключение вызывается, если параметр orderDao имеет значение NULL. Это подчеркивает важность получения действительной зависимости. Constructor Injection - это, на мой взгляд, предпочтительный механизм предоставления объекту его зависимостей. Это понятно разработчику при вызове объекта, зависимости которого должны быть переданы объекту "Человек" для правильного выполнения.

Инжекция сеттера

Но рассмотрим следующий пример... Предположим, у вас есть класс с десятью методами, которые не имеют зависимостей, но вы добавляете новый метод, который имеет зависимость от IDAO. Вы можете изменить конструктор для использования Constructor Injection, но это может заставить вас внести изменения во все вызовы конструктора по всему месту. Кроме того, вы можете просто добавить новый конструктор, который принимает зависимость, но тогда как разработчик легко знает, когда использовать один конструктор над другим. Наконец, если зависимость очень дорога для создания, почему она должна быть создана и передана конструктору, когда ее можно использовать редко? "Setter Injection" - это еще один метод DI, который можно использовать в таких ситуациях.

Setter Injection не приводит к передаче зависимостей конструктору. Вместо этого зависимости устанавливаются на публичные свойства, которые подвергаются объекту, который в этом нуждается. Как предполагалось ранее, основными мотивами для этого являются:

  • Поддержка инъекции зависимостей без необходимости изменения конструктора унаследованного класса.
  • Разрешить создание дорогостоящих ресурсов или служб как можно позже и только при необходимости.

Вот пример того, как выглядит следующий код:

 public class Person { public Person() {} public IDAO Address { set { addressdao = value; } get { if (addressdao == null) throw new MemberAccessException("addressdao" + " has not been initialized"); return addressdao; } } public Address GetAddress() { // ... code that uses the addressdao object // to fetch address details from the datasource ... } // Should not be called directly; // use the public property instead private IDAO addressdao; 
13
ответ дан Piyush Deshpande 07 янв. '14 в 14:45 2014-01-07 14:45

Например, у нас есть 2 класса Client и Service . Client будет использовать Service

 public class Service { public void doSomeThingInService() { // ... } } 

Без внедрения зависимостей

Способ 1)

 public class Client { public void doSomeThingInClient() { Service service = new Service(); service.doSomeThingInService(); } } 

Способ 2)

 public class Client { Service service = new Service(); public void doSomeThingInClient() { service.doSomeThingInService(); } } 

Способ 3)

 public class Client { Service service; public Client() { service = new Service(); } public void doSomeThingInClient() { service.doSomeThingInService(); } } 

1) 2) 3) Использование

 Client client = new Client(); client.doSomeThingInService(); 

faydaları

  • yalnız

Dezavantajlar

  • Хард для тестового Client класса
  • Когда мы меняем конструктор Service , нам нужно изменить код во всем месте создания объекта Service

Использовать инъекцию зависимостей

Способ 1) Конструктор впрыска

 public class Client { Service service; Client(Service service) { this.service = service; } // Example Client has 2 dependency // Client(Service service, IDatabas database) { // this.service = service; // this.database = database; // } public void doSomeThingInClient() { service.doSomeThingInService(); } } 

Yardımı ilə

 Client client = new Client(new Service()); // Client client = new Client(new Service(), new SqliteDatabase()); client.doSomeThingInClient(); 

Способ 2) Сеттер впрыска

 public class Client { Service service; public void setService(Service service) { this.service = service; } public void doSomeThingInClient() { service.doSomeThingInService(); } } 

Yardımı ilə

 Client client = new Client(); client.setService(new Service()); client.doSomeThingInClient(); 

Способ 3) Внедрение интерфейса

Проверьте https://en.wikipedia.org/wiki/Dependency_injection

===

Теперь этот код уже придерживается Dependency Injection и его проще тестировать на Client классе.
Тем не менее, мы все еще используем new Service() много раз, и это не очень хорошо, когда меняем конструктор Service . Чтобы предотвратить это, мы можем использовать инжектор DI, как
1) Простой ручной Injector

 public class Injector { public static Service provideService(){ return new Service(); } public static IDatabase provideDatatBase(){ return new SqliteDatabase(); } public static ObjectA provideObjectA(){ return new ObjectA(provideService(...)); } } 

С помощью

 Service service = Injector.provideService(); 

2) Используйте библиотеку: для Android dagger2

faydaları

  • Сделать тест проще
  • Когда вы меняете Service , вам нужно только изменить ее в классе инжекторов
  • Если вы используете Constructor Injection , когда вы посмотрите на конструктор Client , вы увидите, сколько зависит класс Client

Dezavantajlar

  • Если вы используете Constructor Injection , объект Service создается при создании Client , иногда мы используем функцию в классе Client без использования Service поэтому созданная Service теряется

Определение внедрения зависимости

https://en.wikipedia.org/wiki/Dependency_injection

Зависимость - это объект, который можно использовать ( Service )
Внедрение - это передача зависимости ( Service ) зависимому объекту ( Client ), который будет его использовать.

10
ответ дан Phan Van Linh 14 марта '18 в 7:41 2018-03-14 07:41

Я думаю, так как каждый написал для ДИ, позвольте мне задать несколько вопросов.

  • Если у вас есть конфигурация DI, где все фактические реализации (а не интерфейсы), которые будут внедрены в класс (например, службы для контроллера), почему это не какое-то жесткое кодирование?
  • Что делать, если я хочу изменить объект во время выполнения? Например, моя конфигурация уже говорит, когда я создаю экземпляр MyController, вставляю FileLogger как ILogger. Но я могу захотеть ввести DatabaseLogger.
  • Каждый раз, когда я хочу изменить те объекты, которые мне нужны в AClass, мне нужно теперь изучить два места: сам класс и файл конфигурации. Как это облегчает жизнь?
  • Если Aproperty из AClass не вводится, сложнее ли это издеваться?
  • Возвращаясь к первому вопросу. Если использование нового объекта() плохое, почему мы внедряем реализацию, а не интерфейс? Я думаю, многие из вас говорят, что мы на самом деле вводим интерфейс, но в конфигурации вы указываете реализацию этого интерфейса. Не во время выполнения. Он жестко запрограммирован во время компиляции.

Это основано на ответе @Adam N.

Почему PersonService больше не нужно беспокоиться о GroupMembershipService? Вы только что упомянули, что у GroupMembership есть несколько вещей (объектов/свойств), от которых это зависит. Если GMService был необходим в PService, вы бы использовали его как свойство. Вы можете издеваться над этим независимо от того, вводили вы его или нет. Единственный раз, когда я хотел бы, чтобы он был введен, - это если у GMService были более конкретные дочерние классы, которые вы не знали бы до выполнения. Затем вы хотите ввести подкласс. Или если вы хотите использовать это как синглтон или прототип. Честно говоря, файл конфигурации имеет все жестко закодированные, насколько подкласс для типа (интерфейса), который он будет вводить во время компиляции.

EDIT

Хороший комментарий Хосе Мария Арранц о DI

DI увеличивает сцепление, устраняя необходимость определения направления зависимости и записывая любой код клея.

False. Направление зависимостей находится в форме XML или в виде аннотаций, ваши зависимости написаны как XML-код и аннотации. XML и аннотации. Исходный код.

DI уменьшает сцепление, делая все ваши компоненты модульными (то есть заменяемыми) и имеет четко определенные интерфейсы друг к другу.

False. Для создания модульного кода на основе интерфейсов вам не нужна инфраструктура DI.

О сменном: с очень простым архивом .properties и Class.forName вы можете определить, какие классы могут измениться. Если ANY класс вашего кода можно изменить, Java не для вас, используйте язык сценариев. Кстати: аннотации не могут быть изменены без перекомпиляции.

По моему мнению, есть единственная причина для каркасов DI: сокращение плиты котла. С хорошо проделанной системой factory вы можете сделать то же самое, более контролируемое и более предсказуемое, как ваша предпочтительная структура DI, рамочная реализация кода фреймов DI (XML и аннотации также являются исходным кодом). Проблема в том, что это сокращение плиты котла просто реально в очень простых случаях (один экземпляр для каждого класса и т.д.), Иногда в реальном мире выбор подходящего объекта обслуживания не так прост, как сопоставление класса с одноэлементным объектом.

10
ответ дан Chookoos 25 окт. '13 в 6:56 2013-10-25 06:56

Injection of Dependency означает способ (фактически в любом случае ) для одной части кода (например, класса) для доступа к зависимостям (другие части кода, например, другие классы, это зависит от) модульным способом, не будучи жестко закодированным (чтобы они могли изменять или переопределяться свободно или даже загружаться в другое время по мере необходимости)

(и ps, да, это стало чрезмерно раздутым 25 $именем для довольно простой концепции), мои .25 центы

8
ответ дан Nikos M. 10 дек. '15 в 18:50 2015-12-10 18:50

Я знаю, что @ уже много, но я нашел это очень полезным: http://tutorials.jenkov.com/dependency-injection/index.html

Нет зависимости:

 public class MyDao { protected DataSource dataSource = new DataSourceImpl("driver", "url", "user", "password"); //data access methods... public Person readPerson(int primaryKey) {...} } 

Зависимость:

 public class MyDao { protected DataSource dataSource = null; public MyDao(String driver, String url, String user, String password){ this.dataSource = new DataSourceImpl(driver, url, user, password); } //data access methods... public Person readPerson(int primaryKey) {...} } 

Обратите внимание, как экземпляр DataSourceImpl перемещается в конструктор. Конструктор принимает четыре параметра, которые являются четырьмя значениями, необходимыми для DataSourceImpl . Хотя класс MyDao все еще зависит от этих четырех значений, он больше не удовлетворяет этим зависимостям. Они предоставляются любым классом, создающим экземпляр MyDao .

7
ответ дан Ali Issa 12 нояб. '14 в 17:37 2014-11-12 17:37

Популярные ответы бесполезны, потому что они определяют инъекцию зависимости таким образом, что это не полезно. Согласитесь, что под "зависимостью" мы подразумеваем некоторый ранее существовавший другой объект, который нужен нашему объекту X. Но мы не говорим, что делаем "инъекцию зависимостей", когда говорим

 $foo = Foo->new($bar); 

Мы просто называем это передачей параметров в конструктор. Мы делали это регулярно с тех пор, как были изобретены конструкторы.

"Инъекция зависимостей" считается типом "инверсии управления", а это означает, что из вызывающего абонента выведена некоторая логика. Это не тот случай, когда вызывающий абонент переходит в параметры, поэтому, если это было DI, DI не будет означать инверсию управления.

DI означает, что между вызывающим и конструктором существует промежуточный уровень, который управляет зависимостями. Makefile - простой пример инъекции зависимостей. "Вызывающий" - это человек, который набирает "make bar" в командной строке, а "конструктор" - это компилятор. Файл Makefile указывает, что бар зависит от foo, и он выполняет

 gcc -c foo.cpp; gcc -c bar.cpp 

перед выполнением

 gcc foo.o bar.o -o bar 

Человек, набравший "make bar" , не должен знать, что бар зависит от foo. Зависимость была введена между "make bar" и gcc.

Основная цель промежуточного уровня состоит не только в передаче зависимостей конструктору, но и в перечислении всех зависимостей только в одном месте и скрыть их от кодера (не для того, чтобы обеспечить их кодер).

Обычно промежуточный уровень предоставляет фабрики для построенных объектов, которые должны обеспечивать роль, которую должен удовлетворять каждый запрошенный тип объекта. Это потому, что, имея промежуточный уровень, который скрывает детали конструкции, вы уже понесли штраф за абстракцию, введенный фабриками, поэтому вы могли бы также использовать заводы.

7
ответ дан Phil Goetz 02 июня '15 в 21:09 2015-06-02 21:09

Инъекционная инъекция - одно из возможных решений того, что обычно можно назвать требованием "Зависимость обфускации". Зависимость Obfuscation - это метод принятия "очевидной" природы из процесса предоставления зависимости классу, который ее требует, и, следовательно, каким-то образом запутывает предоставление указанной зависимости указанному классу. Это не обязательно плохо. Фактически, путем запутывания способа предоставления зависимостям классу, то что-то вне класса отвечает за создание зависимости, что означает, что в разных сценариях может быть предоставлена ​​другая реализация зависимости, не внося никаких изменений к классу. Это отлично подходит для переключения между режимами производства и тестирования (например, с использованием зависимости "mock" ).

К сожалению, плохая часть состоит в том, что некоторые люди предположили, что вам нужна специализированная инфраструктура для обфускации зависимостей и что вы как-то "менее" программист, если не хотите использовать определенную инфраструктуру для этого. Другим, чрезвычайно тревожным мифом, по мнению многих, является то, что инъекция зависимостей - единственный способ добиться запутывания зависимости. Это явно и исторически и, очевидно, на 100% неверно, но у вас возникнут проблемы с убеждением некоторых людей в том, что есть альтернативы инъекции зависимостей для требований обфускации зависимостей.

Программисты поняли потребность в обфускации зависимостей в течение многих лет, и многие альтернативные решения эволюционировали как до, так и после инъекции зависимостей. Существуют шаблоны Factory, но также есть много вариантов, использующих ThreadLocal, где не требуется инъекция в конкретный экземпляр - зависимость эффективно вводится в поток, который имеет преимущество в том, чтобы сделать доступный объект (через удобные методы статического геттера) любому класс, который требует его, без необходимости добавлять аннотации к классам, которые его требуют, и создать сложный XML-клей, чтобы это произошло. Когда ваши зависимости требуются для настойчивости (JPA/JDO или что-то еще), это позволяет вам достичь "tranaparent persistence" намного проще и с классами модели домена и бизнес-модели, состоящими исключительно из POJO (т.е. Никакой специфической структуры/блокировки в аннотациях).

6
ответ дан Volksman 02 апр. '14 в 1:21 2014-04-02 01:21

Из книги, Хорошо обоснованный Java-разработчик: жизненные приемы программирования Java 7 и полиглота

DI - это особая форма IoC, в результате чего процесс нахождения зависимостей вне прямого управления вашим исполняемым кодом.

5
ответ дан TastyCode 18 мая '13 в 22:27 2013-05-18 22:27

Инъекция зависимостей (DI) является одной из шаблонов проектирования, в которой используется базовая функция OOP - отношения в одном объекте с другим объектом. Хотя наследование наследует один объект для создания более сложного и конкретного другого объекта, отношения или ассоциации просто создают указатель на другой объект из одного объекта с использованием атрибута. Мощность DI сочетается с другими функциями ООП, как и интерфейсы и скрывающий код. Предположим, у нас есть клиент (подписчик) в библиотеке, который может занять только одну книгу для простоты.

Интерфейс книги:

 package com.deepam.hidden; public interface BookInterface { public BookInterface setHeight(int height); public BookInterface setPages(int pages); public int getHeight(); public int getPages(); public String toString(); } 

Затем у нас может быть много книг; одним из типов является вымысел:

 package com.deepam.hidden; public class FictionBook implements BookInterface { int height = 0; // height in cm int pages = 0; // number of pages  public FictionBook() { // TODO Auto-generated constructor stub } @Override public FictionBook setHeight(int height) { this.height = height; return this; } @Override public FictionBook setPages(int pages) { this.pages = pages; return this; } @Override public int getHeight() { // TODO Auto-generated method stub return height; } @Override public int getPages() { // TODO Auto-generated method stub return pages; } @Override public String toString(){ return ("height: " + height + ", " + "pages: " + pages); } } 

Теперь абонент может иметь связь с книгой:

 package com.deepam.hidden; import java.> 

Все три класса могут быть скрыты для его собственной реализации. Теперь мы можем использовать этот код для DI:

 package com.deepam.implement; import com.deepam.hidden.Subscriber; import com.deepam.hidden.FictionBook; public class CallHiddenImplBook { public CallHiddenImplBook() { // TODO Auto-generated constructor stub } public void doIt() { Subscriber ab = new Subscriber(); // injection I FictionBook bookI = new FictionBook(); bookI.setHeight(30); // cm bookI.setPages(250); ab.setBook(bookI); // inject System.out.println("injection I " + ab.getBook().toString()); // injection II FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set System.out.println("injection II " + ab.getBook().toString()); } public static void main(String[] args) { CallHiddenImplBook kh = new CallHiddenImplBook(); kh.doIt(); } } 

Существует множество способов использования инъекции зависимостей. Можно объединить его с Singleton и т.д., Но все же в базовом это только ассоциация, реализуемая путем создания атрибута типа объекта внутри другого объекта. Полезность только и только в функции, этот код, который мы должны писать снова и снова, всегда готов и сделан для нас вперед. Вот почему DI так тесно связан с Inversion of Control (IoC), что означает, что наша программа передает управляющий другой запущенный модуль, который делает инъекции beans в наш код. (Каждый объект, который может быть введен, может быть подписан или рассмотрен как Bean.) Например, в Spring это делается путем создания и инициализации контейнера ApplicationContext, что делает это для нас. Мы просто в нашем коде создаем контекст и вызываем инициализацию beans. В этот момент инъекция была сделана автоматически.

4
ответ дан hariprasad 20 сент. '15 в 15:33 2015-09-20 15:33

из книги Apress.Spring.Persistence.with.Hibernate.Oct.2010

Цель инъекции зависимостей - отделить работу устранение внешних программных компонентов из вашего приложения логика. Без введения зависимостей детали того, как компонент доступ к требуемым сервисам может запутаться с компонентами код. Это не только увеличивает вероятность ошибок, добавляет код раздувание и увеличение сложности обслуживания; он соединяет компоненты вместе, что затрудняет изменение зависимостей, когда рефакторинг или тестирование.

4
ответ дан BERGUIGA Mohamed Amine 28 авг. '15 в 13:00 2015-08-28 13:00

Включение зависимостей является основой концепции, связанной с Spring Framework.While создание структуры любого проекта Spring может выполнять жизненно важную роль, и здесь инъекция зависимостей приходит в кувшин.

На самом деле, предположим, что в java вы создали два разных класса как класс A и класс B, и независимо от того, какая функция доступна в классе B, которую вы хотите использовать в классе A, поэтому в это время может использоваться инъекция зависимостей. где вы можете разбивать объект одного класса на другой, таким же образом вы можете ввести целый класс в другой класс, чтобы сделать его доступным. Таким образом, зависимость может быть преодолена.

ВЗАИМОДЕЙСТВИЕ ЗАВИСИМОСТИ ПРОСТО СКРЫВАЕТ ДВУХ КЛАССОВ И В ТО ЖЕ ВРЕМЯ, ПОДДЕРЖИВАЯ ИХ ОТДЕЛЬНО.

3
ответ дан mohit sarsar 28 мая '14 в 12:08 2014-05-28 12:08

В простых словах инъекция зависимостей (DI) - это способ удаления зависимостей или жесткой связи между разными объектами. Инъекция зависимостей дает когезионное поведение каждому объекту.

DI - это реализация принципала IOC Spring, в котором говорится: "Не звоните нам, мы позвоним вам". Использование программиста для инъекций зависимостей не требуется для создания объекта с использованием нового ключевого слова.

Объекты загружаются в контейнер Spring, а затем мы их повторно используем, когда нам это нужно, путем извлечения этих объектов из контейнера Spring с использованием метода getBean (String beanName).

3
ответ дан Waqas Ahmed 12 нояб. '13 в 8:19 2013-11-12 08:19

Инъекция зависимостей (DI) является частью практики принципа инверсии зависимостей (DIP), которая также называется Inversion of Control (IoC). В основном вам нужно сделать DIP, потому что вы хотите сделать свой код более модульным и единым тестируемым, а не только одной монолитной системой. Итак, вы начинаете идентифицировать части кода, которые можно отделить от класса и отвлечь. Теперь выполнение абстракции нужно вводить извне класса. Обычно это можно сделать с помощью конструктора. Таким образом, вы создаете конструктор, который принимает абстракцию как параметр, и это называется инъекцией зависимостей (через конструктор). Для более подробного описания контейнера DIP, DI и IoC вы можете прочитать здесь

3
ответ дан kusnaditjung tjung 04 июня '16 в 2:34 2016-06-04 02:34

Инъекция зависимостей - это тип реализации принципа Инверсия управления , на основе которого построено Frameworks.

Рамки , как указано в "Шаблон проектирования" GoF, являются классами, которые реализуют логику основного потока управления, создающую разработчика для этого, таким образом, Frameworks реализуют инверсию принципа управления.

Способ реализовать как метод, а не как иерархию классов, этот принцип IoC - это просто инъекция зависимостей.

DI состоит в основном в деле делегировании отображения экземпляров классов и ссылки на эти экземпляры на внешний "объект": объект, статический класс, компонент, структуру и т.д.

Экземпляры классов - это " зависимые ", внешняя привязка вызывающего компонента с экземпляром класса через ссылку - это " injection ".

Очевидно, что вы можете реализовать эту технику во многом так же, как вы хотите, с точки зрения ООП, см., например, инжекцию конструктора, инъекцию установщика, инъекцию интерфейса.

Делегирование третьей стороны для выполнения задачи сопоставления ссылки на объект очень полезно, когда вы хотите полностью отделить компонент, который нуждается в некоторых сервисах от реализации одних и тех же сервисов.

Таким образом, при разработке компонентов вы можете сосредоточиться исключительно на своей архитектуре и своей конкретной логике, доверяя интерфейсам для совместной работы с другими объектами, не беспокоясь о каких-либо изменениях в реализации объектов или сервисов, также если один и тот же объект вы используете, будет полностью заменена (очевидно, соблюдая интерфейс).

1
ответ дан Ciro Corvino 18 нояб. '16 в 1:01 2016-11-18 01:01

Я бы предложил немного другое, короткое и точное определение того, что такое инъекция зависимостей, сосредоточившись на основной цели, а не на технических средствах (следуя отсюда ):

Dependency Injection - это процесс создания статического графика без атрибутов объектов службы, где каждая служба параметризуется своими зависимостями.

Объекты, которые мы создаем в наших приложениях (независимо от того, используем ли я Java, С# или другой объектно-ориентированный язык), обычно попадают в одну из двух категорий: статические и глобальные "объекты обслуживания" (модули), а также состояния, динамические и локальные "объекты данных".

График модулей - график объектов службы - обычно создается при запуске приложения. Это можно сделать с помощью контейнера, такого как Spring, но также можно выполнить вручную, передав параметры конструкторам объектов. Оба способа имеют свои плюсы и минусы, но фреймворк определенно не нужен для использования DI в вашем приложении.

Одним из требований является то, что услуги должны быть параметризованы их зависимостями. То, что это означает, в точности зависит от языка и подхода, применяемого в данной системе. Обычно это принимает форму параметров конструктора, но использование настроек также является опцией. Это также означает, что зависимости службы скрыты (при вызове метода услуги) от пользователей службы.

Когда использовать? Я бы сказал, всякий раз, когда приложение достаточно велико, что инкапсуляция логики в отдельные модули, с графиком зависимости между модулями дает выигрыш в удобочитаемости и изучаемости кода.

1
ответ дан adamw 21 сент. '18 в 12:42 2018-09-21 12:42
  • 1
  • 2

Другие вопросы по меткам > или Задайте вопрос