it-swarm-tr.com

Bağımlılık enjeksiyonu nedir?

bağımlılık enjeksiyonu hakkında ne zaman ne zaman kullanılacağı ve bunun için hangi çerçevelerin mevcut olduğu gibi özel sorular içeren birçok soru var. Ancak,

Bağımlılık enjeksiyonu nedir ve ne zaman/neden kullanılmalı veya kullanılmamalıdır?

2811
AR.

Temel olarak nesnelerinizin bir bağımlılık yaratmasını sağlamak veya bir fabrika nesnesinden bir tane yapmasını istemek yerine, ihtiyaç duyulan bağımlılıkları dışarıdan nesneye aktarırsınız ve başka birinin problemini yaparsınız. Bu "birisi" ya bağımlılık grafiğini daha ileriye taşıyan bir nesne veya bağımlılık grafiğini oluşturan bir bağımlılık enjektörüdür (çerçeve). Burada kullandığım gibi bağımlılık, mevcut nesnenin referans alması gereken diğer nesnelerdir.

Bağımlılık enjeksiyonunun en büyük avantajlarından biri, test lotlarını daha kolay hale getirebilmesidir. Yapıcıda şöyle bir şey yapan bir nesneniz olduğunu varsayalım:

public SomeClass() {
    myObject = Factory.getObject();
}

Yapmanız gereken tek şey SomeClass üzerinde bazı ünite testleri yapmak olduğunda, özellikle myObject karmaşık disk veya ağ erişimi olan bir şeyse, bu sorun yaratabilir. Yani şimdi alaycı myObject a bakıyorsunuz ama aynı zamanda bir şekilde fabrika aramasını da engelliyorsunuz. Zor. Bunun yerine nesneyi yapıcıya argüman olarak iletin. Artık sorunu başka bir yere taşıdınız, ancak test yapmak çok daha kolay hale gelebilir. Sadece bir kukla myObject olun ve bunu iletin. Yapıcı şimdi biraz benzeyecek:

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

Bu, yapıcı aracılığıyla bir bağımlılık enjeksiyonu tarzıdır. Birkaç mekanizma mümkündür. 

  • Yorumlarda belirtildiği gibi, ortak bir alternatif hiçbir işe yaramaz yapıcı tanımlamak ve özellik belirleyicileri (h/t @MikeVella) aracılığıyla enjekte edilen bağımlılıklara sahip olmaktır. 
  • Martin Fowler üçüncü bir alternatifi (h/t @MarcDix), sınıflara enjekte edilmek istedikleri bağımlılıklar için açıkça bir arayüz uyguladıklarını belgelemektedir.

Bağımlılık enjeksiyonunu kullanmıyorken (inşaatçılarında çok fazla iş yapan sınıflarda olduğu gibi), ünite testinde bileşenleri izole etmek daha zor hale gelir. 

2013'te bu cevabı yazdığımda, bu - Google Test Blog ’da çok önemli bir konuydu. Bu, benim için en büyük avantaj olmaya devam ediyor, çünkü çalışma zamanı tasarımınızda her zaman ekstra esnekliğe ihtiyaç duymayabilirsiniz (örneğin, servis bulucu veya benzer modeller için), ancak çoğu zaman sınıflarınızı test sırasında yalıtmanız gerekir.

1764
wds

Şimdiye kadar bulduğum en iyi tanım James Shore tarafından

"Bağımlılık Enjeksiyonu" 25 dolarlık bir eşittir. 5 kuruş konsepti için kullanılan terim. [...] Bağımlılık enjeksiyonu, bir .__ vermek anlamına gelir. örnek değişkenlerini itiraz et. [...].

Bu konuda da faydalı olabilecek Martin Fowler tarafından yazılmış bir makale vardır.

Bağımlılık enjeksiyonu temel olarak bir nesnenin kendisi yapması yerine ihtiyaç duyduğu nesneleri (bağımlılıklarını) sağlıyor. Bağımlılıkların alay edilmesine veya engellenmesine izin verdiği için test için çok faydalı bir tekniktir.

Bağımlılıklar nesnelere birçok yolla enjekte edilebilir (yapıcı enjeksiyon veya ayarlayıcı enjeksiyon gibi). Biri bunu yapmak için özel bağımlılık enjeksiyon çerçevelerini (örneğin Bahar) kullanabilir, ancak kesinlikle gerekli değildir. Bağımlılık enjeksiyonuna sahip olmak için bu çerçevelere ihtiyacınız yok. Nesnelerin (bağımlılıkların) açıkça ortaya konması ve aktarılması, çerçeve tarafından enjeksiyon yapmak kadar bir enjeksiyon kadar iyidir.

2167
Thiago Arrais

Bu komik örneği gevşek bağlantı : açısından buldum.

Herhangi bir uygulama, faydalı şeyler yapmak için birbirleriyle işbirliği yapan pek çok nesneden oluşur. Geleneksel olarak her nesne, birlikte çalıştığı bağımlı nesnelere (bağımlılıklar) kendi referanslarını almaktan sorumludur. Bu, yüksek derecede eşleşmiş sınıflara ve test edilmesi zor bir koda yol açar.

Örneğin, Carnesnesini göz önünde bulundurun.

Bir Carname__, çalışacak tekerleklere, motora, yakıta, aküye vb. Bağlıdır. Geleneksel olarak, böyle bağımlı nesnelerin markasını, Carnesnesinin tanımıyla birlikte tanımlarız.

Bağımlılık Enjeksiyonu Olmadan (DI):

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

Burada, Carnesnesi bağımlı nesneleri oluşturmaktan sorumludur.

İlk bağımlı NepaliRubberWheel() delikten sonra - bağımlı nesnesinin türünü değiştirmek istiyorsak - yani Wheel- diyelim mi? Car nesnesini, yeni bağımlılığı ChineseRubberWheel() diyerek yeniden oluşturmamız gerekir, ancak bunu yalnızca Carüreticisi yapabilir.

Öyleyse Dependency Injection bizim için ne yapar ...?

Bağımlılık enjeksiyonunu kullanırken nesnelere bağımlılıkları verilir derleme zamanı yerine çalışma zamanında (otomobil üretim zamanı). Böylece artık istediğimiz zaman Wheeldosyasını değiştirebiliriz. Burada, dependency(wheelname__) çalışma zamanında Cariçine enjekte edilebilir.

Bağımlılık enjeksiyonunu kullandıktan sonra:

Burada, çalışma zamanında bağımlılıkları (Tekerlek ve Batarya) enjekte ediyoruz. . Dolayısıyla terim: Bağımlılık Enjeksiyonu.

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;
  }
}

Kaynak: Bağımlılık enjeksiyonunu anlama

598
gtiwari333

Bağımlılık Enjeksiyonu, nesnelerin dahili olarak inşa etmek yerine nesnelerin örneklerini diğer kod parçalarından alacakları şekilde tasarlandığı bir uygulamadır. Bu, nesne için gerekli olan arayüzü uygulayan herhangi bir nesnenin, kodu basitleştirmeden değiştirilebileceği anlamına gelir; bu, testi basitleştirir ve ayrıştırmayı geliştirir.

Örneğin, şu ipleri göz önünde bulundurun:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
} 

Bu örnekte, PersonService::addManager ve PersonService::removeManager öğelerinin uygulanması, çalışmasını yapabilmek için GroupMembershipService örneğine ihtiyaç duyar. Bağımlılık Enjeksiyonu olmadan, bunu yapmanın geleneksel yolu, GroupMembershipService yapıcısında yeni bir PersonService örneği oluşturmak ve bu örnek niteliğini her iki işlevde kullanmaktır. Bununla birlikte, GroupMembershipService yapıcısının gerektirdiği veya daha da kötüsü çok şey varsa, GroupMembershipService'da çağrılması gereken bazı başlatma "ayarlayıcıları" vardır, kod oldukça hızlı bir şekilde büyür ve PersonService artık yalnızca GroupMembershipService'a değil, ayrıca GroupMembershipService'nın bağlı olduğu diğer her şey. Dahası, GroupMembershipService ile olan bağlantı PersonService içine kodlanmıştır, bu da test amaçlı olarak bir GroupMembershipService '' taklit edemeyeceğiniz '' veya uygulamanızın farklı bölümlerinde bir strateji deseni kullanamayacağınız anlamına gelir. 

Dependency Injection ile, GroupMembershipService içindeki PersonService örneğini başlatmak yerine, onu PersonService yapıcısına iletir veya yerel bir örneğini ayarlamak için bir Özellik (alıcı ve ayarlayıcı) eklersiniz. Bu, PersonService dosyanızın artık GroupMembershipService oluşturma hakkında endişelenmek zorunda kalmayacağı, yalnızca verilenleri kabul ettiği ve onlarla çalıştığı anlamına gelir. Bu ayrıca GroupMembershipService alt sınıfı olan veya GroupMembershipService arabirimini uygulayan herhangi bir şeyin PersonService içine "enjekte edilebileceği" anlamına gelir ve PersonService değişikliği hakkında bilgi sahibi olmak zorunda değildir.

241
Adam Ness

Kabul edilen cevap iyi bir cevap - ancak şunu da belirtmek isterim ki, DI kodda kodlanmış sabitlerden kaçınılan klasikten çok uzaktır. 

Bir veritabanı adı gibi bir sabit kullandığınızda, onu kodun içinden hızlı bir şekilde bazı config dosyasına taşır ve bu değeri içeren bir değişkeni gereken yere iletirsiniz. Bunu yapmanın nedeni, bu sabitlerin genellikle kodun geri kalanından daha sık değişmesidir. Örneğin, kodu bir test veritabanında test etmek istiyorsanız. 

DI Nesne Yönelimli programlama dünyasında buna benzer. Sabit değişmezler yerine oradaki değerler bütün nesnelerdir - ancak bunları oluşturan kodun sınıf kodundan çıkarılmasının nedeni benzerdir - nesneler bunları kullanan koddan daha sık değişir. Böyle bir değişimin gerekli olduğu önemli bir durum testlerdir.

155
zby

Car ve Engine sınıfları ile basit bir örnek deneyelim, herhangi bir otomobilin en azından şimdilik, herhangi bir yere gitmek için bir motora ihtiyacı var. Bu yüzden aşağıda kod bağımlılık enjeksiyonu olmadan nasıl görünecek.

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

Ve Car sınıfını başlatmak için bir sonraki kodu kullanacağız:

Car car = new Car();

Bu kodla ilgili olarak GasEngine ile sıkı bir şekilde birleştiğimiz ve eğer bunu ElectricityEngine olarak değiştirmeye karar verirsek, o zaman Araba sınıfını yeniden yazmamız gerekecek. Uygulama büyüdükçe, daha fazla sorun ve baş ağrısı da yeni tip motor eklemek ve kullanmak zorunda kalacağız. 

Bir başka deyişle, bu yaklaşımla üst düzey Car sınıfımızın, SOLID'den Bağımlılık İnversiyon Prensibi'ni (DIP) ihlal eden daha düşük seviyeli GasEngine sınıfına bağlı olmasıdır. DIP, somut sınıflara değil soyutlamalara dayanmamız gerektiğini ileri sürüyor. Bu yüzden bunu tatmin etmek için IEngine arayüzünü tanıtıyoruz ve aşağıdaki gibi bir kod yazıyoruz:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

Artık Car sınıfı, belirli bir motor uygulamasına değil, yalnızca IEngine arayüzüne bağlıdır. Şimdi, tek püf noktası, nasıl bir otomobil örneği yaratacağız ve ona GasEngine veya ElectricityEngine gibi gerçek bir somut Motor sınıfı vereceğiz. Bağımlılık Enjeksiyonu buraya giriyor. 

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

Burada temel olarak bağımlılığımızı (Engine örneği) Car yapıcısına enjekte ederiz (geçer). Şimdi sınıflarımız nesneler ve onların bağımlılıkları arasında gevşek bir bağa sahipler ve Araba sınıfını değiştirmeden yeni motor türlerini kolayca ekleyebiliriz.

Zorluk kodlu bağımlılıkları olmadığı için, sınıfların daha gevşek bir şekilde bağlanmış olduğu Bağımlılık Enjeksiyonu 'nin temel yararı. Bu yukarıda belirtilen Bağımlılık İnversiyon Prensibi'ni izler. Belirli uygulamalara gönderme yapmak yerine, sınıflar, sınıf oluşturulurken kendilerine sağlanan soyutlamaları (genellikle arayüzler) ister.

Sonuçta Bağımlılık enjeksiyonu sadece .__ için bir tekniktir. nesneler ve bağımlılıkları arasında gevşek eşleşme sağlanması. Sınıfın ihtiyaç duyduğu doğrudan somutlaştırıcı bağımlılıklar yerine, eylemlerini gerçekleştirmek için sınıfa bağımlılıklar sağlanır. (çoğunlukla) yapıcı enjeksiyon yoluyla.

Ayrıca birçok bağımlılığa sahip olduğumuzda, tüm bağımlılıklarımız için hangi arayüzlerin hangi somut uygulamalarla eşleştirileceğini söyleyebileceğimiz ve tüm bağımlılıklarımız için hangi somut uygulamalarla eşleştirileceğini söyleyebileceğimiz Inversion of Control (IoC) konteynerleri kullanmak çok iyi bir uygulamadır Amacımız. Örneğin, IoC kabı eşlemesinde, IEngine bağımlılığının GasEngine sınıfına eşlenmesi gerektiğini ve IoC kabını Car sınıfının bir örneğini sorduğumuzda belirtebiliriz , otomatik olarak Car sınıfımızı, bir GasEngine bağımlılığı geçerek oluşturacak. 

UPDATE: Geçenlerde Julie Lerman'dan EF Core hakkında bir kurs izledim ve DI hakkında kısa tanımını beğendim.

Bağımlılık enjeksiyonu, uygulamanızın enjekte edilmesini sağlayan bir kalıptır. Nesneleri zorlamaksızın onlara ihtiyaç duyan sınıflara uçuyor. Bu nesnelerden sorumlu olan sınıflar. Kodunuzun .__ olmasını sağlar. daha gevşek bir şekilde birleştiğinde ve Entity Framework Çekirdeği de aynı hizmetler sistemi.

103
user2771704

Balığa gitmek istediğinizi düşünelim:

  • Bağımlılık enjeksiyonu olmadan, her şeye kendiniz bakmanız gerekir. Bir tekne bulmanız, bir olta satın almak, yem aramak, vb. Gerekir. Bu elbette mümkündür, ancak size çok fazla sorumluluk yükler. Yazılım açısından, tüm bu şeyleri aramanız gerektiği anlamına gelir.

  • Bağımlılık enjeksiyonuyla, bir başkası tüm hazırlıklara özen gösterir ve gerekli ekipmanı size sunar. Kullanıma hazır olan tekneyi, oltayı ve yemi alacaksınız ("enjekte edilecek").

102
Olivier Liechti

BuBağımlılık Enjeksiyonu ve Bağımlılık Enjeksiyon Kabı hakkında şimdiye kadar gördüğüm en basit açıklama.

Bağımlılık Enjeksiyonu Olmadan

  • Uygulamanın Foo'ya (örneğin bir denetleyici) ihtiyacı var, yani:
  • Uygulama Foo oluşturur
  • Uygulama Foo .__ çağırır.
    • Foo'nun Bar'a ihtiyacı var (ör. Hizmet), bu nedenle:
    • Foo Bar yaratıyor
    • Foo, Bar .__'u çağırıyor.
      • Bar’ın Bim’e (bir hizmet, bir depo, …) İhtiyacı var.
      • Bar Bim'i yarattı
      • Bar bir şey yapar

Bağımlılık Enjeksiyonu ile

  • Uygulama, Bim'e ihtiyaç duyan Bar'a ihtiyaç duyan Foo'ya ihtiyaç duyuyor:
  • Uygulama Bim oluşturur
  • Uygulama Bar oluşturur ve Bim verir
  • Uygulama Foo oluşturur ve Bar verir
  • Uygulama Foo .__ çağırır.
    • Foo, Bar .__'u çağırıyor.
      • Bar bir şey yapar

Bağımlılık Enjeksiyon Kabı Kullanma

  • Uygulama Foo'ya ihtiyaç duyuyor:
  • Uygulama Konteynırdan Foo alır, yani:
    • Konteyner Bim yaratıyor
    • Container Bar yaratır ve Bim verir
    • Container, Foo yaratır ve ona Bar verir
  • Uygulama Foo .__ çağırır.
    • Foo, Bar .__'u çağırıyor.
      • Bar bir şey yapar

Bağımlılık Enjeksiyonu ve bağımlılık Enjeksiyon Konteynerleri farklı şeylerdir:

  • Bağımlılık Enjeksiyonu daha iyi kod yazmak için bir yöntemdir
  • dI Kapsayıcı bağımlılıkları enjekte etmeye yardımcı olan bir araçtır

Bağımlılık enjeksiyonunu yapmak için bir kaba ihtiyacınız yok. Ancak bir konteyner size yardımcı olabilir.

86
Trix

“Bağımlılık enjeksiyonu” sadece parametreleştirilmiş kurucular ve halka açıklayıcılar kullanmak anlamına gelmiyor mu?

James Shore'nin makalesi karşılaştırma için aşağıdaki örnekleri göstermektedir .

Bağımlılık enjeksiyonu olmayan yapıcı:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

Bağımlılık enjeksiyonlu yapıcı:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}
49
JaneGoodall

Bağımlılık Enjeksiyonu (DI) Nedir?

Diğerlerinin dediği gibi, Bağımlılık Enjeksiyonu (DI) , ilgilenen sınıfımızın (tüketici sınıfı) olduğu diğer nesne örneklerinin doğrudan yaratılması ve ömrünün yönetimi sorumluluğunu ortadan kaldırır. bağımlı ( UML anlamında ). Bu örnekler bunun yerine tüketici sınıfımıza, tipik olarak yapıcı parametreleri olarak veya mülk belirleyicileri yoluyla (müşteri sınıfına giren ve tüketici sınıfına geçen bağımlılık nesnesinin yönetimi genellikle Kontrolün Tersine Çevirilmesi (IoC) kapsayıcı, ancak bu başka bir konudur).

DI, DIP ve SOLID

Özellikle, Robert C Martin'in paradigmasında Nesne Yönelimli Tasarımın Katı ilkeleri, DI, Bağımlılık İnversiyon İlkesi'nin (DIP) olası uygulamalarından biridir. . DIP, D mantrasınınSOLID değeridir - diğer DIP uygulamaları Hizmet Bulucu ve Eklenti modellerini içerir.

DIP'in amacı, sınıflar arasında sıkı ve somut bağımlılıkları ayırmak ve bunun yerine, dili ve yaklaşıma bağlı olarak, bir interface, abstract class veya pure virtual class ile elde edilebilecek bir soyutlama yoluyla kuplajı gevşetmektir. Kullanılmış.

DIP olmadan, kodumuz (bu 'tüketen sınıf' olarak adlandırdım) doğrudan somut bir bağımlılıkla birleştirilir ve ayrıca genellikle bu bağımlılığın bir örneğini nasıl elde edeceğinizi ve yöneteceğinizi bilme sorumluluğuyla da yüklenir, yani kavramsal olarak:

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

DIP uygulamasından sonra, gereksinim gevşetilir ve Foo bağımlılığının ömrünü elde etme ve yönetme kaygısı kaldırılmıştır:

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

Neden DIP (ve DI) kullanıyorsunuz?

Bu şekilde sınıflar arasındaki bağımlılıkların ayrıştırılması, bu bağımlılık sınıflarının, soyutlamanın ön koşullarını da yerine getiren diğer uygulamalarla birlikte easy ikame yapılmasına izin verir (örneğin bağımlılık, Aynı arayüz). Dahası, diğerlerinin de belirttiği gibi, muhtemelen the DIP aracılığıyla sınıfları ayırmanın en yaygın nedeni, tüketilen bir sınıfın izolasyonda test edilmesine izin vermektir, çünkü bu aynı bağımlılıklar şimdi engellenebilir. ve/veya alay.

DI'nin bir sonucu, bağımlılık nesnesi örneklerinin kullanım ömrü yönetimi artık bağımlılık nesnesi artık tüketici sınıfına geçirildiği için (yapıcı veya ayarlayıcı enjeksiyon yoluyla) artık bir tüketici sınıf tarafından kontrol edilmemesidir.

Bu farklı şekillerde görülebilir:

  • Tüketici sınıfının ömür boyu bağımlılık kontrolünün korunması gerekiyorsa, bağımlılık sınıfı örneklerini oluşturmak için tüketici sınıfına bir (soyut) fabrika enjekte edilerek kontrol yeniden tesis edilebilir. Tüketici, fabrikada gerektiğinde Create kullanarak örnekler elde edebilecek ve bu örnekleri tamamlandıktan sonra elden çıkarabilecektir.
  • Veya, bağımlılık durumlarının ömür boyu kontrolü bir IoC kabına bırakılabilir (aşağıda daha fazlası var).

DI ne zaman kullanılır?

  • Muhtemelen eşdeğer bir uygulama için bir bağımlılık yerine ihtiyaç duyulacaksa,
  • Üniteyi test etmeniz gereken her zaman, bir sınıfın metotlarını bağımlılıklarını izole ederek test etmek,
  • Bir bağımlılığın kullanım ömrünün belirsizliği deneyi zorunlu kılabilirse (örneğin, Hey, MyDepClass iş parçacığı güvenlidir - ya bunu bir tekil yapar ve aynı örneği tüm tüketicilere enjekte edersek)?

Örnek

İşte basit bir C # uygulaması. Aşağıda Tüketici sınıfı verilmiştir:

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

Her ne kadar zararsız görünse de, diğer iki sınıfa iki static bağımlılığı vardır, System.DateTime ve System.Console, yalnızca günlük çıktı seçeneklerini sınırlamakla kalmaz (konsola giriş yapmak kimse izlemiyorsa değersizdir), ancak daha da kötüsü zordur deterministik olmayan bir sistem saatine bağımlılığı verilen otomatik olarak test etmek.

Bununla birlikte, bu sınıfa DIP uygulayabiliriz, bağımlılık olarak zaman damgası endişesini ortadan kaldırarak ve sadece basit bir arabirime MyLogger bağını kaldırarak:

public interface IClock
{
    DateTime Now { get; }
}

Ayrıca Console üzerindeki bağımlılığı TextWriter gibi bir soyutlamaya gevşetebiliriz. Bağımlılık Enjeksiyonu, tipik olarak, constructor enjeksiyon (tüketen bir sınıfın yapıcısına bir parametre olarak bir soyutlamaya geçen) veya Setter Injection (bağımlılığı setXyz() ayarlayıcı veya a .Net özelliği ile {set;} tanımlı) geçirerek uygulanır. . Yapıcı Enjeksiyonu tercih edilir, çünkü bu, sınıfın inşaattan sonra doğru durumda olmasını ve iç bağımlılık alanlarının readonly (C #) veya final (Java) olarak işaretlenmesine izin verir. Bu yüzden yukarıdaki örnekte yapıcı enjeksiyonunu kullanmak, bizi şu şekilde bırakır:

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);
    }
}

(Elbette DateTime.Now 'e dönebilecek olan bir somut Clock sağlanmalı ve bu iki bağımlılık, bir IoC kabı tarafından yapıcı enjeksiyonu yoluyla sağlanmalıdır)

Artık bağımlılıklar üzerinde kontrolümüz olduğu için günlüğümüzün doğru çalıştığını kesin olarak kanıtlayan otomatik bir Birim Testi oluşturulabilir, çünkü zaman ve yazılı çıktıya göz atabiliriz:

[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());
}

Sonraki Adımlar

Bağımlılık enjeksiyonu, somut bağımlılık örneklerini enjekte etmek (sağlamak) ve yaşam süresi örneklerini yönetmek için Kontrol konteynerinin Ters Çevirilmesi (IoC) ile her zaman ilişkilidir. Yapılandırma/önyükleme işlemi sırasında, IoC kapları aşağıdakilerin tanımlanmasına izin verir:

  • her bir soyutlama ve yapılandırılmış somut uygulama arasında eşleştirme (örneğin, bir tüketici bir IBar istediğinde istediği zaman "_, ConcreteBar örneği döndür" ")
  • her bağımlılığın yaşam boyu yönetimi için politikalar belirlenebilir; her tüketici örneği için yeni bir nesne oluşturmak, tüm tüketicilerdeki tek bir bağımlılık örneğini paylaşmak, aynı bağımlılık örneğini yalnızca aynı iş parçacığı boyunca paylaşmak vb.
  • Net'te, IoC kapları IDisposable gibi protokollerin farkındadır ve yapılandırılan kullanım ömrü yönetimi doğrultusunda Disposing bağımlılıklarının sorumluluğunu üstlenir.

Tipik olarak, IoC kapları bir kez konfigüre edildikten/önyüklendikten sonra, kodlayıcıya bağımlılıklardan endişe etmek yerine eldeki koda odaklanmasına izin veren arka planda sorunsuz şekilde çalışırlar.

DI-dostu kodun anahtarı, sınıfların statik birleştirilmesinden kaçınmak ve Bağımlılıklar oluşturmak için new () kullanmamaktır.

Yukarıdaki örnekte olduğu gibi, bağımlılıkların çözülmesi bazı tasarım çabaları gerektirir ve geliştirici için, newing bağımlılıklarının doğrudan alışkanlığını ortadan kaldırmak ve bunun yerine bağımlılıkları yönetmek için kaba güvenmek için gereken bir paradigma kayması vardır.

Fakat faydalar çoktur, özellikle de ilgi alanınızı tamamen sınamak için.

Not : POCO/POJO/Serileştirme DTO'ları/Varlık Grafikleri/Anonim JSON projeksiyonları ve diğerleri - yani "Verilerin oluşturulması/haritalanması/projeksiyonu (new ..() yoluyla) yalnızca "sınıflar veya kayıtlar - kullanılan veya yöntemlerden döndürülenler not Bağımlılıklar olarak kabul edilir (UML anlamında) ve DI'ye tabi değildir. Bunları yansıtmak için new kullanmak tamamen uygun.

36
StuartLC

Bağımlılık Enjeksiyonu kavramının anlaşılmasını kolaylaştırmak. Bir ampulü değiştirmek (açmak/kapatmak) için anahtar düğmesine bir örnek verelim.

Bağımlılık Enjeksiyonu Olmadan

Anahtarın hangi ampule bağlı olduğumu önceden bilmesi gerekir (kodlanmış bağımlılık). Yani,

Anahtar -> KalıcıBulb // anahtar doğrudan kalıcı ampule bağlanır, kolay test edilemez

 

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

Bağımlılık Enjeksiyonu ile

Anahtar sadece bana hangi ampulün geçtiğini açmak/kapatmak zorunda olduğumu bilir. Yani,

Geçiş -> Ampul1 OR Ampul2 OR NightBulb (enjekte edilen bağımlılık)

 

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

Değiştirme James Anahtar ve Ampul İçin Örnek:

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`
33
wakqasahmed

Bağımlılık Enjeksiyonunun (DI) bütün amacı uygulama kaynak kodunu temiz ve sabit tutmaktır:

  • temiz bağımlılık başlatma kodu
  • kararlı kullanılan bağımlılığa bakılmaksızın

Pratik olarak, her tasarım deseni gelecekteki değişikliklerin minimum dosyaları etkilemesi için endişeleri ayırır.

DI'nin özel alanı, bağımlılık konfigürasyonu ve ilklendirme temsilcisidir.

Örnek: Shell scriptli DI

Zaman zaman Java dışında çalışıyorsanız, source 'nin birçok betik dilinde (Shell, Tcl, vb., Hatta Python'da import bile kullanılmadığını) nasıl kullanıldığını hatırlayın.

Basit dependent.sh betiğini göz önünde bulundurun:

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

Komut dosyası bağımlıdır: kendi başına başarılı bir şekilde yürütülmez (archive_files tanımlanmadı).

archive_files uygulama kodunda archive_files_Zip.sh tanımlayın (bu durumda Zip kullanarak):

#!/bin/sh
# Dependency
function archive_files {
    Zip files.Zip "[email protected]"
}

source- nin uygulama komut dosyasını doğrudan bağımlı olanın içinde kullanmak yerine, her iki "bileşeni" saran bir injector.sh "container" kullanırsınız:

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

archive_filesbağımlılık, sadece enjekte, bağımlı betiğine dönüştürüldü.

tar veya xz kullanarak archive_files uygulayan bağımlılık enjekte etmiş olabilirsiniz.

Örnek: DI'yi çıkarma

dependent.sh betiği doğrudan bağımlılıkları kullanıyorsa, yaklaşıma bağımlılık araması (bu, {bağımlılık enjeksiyonunu ile zıt olan) olarak adlandırılır:

#!/bin/sh
# Dependent

# dependency look-up
source ./archive_files_Zip.sh

touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

Şimdi sorun şu ki, bağımlı "bileşen" başlatma işlemini kendisi yapmak zorunda.

"Bileşen" in kaynak kodu ne clean ne de stable değildir, çünkü bağımlılıkların başlatılmasındaki her değişiklik "bileşenler" in kaynak kod dosyası için de yeni sürüm gerektirir.

Son sözler

DI, Java çerçevelerinde olduğu gibi büyük ölçüde vurgulanmış ve popüler değildir.

Ancak, endişelerini bölmek için genel bir yaklaşım:

  • uygulama gelişme (tek kaynak kodu sürüm yaşam döngüsü)
  • uygulama konuşlandırma (çoklu bağımsız yaşam döngüleri olan hedef ortamlar)

Konfigürasyonun sadece bağımlılık araması ile kullanılması, konfigürasyon parametrelerinin sayısı, bağımlılık başına (örneğin yeni kimlik doğrulama tipi) ve desteklenen bağımlılık tipi sayısı (ör. Yeni veritabanı türü) başına değişebileceğinden yardımcı olmaz.

25
uvsmtid

Yukarıdaki tüm cevaplar iyidir, amacım kavramı basit bir şekilde açıklamaktır; böylece programlama bilgisi olmayan herkes de kavramı anlayabilir

Bağımlılık enjeksiyonu, karmaşık sistemleri daha basit bir şekilde oluşturmamıza yardımcı olan tasarım modellerinden biridir.

Günümüz hayatında bu kalıbın çok çeşitli uygulamalarını görebiliriz . Örneklerden bazıları Teyp, VCD, CD Sürücü vb.

 Reel-to-reel portable tape recorder, mid-20th century.

Yukarıdaki resim, 20. yüzyılın ortalarında, Reel-reel portatif ses kayıt cihazının bir görüntüsüdür. Kaynak .

Bir teyp makinesinin birincil amacı, sesi kaydetmek veya çalmaktır.

Bir sistemi tasarlarken, ses veya müzik kaydetmek veya çalmak için bir makaraya ihtiyaç duyar. Bu sistemi tasarlamak için iki olasılık var

  1. makarayı makinenin içine yerleştirebiliriz
  2. makaraya yerleştirilebileceği bir kanca sağlayabiliriz.

Birincisini kullanırsak, makarayı değiştirmek için makineyi açmamız gerekir .. ... ikincisini seçersek, bu makara için bir kanca yerleştirirse, makarayı değiştirerek herhangi bir müzik çalma avantajı elde ederiz. . ve ayrıca sadece makaradaki her şeyi çalmak için fonksiyonun azaltılması.

Akıllıca bağımlılık enjeksiyonu gibi, bağımsız bileşenlerin karmaşık bir sistem oluşturmak üzere bir araya getirilebilmesi için sadece bileşenin spesifik işlevselliğine odaklanmak için bağımlılıkları dışa aktarma işlemidir.

Bağımlılık enjeksiyonunu kullanarak elde ettiğimiz temel faydalar.

  • Yüksek yapışma ve gevşek bağlantı.
  • Bağımlılığı dışlamak ve sadece sorumluluğu aramak.
  • İşleri bileşen olarak yapmak ve yüksek yeteneklere sahip geniş bir sistem oluşturmak için birleştirmek.
  • Bağımsız bir şekilde geliştirildiklerinden, doğru bir şekilde test edildiklerinden, yüksek kaliteli bileşenlerin geliştirilmesine yardımcı olur.
  • Biri başarısız olursa bileşenin bir başkasıyla değiştirilmesine yardımcı olur.

Günümüzde, bu kavram programlama dünyasında iyi bilinen çerçevelerin temelini oluşturuyor .. __ Bahar Açısı vb. Bu konseptin üstüne inşa edilmiş iyi bilinen yazılım çerçeveleridir.

Bağımlılık enjeksiyonu, diğer nesnelerin derleme zamanında hangi işlevselliği sağlamak için kullanılacağını bilmeksizin dayandığı nesnelerin örneklerini oluşturmak için kullanılan bir kalıptır veya bir nesneye basitçe özellikleri enjekte etme yöntemine bağımlılık enjeksiyonu denir.

Bağımlılık enjeksiyonu örneği

Önceden böyle kod yazıyoruz

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

Bağımlılık enjeksiyonu ile bağımlılık enjektörü bizim için örneklememizi kaldıracak 

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

Ayrıca okuyabilir

Kontrol İnversiyonu ve Bağımlılık Enjeksiyonu Arasındaki Fark

18
Samuel J Mathew

Bağımlılık Enjeksiyonu Nedir?

Bağımlılık Enjeksiyonu (DI), birbirine bağlı olan nesneleri ayırmak anlamına gelir. Diyelim ki A nesnesi B Nesnesine bağlı olduğundan, fikir bu nesneyi birbirinden ayırmak. Derleme zamanına rağmen, çalışma zamanında nesnelere bağımlılık paylaşmayı tercih eden yeni anahtar kelime kullanarak nesneyi zorlamak zorunda değiliz . 

Bağımlılık Enjeksiyonu İlkbaharda Nasıl Çalışır:

Konfigürasyon dosyasındaki fasulye bağımlılığını tanımlamak yerine, yeni anahtar kelime kullanarak nesneyi zorla kodlamamız gerekmez. Yaylı kap, kancayı takmaktan sorumlu olacaktır.

Kontrolün Ters Çevirilmesi (IOC)

IOC genel bir kavramdır ve birçok farklı şekilde ifade edilebilir ve Bağımlılık Enjeksiyonu, IOC'nin somut bir örneğidir.

İki Bağımlılık Enjeksiyonu türü:

  1. Yapıcı Enjeksiyon
  2. Ayarlayıcı Enjeksiyon

1. Oluşturucu tabanlı bağımlılık enjeksiyonu:

Yapıcı tabanlı DI, konteyner her biri diğer sınıfa bağımlılığı temsil eden bir takım argümanlara sahip bir sınıf kurucuyu çağırdığında gerçekleştirilir.

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. Setter bazlı bağımlılık enjeksiyonu:

Setter tabanlı DI, fasulyenizi somutlaştırmak için bir bağımsız değişken yapıcı veya bağımsız değişken statik fabrika yöntemini çağırdıktan sonra fasulyenizdeki konteyner çağrı ayarlayıcı yöntemleri ile gerçekleştirilir.

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"/>

NOT: Zorunlu bağımlılıklar için yapıcı argümanlarını ve isteğe bağlı bağımlılıklar için ayarlayıcıları kullanmak iyi bir kuraldır. Bir ayarlayıcıda @ İstenilen açıklamaya göre bir not kullanırsak, ayarlayıcıları gerekli bağımlılıklar yapmak için kullanabileceğinizi unutmayın.

17
Harleen

Aklıma gelen en iyi benzetme, cerrahın asıl kişi olduğu bir ameliyathanedeki cerrah ve asistanı/cerrahlarıdır; cerrahın ihtiyaç duyduğu anda çeşitli cerrahi bileşenleri sağlayan asistandır Yaptığı en iyi şey (ameliyat). Asistan olmadan, cerrah her ihtiyacı olduğunda bileşenleri kendisi almak zorundadır.

Kısaca DI, ona bağlı bileşenleri sağlayarak, bağımlı bileşenleri almak için bileşenler üzerine ortak bir ek sorumluluğu (yükü) kaldırma tekniğidir.

DI sizi surgeon who can concentrate on surgery gibi Tek Sorumluluk (SR) ilkesine yaklaştırır.

DI ne zaman kullanılır: DI'yi neredeyse tüm üretim projelerinde (küçük/büyük), özellikle de sürekli değişen iş ortamlarında kullanmanızı tavsiye ederim :)

Neden: Çünkü, kodunuzun kolayca test edilebilir, takılabilir vb. Olmasını istersiniz, böylece değişikliklerinizi hızlı bir şekilde test edebilirsiniz ve piyasaya sürün. Ayrıca neden daha fazla kontrole sahip olduğunuz bir kod temeli yolculuğunuzda sizi destekleyecek harika ücretsiz araçlar/çerçeveler varken olmasın?.

15
Anwar Husain

Bu, nesnelerin yalnızca işlerini yapmak için gereken kadar bağımlılığa sahip olması ve bağımlılıkların az olması gerektiği anlamına gelir. Ayrıca, bir nesnenin bağımlılıkları mümkün olduğunda “somut” nesneler üzerinde değil, arayüzler üzerinde olmalıdır. (Somut bir nesne, yeni anahtar kelimeyle oluşturulan herhangi bir nesnedir.) Gevşek bağlantı, daha fazla yeniden kullanılabilirlik, daha kolay bakım kolaylığı sağlar ve pahalı hizmetler yerine kolayca “sahte” nesneler sağlamanıza olanak tanır.

“Bağımlılık Enjeksiyonu” (DI) “Kontrolün Ters Çevirilmesi” (IoC) olarak da bilinir, bu gevşek eşleşmeyi teşvik etmek için bir teknik olarak kullanılabilir.

DI'yi uygulamak için iki temel yaklaşım vardır:

  1. Yapıcı enjeksiyon 
  2. Ayarlayıcı enjeksiyon

Yapıcı enjeksiyon

Nesnelerin bağımlılıklarını kurucusuna iletme tekniğidir.

Yapıcının bir nesneyi kabul ettiğini ve somut bir nesneyi kabul etmediğini unutmayın. Ayrıca orderDao parametresi boşsa bir istisna atıldığını unutmayın. Bu, geçerli bir bağımlılık almanın önemini vurgulamaktadır. Yapıcı Enjeksiyon, bence, bir nesneye bağımlılıklarını vermek için tercih edilen mekanizmadır. Nesneyi çağırırken geliştiriciye, hangi uygulamaların uygun bir şekilde yürütülmesi için “Kişi” nesnesine verilmesi gerektiği açıktır.

Ayarlayıcı Enjeksiyon

Ancak aşağıdaki örneği göz önünde bulundurun… Diyelim ki, on metodu bağımlı olmayan bir sınıfınız olduğunu, fakat IDAO'ya bağımlı olan yeni bir yöntem eklediğinizi varsayalım. Yapıcı Enjeksiyonunu kullanmak için yapıcıyı değiştirebilirsiniz, ancak bu sizi her yerdeki tüm yapıcı çağrılarında değişiklik yapmaya zorlayabilir. Alternatif olarak, bağımlılığı alan yeni bir kurucu ekleyebilirsiniz, ancak bir geliştirici bir kurucuyu diğerine ne zaman kullanacağını kolayca bilir. Son olarak, eğer bağımlılık yaratması çok pahalı ise, neden sadece nadiren kullanılabiliyorsa yaratılmalı ve yapıcıya aktarılmalıdır? “Setter Enjeksiyonu”, bu gibi durumlarda kullanılabilecek bir başka DI tekniğidir.

Setter Enjeksiyonu, yapıcıya iletilen bağımlılıkları zorlamaz. Bunun yerine, bağımlılıklar ihtiyaç duyulan nesnenin maruz kaldığı kamu malları üzerine kuruludur. Daha önce de belirtildiği gibi, bunu yapmak için birincil motivasyon aşağıdakileri içerir:

  1. Eski bir sınıfın kurucusunu değiştirmek zorunda kalmadan bağımlılık enjeksiyonunu desteklemek.
  2. Pahalı kaynakların veya hizmetlerin mümkün olduğu kadar geç ve yalnızca gerektiğinde oluşturulmasına izin vermek.

Yukarıdaki kodun nasıl göründüğüne bir örnek:

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

Örneğin, 2 sınıf Client ve Service var. ClientService kullanacak

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

Bağımlılık Enjeksiyonu Olmadan

Yol 1)

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

2. Yol)

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

Yol 3)

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

1) 2) 3) Kullanarak

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

Avantajları

  • Basit

Dezavantajları

  • Test için zor Client sınıfı
  • Service yapıcısını değiştirdiğimizde, her yerde Service nesnesi kodunu değiştirmemiz gerekir

Bağımlılık Enjeksiyonu Kullan

Yol 1) Yapıcı enjeksiyon

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();
    }
}

kullanılarak

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

Yol 2) Ayarlayıcı enjeksiyonu

public class Client {
    Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

kullanılarak

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

Yol 3) Arayüz enjeksiyonu

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

===

Şimdi, bu kod zaten Dependency Injection öğesini takip ediyor ve Client sınıfı testi için daha kolay.
Ancak, yine de birçok zaman new Service() kullanıyoruz ve Service yapıcısını değiştirdiğinizde iyi değil. Bunu önlemek için DI enjektörünü kullanabiliriz.
1) Basit manuel 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(...));
    }
}

Kullanma

Service service = Injector.provideService();

2) Kütüphaneyi kullanın: Android hançer2

Avantajları

  • Testi kolaylaştırın
  • Service öğesini değiştirdiğinizde, sadece Injector sınıfında değiştirmeniz gerekir.
  • Eğer Constructor Injection kullanıyorsanız, Client yapıcısına baktığınızda, Client sınıfının ne kadar bağımlı olduğunu göreceksiniz.

Dezavantajları

  • Constructor Injection kullanıyorsanız, Service nesnesi Client oluşturulduğunda oluşturulur, bazen Client sınıfında işlevini kullanırız Service kullanmayın, böylece oluşturulan Service boşa harcanır

Bağımlılık Enjeksiyonu tanımı

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

Bağımlılık kullanılabilecek bir nesnedir (Service)
Bir enjeksiyon bağımlılığın (Service) onu kullanan bir bağımlı nesneye (Client) geçirilmesidir.

13
Phan Van Linh

Sanırım herkes DI için yazdığından, birkaç soru sorayım.

  1. Bir DI konfigürasyonuna sahip olduğunuzda, bir sınıfa enjekte edilecek tüm gerçek uygulamaları (arayüzler değil) (örneğin bir kontrol cihazına servisler için) enjekte edilecek olan bu neden bir tür kodlama değil? 
  2. Çalışma zamanında nesneyi değiştirmek istersem ne olur? Örneğin, benim config zaten MyController'ı başlattığımda, FileLogger'ı ILogger olarak enjekte ettiğimi söylüyor. Ancak DatabaseLogger'ı enjekte etmek isteyebilirim. 
  3. AClass'ımın ihtiyaç duyduğu nesneleri değiştirmek istediğimde, şimdi iki yere bakmam gerekiyor - sınıfın kendisi ve yapılandırma dosyası. Bu hayatı nasıl kolaylaştırıyor?
  4. AClass'ın Aproperty'si enjekte edilmezse, bununla alay etmek daha mı zor? 
  5. İlk soruya geri döneceğim. Yeni bir nesne () kullanmak kötüyse, arayüzü nasıl uygularız? Sanırım çoğunuz aslında arayüzü enjekte ettiğimizi söylüyorsunuz, ancak konfigürasyon bu arayüzün uygulanmasını belirtmenizi sağlar. Çalışma zamanında değil .. derleme süresi boyunca kodlanmıştır.

Bu yayınlanan @Adam N cevabı dayanmaktadır.

Neden PersonService'in GroupMembershipService için endişelenmesine gerek yok? Az önce bahsettiğiniz GroupMembership'in bağlı olduğu birden fazla şey (nesne/özellik) var. PService'de GMService gerekli olsaydı, bir özellik olarak sahip olurdu. Enjekte edip etmediğinize bakmaksızın bununla alay edebilirsiniz. Enjekte edilmesini istediğim tek zaman, GMService'in çalışma zamanına kadar bilemeyeceğiniz daha spesifik alt sınıfları olup olmadığıydı. O zaman alt sınıfı enjekte etmek istersiniz. Veya bunu singleton veya prototip olarak kullanmak istiyorsanız. Dürüst olmak gerekirse, yapılandırma dosyası, derleme süresi boyunca enjekte edilecek bir tür (arabirim) için hangi alt sınıfa kadar kodlanmış her şeye sahiptir. 

D&UUML;ZENLE 

Jose Maria Arranz tarafından DI üzerine güzel bir yorum

DI, bağımlılık yönünü belirleme ve herhangi bir yapıştırıcı kodunu yazma gereksinimini ortadan kaldırarak uyumu arttırır.

Yanlış. Bağımlılıkların yönü XML biçiminde veya ek açıklamalar şeklindedir, bağımlılıklarınız XML kodu ve ek açıklamalar şeklinde yazılmıştır. XML ve ek açıklamalar ARE kaynak kodu.

DI, tüm bileşenlerinizi modüler hale getirerek (yani değiştirilebilir) ve birbirlerine iyi tanımlanmış arayüzlere sahip olarak kaplin azaltır.

Yanlış. Arayüzlere dayalı modüler bir kod oluşturmak için bir DI çerçevesine ihtiyacınız yoktur.

Değiştirilebilirlik hakkında: çok basit bir .properties arşivi ve Class.forName ile hangi sınıfların değiştirebileceğini tanımlayabilirsiniz. Kodunuzun HERHANGİ bir sınıfı değiştirilebiliyorsa, Java sizin için değildir, bir komut dosyası dili kullanın. Bu arada: ek açıklamalar yeniden derlenmeden değiştirilemez.

Bence DI çerçevelerinin tek bir nedeni var: kazan plakası azalması. İyi yapılmış bir fabrika sistemiyle, tercih ettiğiniz DI çerçevesiyle aynı, daha kontrollü ve daha öngörülebilir olanı yapabilirsiniz, DI çerçeveleri kod azaltma sözü verir (XML ve ek açıklamalar da kaynak koddur). Sorun şu ki, bu kazan plakası azaltma, çok basit durumlarda (sınıf başına bir örnek ve benzeri) sadece gerçektir, bazen gerçek dünyada, uygun servis nesnesini seçmek, bir sınıfı bir singleton nesnesine eşlemek kadar kolay değildir.

10
Chookoos

Bağımlılık Enjeksiyonu , kodun bir kısmı için (örneğin bir sınıf) bağımlılıklara (diğer kod parçaları, örneğin diğer sınıflara bağlı olarak) erişmenin bir yolu (aslında herhangi bir şekilde) anlamına gelir kodlanmış olmadan modüler bir şekilde (böylece serbestçe değiştirilebilir veya geçersiz kılınabilir, ya da gerektiğinde başka bir zamanda yüklenebilir)

(ve ps, evet oldukça basit, konsept için aşırı keskin 25 $ bir isim haline geldi), .25 sent

8
Nikos M.

Çoktan cevaplar olduğunu biliyorum ama bunu çok faydalı buldum: http://tutorials.jenkov.com/dependency-injection/index.html

Bağımlılık Yok:

public class MyDao {

  protected DataSource dataSource =
    new DataSourceImpl("driver", "url", "user", "password");

  //data access methods...
  public Person readPerson(int primaryKey) {...}

}

Bağımlılık:

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 başlatmasının nasıl bir yapıcıya taşındığına dikkat edin. Yapıcı, DataSourceImpl tarafından ihtiyaç duyulan dört değer olan dört parametre alır. MyDao sınıfı hala bu dört değere bağlı olsa da, artık bu bağımlılıkları karşılamıyor. Bunlar MyDao örneğini oluşturan her sınıf tarafından sağlanır.

7
Ali Issa

Popüler cevaplar yararsızdır, çünkü bağımlılık enjeksiyonunu yararlı olmayan bir şekilde tanımlarlar. "Bağımlılık" ile, X nesnesinin ihtiyaç duyduğu önceden var olan başka bir nesneyi kastettiğimizi kabul edelim. Ama biz söylediğimizde "bağımlılık enjeksiyonu" yaptığımızı söylemiyoruz.

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

Biz sadece bu parametrelere yapıcı diyoruz. Yapıcılar icat edildiğinden beri bunu düzenli olarak yapıyoruz.

"Bağımlılık enjeksiyonu", bir tür "kontrolün tersine çevrilmesi" olarak kabul edilir; bu, bir mantığın arayandan çıkarıldığı anlamına gelir. Arayan parametrelerden geçtiğinde durum böyle değil, bu yüzden DI olsaydı DI, kontrolün ters çevrilmesi anlamına gelmezdi.

DI, arayan ve bağımlılıkları yöneten yapıcı arasında bir orta seviye olduğu anlamına gelir. Makefile, bağımlılık enjeksiyonunun basit bir örneğidir. "Arayan" komut satırına "make bar" yazan kişi ve "yapıcı" derleyicidir. Makefile, çubuğun foo'ya bağlı olduğunu belirtir ve

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

yapmadan önce

gcc foo.o bar.o -o bar

"Make bar" yazan kişinin, barın foo'ya bağlı olduğunu bilmesi gerekmez. Bağımlılık "make bar" ve gcc arasına enjekte edildi.

Orta seviyenin temel amacı, sadece yapıcıya bağımlılıklardan geçmek değil, tüm bağımlılıkları sadece tek bir yerde sıralamak ve bunları kodlayıcıdan gizlemektir (kodlayıcıyı sağlamak için değil) .

Genellikle ara seviye, istenen her nesne tipinin yerine getirmesi gereken bir rol sağlaması gereken inşa edilmiş nesneler için fabrikalar sağlar. Bunun nedeni, inşaatın ayrıntılarını gizleyen bir ara seviyeye sahip olmanız, zaten fabrikaların dayattığı soyutlama cezalarını zaten üstlendiğinizden dolayı, fabrikaları da kullanabilirsiniz.

7
Phil Goetz

Bağımlılık enjeksiyonu, genellikle "Bağımlılık Gizliliği" şartı olarak adlandırılabilecek bir çözümdür. Bağımlılık Yasaklama, “açık” bir niteliği, onu gerektiren bir sınıfa bağımlılık sağlama sürecinden çıkarmanın bir yöntemidir ve bu nedenle bir şekilde sözü geçen sınıfa bağımlılığın sağlanmasını engeller. Bu mutlaka kötü bir şey değil. Aslında, bir sınıfa bağımlılığın nasıl sağlandığını gizlemenin ardından, sınıf dışında bir şey bağımlılığın yaratılmasından sorumludur; bu, çeşitli senaryolarda, herhangi bir değişiklik yapmadan sınıfa farklı bir bağımlılık uygulaması sağlanabileceği anlamına gelir. sınıfa. Bu, üretim ve test modları arasında geçiş yapmak için idealdir (örneğin, 'sahte' bir hizmet bağımlılığı kullanarak).

Ne yazık ki, kötü olan kısım, bazı insanların bağımlılık şaşırtmalarını yapmak için özel bir çerçeveye ihtiyaç duyduklarını ve bunu yapmak için belirli bir çerçeveyi kullanmamayı seçerseniz bir şekilde 'daha az' bir programcı olduğunuzu varsaymalarıdır. Birçoğunun inandığı, son derece rahatsız edici bir efsane, bağımlılık enjeksiyonunun bağımlılık şaşırtmanın tek yolu olduğu yönündedir. Bu kanıtlanabilir ve tarihsel ve açık bir şekilde% 100 yanlıştır, ancak bazı insanları bağımlılık şaşırtma gereksinimleriniz için bağımlılık enjeksiyonuna alternatifler olduğuna ikna etmekte zorlanacaksınız.

Programcılar yıllarca bağımlılık gizleme gereksinimini anlamış ve bağımlılık enjeksiyonunun tasarlanmasından önce ve sonra birçok alternatif çözüm gelişti. Fabrika kalıpları vardır, ancak ThreadLocal'ı kullanarak, belirli bir örneğe enjeksiyon yapılmasının gerekli olmadığı yerlerde birçok seçenek vardır - bağımlılık, nesnenin kullanılabilir olmasını sağlama avantajına sahip olan (rahatlık statik alıcı yöntemleri yoluyla) herhangi birine gerektiren sınıflara açıklama eklemek zorunda kalmadan bunu gerektiren sınıf ve bunu gerçekleştirmek için karmaşık XML yapıştırıcıyı kurun. Bağımlılıklarınız süreklilik için gerekli olduğunda (JPA/JDO veya her neyse), 'kalıcı kalıcılık' elde etmenize çok daha kolay ve yalnızca POJO'lardan oluşan etki alanı modeli ve iş modeli sınıfları ile (yani ek açıklamalarda belirli bir çerçeveye özel/kilitli değil) ulaşmanıza olanak tanır.

6
Volksman

Kitaptan, ' Temelli Java Geliştiricisi: Java 7'nin hayati teknikleri ve polyglot programlama

DI, bağımlılıklarınızı bulma sürecinin .__ olduğu özel bir IoC şeklidir. Yürütmekte olan kodunuzun doğrudan kontrolü dışında.

5
TastyCode

Bağımlılık Enjeksiyonu (DI), OOP 'in temel özelliğini kullanan Tasarım Birimlerinden biridir - bir nesnede başka bir nesne ile ilişki. Kalıtım, bir nesneyi daha karmaşık ve spesifik başka bir nesne yapmak için miras alırken, ilişki veya ilişki, niteliği kullanarak bir nesneden başka bir nesneye bir işaretçi oluşturur. DI'nin gücü, arabirimler ve gizleme kodu gibi diğer OOP özellikleriyle bir aradadır . Kitaplıkta basitlik için sadece bir kitap ödünç alabilen bir müşterimiz (abone) var.

Kitabın Arayüzü:

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();
}

Sonra birçok kitap alabiliriz; türlerinden biri kurgu:

package com.deepam.hidden;

public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages

/** constructor */
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);
}
}

Artık abone kitabla ilişki kurabilir:

package com.deepam.hidden;

import Java.lang.reflect.Constructor;
import Java.lang.reflect.InvocationTargetException;

public class Subscriber {
BookInterface book;

/** constructor*/
public Subscriber() {
    // TODO Auto-generated constructor stub
}

// injection I
public void setBook(BookInterface book) {
    this.book = book;
}

// injection II
public BookInterface setBook(String bookName) {
    try {
        Class<?> cl = Class.forName(bookName);
        Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
        BookInterface book = (BookInterface) constructor.newInstance();
        //book = (BookInterface) Class.forName(bookName).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return book;
}

public BookInterface getBook() {
  return book;
}

public static void main(String[] args) {

}

}

Her üç sınıf da kendi uygulaması için gizlenebilir. Şimdi bu kodu DI için kullanabiliriz:

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();
}
}

Bağımlılık enjeksiyonunu kullanmanın birçok farklı yolu vardır. Bunu Singleton, vb. İle birleştirmek mümkündür, ancak yine de temelde, sadece başka bir nesnenin içinde nesne türünün niteliği yaratılarak yapılan ilişkilendirmedir. tekrar ve tekrar her zaman bizim için hazırlanır ve yapılır. Bu nedenle DI'nin, Inversion of Control (IoC) ile bu kadar yakından bağlanması, yani programımızın kontrolümüze geçmesi anlamına gelir, bu da kodumuza fasulye enjekte eden başka bir çalışan modülü kontrol eder. (Enjekte edilebilen her nesne bir Fasulye olarak imzalanabilir veya imzalanabilir.) Örneğin, ilkbaharda bu bizim için çalışan ApplicationContext container oluşturularak ve başlatılarak yapılır. Biz sadece kodumuzda İçeriği yaratır ve fasulyeyi başlatmayı çağırırız. O anda enjeksiyon otomatik olarak yapılmıştır.

4
hariprasad

kitaptan Apress.Spring.Persistence.with.Hibernate.Oct.2010

Bağımlılık enjeksiyonunun amacı, Harici yazılım bileşenlerini uygulama işinizden çözme. mantık. Bağımlılık enjeksiyonu olmadan, bir bileşenin detayları. gerekli hizmetlere erişirse, bileşenin .__ ile karıştırılabilir. kodu. Bu sadece hata potansiyelini arttırmakla kalmıyor, kod .__ da ekliyor. şişkinlik ve bakım karmaşıklıklarını büyütür; bileşenleri eşler birbirlerine daha yakın, bağımlılıkların zaman zaman değişmesini zorlaştırıyor. yeniden düzenleme veya test etme.

4

Basit bir ifadeyle, bağımlılık enjeksiyonu (DI), bağımlılıkları ortadan kaldırmanın veya farklı nesneler arasındaki sıkı kaplin yoludur. Bağımlılık Enjeksiyonu, her bir nesneye yapışkan bir davranış verir. 

DI, “Bizi arama, sizi arayacağız” diyen IOC Bahar müdürünün uygulamasıdır. Bağımlılık enjeksiyon programlayıcısının kullanılması, yeni anahtar sözcüğü kullanarak nesne oluşturmanıza gerek yoktur. 

Nesneler bir kez Spring kapsayıcısına yüklenir ve daha sonra bu nesneleri Spring kapsayıcısından getBean (String beanName) yöntemini kullanarak almak istediğimizde yeniden kullanırız.

3
Waqas Ahmed

Bağımlılık Enjeksiyonu (DI), Bağımlılık İnversiyon Prensibi (DIP) uygulamasının bir parçasıdır, buna da Kontrol İnversiyonu (IoC) adı verilir. Temel olarak DIP işlemine ihtiyacınız var çünkü kodunuzu daha tek bir monolitik sistem yerine daha modüler ve ünite test edilebilir hale getirmek istiyorsanız. Böylece kodun sınıftan ayrılabilecek ve soyutlanabilecek kısımlarını tanımlamaya başlarsınız. Şimdi soyutlamanın uygulanmasının sınıf dışından enjekte edilmesi gerekiyor. Normalde bu, yapıcı aracılığıyla yapılabilir. Böylece soyutlamayı parametre olarak kabul eden bir kurucu yaratıyorsunuz ve buna bağımlılık enjeksiyonu deniyor (yapıcı aracılığıyla). DIP, DI ve IoC konteyneri hakkında daha fazla açıklama için Buradan

3

Bağımlılık enjeksiyonu, Spring Framework ile ilgili kavramın kalbidir. Herhangi bir proje yayının çerçevesini oluştururken hayati bir rol oynayabilir ve burada bağımlılık enjeksiyonu sürahiye gelir.

Aslında, Java’da, A sınıfı ve B sınıfı olarak iki farklı sınıf oluşturduğunuzu ve B sınıfı için hangi fonksiyonun mevcut olduğunu, A sınıfı için kullanmak istediğinizden, yani o zaman bağımlılık enjeksiyonunu kullanabilirsiniz. Başka bir sınıfın kasa nesnesi diğerinde, aynı şekilde başka bir sınıfa bütün bir sınıfı enjekte ederek ulaşılabilir hale getirebilirsiniz .. Bu şekilde bağımlılığın üstesinden gelinebilir.

BAĞIMSIZLIK ENJEKSİYONU IS İKİ SINIFTAKİ SIKIŞTIRMA VE AT AYRI TUTAN AYI SÜRE.

3
mohit sarsar

Bağımlılık Enjeksiyonunun ne olduğunun, teknik amaçlara değil, temel hedefe odaklanarak ( here 'dan sonra) biraz farklı, kısa ve kesin bir tanımını öneriyorum:

Bağımlılık Enjeksiyonu, statik, durumsuz .__ oluşturma işlemidir. Her servisin parametresi ile belirtildiği hizmet nesneleri grafiği. bağımlılıklar.

Uygulamalarımızda yarattığımız nesneler (Java, C # veya başka bir nesne yönelimli dil kullanıyor olsak da) genellikle iki kategoriden birine girer: vatansız, statik ve global “hizmet nesneleri” (modüller) ve durumlu, dinamik ve yerel “Veri nesneleri”.

Modül grafiği - servis nesnelerinin grafiği - genellikle uygulama başlangıcında oluşturulur. Bu, Spring gibi bir kap kullanılarak yapılabilir, ancak parametrelerin nesne yapıcılarına iletilmesiyle de elle yapılabilir. Her iki yolun da avantajları ve dezavantajları vardır, ancak uygulamanızda DI kullanmak için kesinlikle bir çerçeve gerekmez.

Bir gereklilik, hizmetlerin bağımlılıkları tarafından parametrelenmesi gerektiğidir. Bunun tam olarak anlamı, verilen sistemde alınan dile ve yaklaşıma bağlıdır. Genellikle, bu yapıcı parametrelerini alır, ancak ayarlayıcıları kullanmak da bir seçenektir. Bu aynı zamanda bir servisin bağımlılıklarının, servis kullanıcılarının kullanımından gizlenen (bir servis yöntemi çağrılırken) anlamına gelir.

Ne zaman kullanılır? Ne zaman uygulama yeterince mantık, ayrı modüller içine enkapsüle olan, modüller arasında bir bağımlılık grafik ile kodun okunabilirliği ve keşfedilirliği bir kazanç sağlar derim.

2
adamw

Bağımlılık Enjeksiyonu, ayrıştırılmış bileşeni, bazı bağımlılıklarından agnostik hale getirme uygulamasıdır; bu, şunu söyleyen KATI rehberini izler.

Bağımlılık inversiyon ilkesi: "soyutlamalara bağlı olmalı,

Bağımlılık Enjeksiyonunun daha iyi uygulanması, Bileşenlerin bağımlılık enjeksiyon kabından ayrıştırılmasına izin verdiği için Kompozisyon Kökü tasarım desenidır.

Kompozisyon Root http://blog.ploeh.dk/2011/07/28/CompositionRoot/ Hakkında Mark Seemann tarafından yazılmış bu harika makaleyi tavsiye ediyorum.

i̇şte bu makalenin temel noktaları:

Bir Kompozisyon Kökü, bir uygulamada (tercihen) benzersiz bir konumdur. modüllerin birarada olduğu yerler.

...

Sadece uygulamalarda Kompozisyon Kökü bulunmalıdır. Kütüphaneler ve çerçeveler olmamalıdır.

...

Bir DI Konteyneri sadece Kompozisyon Kökünden ..__ referans alınmalıdır. Diğer tüm modüllerin konteynere referansı olmamalıdır.

Bağımlılık enjeksiyon çerçevesi olan Di-Ninja'nın dokümantasyonu, Kompozisyon Kökü ve Bağımlılık Enjeksiyonu Prensiplerinin nasıl çalıştığını göstermek için çok iyi bir örnektir https://github.com/di-ninja/di-ninja Bildiğim gibi, javascript'te Kompozisyon-Kök tasarım desenini uygulayan tek DiC'dir.

1
Jo Takion

Christoffer Noring'den Pablo Deeleman'ın “Açısal Öğrenme - İkinci Basım” adlı kitabı:

"Uygulamalarımız büyüdükçe ve geliştikçe, kod varlıklarımızın her biri dahili olarak, yazılım mühendisliği dünyasında bağımlılıklar olarak daha iyi bilinen diğer nesnelerin örneklerini gerektirecektir. Bu bağımlılıkları bağımlı müşteriye geçirme eylemi enjeksiyon olarak bilinir, ve aynı zamanda enjektör olarak adlandırılan başka bir kod kuruluşunun katılımını gerektirir, enjektör gerekli bağımlılıkların somutlaştırılması ve önyüklenmesi sorumluluğunu üstlenir, böylece müşteriye başarıyla enjekte edildikleri andan itibaren kullanıma hazır hale gelirler. müşteri kendi bağımlılıklarını nasıl gerçekleştirebileceği hakkında hiçbir şey bilmiyor ve sadece bunları kullanmak için uyguladıkları arayüzün farkında. ”

1
H S Progr

Bağımlılık Enjeksiyonu, Altyapı inşaatına dayanan "Denetimin Tersine Dönme" ilkesinin bir türüdür.

GoF'un "Tasarım Deseni" nde belirtildiği gibi Frameworks, geliştiriciyi bunu yapan ana kontrol akış mantığını uygulayan sınıflardır, bu şekilde, Frameworks kontrol ilkesinin ters çevrilmesini gerçekleştirir.

Bir teknik olarak ve sınıf hiyerarşisi olarak değil, bu IoC ilkesini uygulamanın bir yolu, sadece Bağımlılık Enjeksiyonu.

DI, temel olarak sınıf örneklerinin eşlenmesini ve bu örneklere referans türünün harici bir "varlık" olarak temsil edilmesini içerir: bir nesne, statik sınıf, bileşen, çerçeve vb. 

Sınıf örnekleri "bağımlılık" dır, çağıran bileşenin referans yoluyla sınıf örneği ile dış bağlanması "enjeksiyon" dır.

Açıkçası, bu tekniği OOP bakış açısından istediğiniz kadar uygulayabilirsiniz, bakınız örneğin inşaatçı enjeksiyon, ayarlayıcı enjeksiyon, arayüz enjeksiyon.

Bir nesneye bir ref ile eşleştirme görevini yerine getirmek üzere üçüncü bir şahsı devretmek, aynı hizmetleri uygulamasından bazı hizmetleri gerektiren bir bileşeni tamamen ayırmak istediğinizde çok kullanışlıdır. 

Bu şekilde, bileşenleri tasarlarken, yalnızca kendi mimarisi ve özel mantığına odaklanarak, kullandığınız nesnelerin/hizmetlerin herhangi bir uygulama değişikliği konusunda endişelenmeden, diğer nesnelerle işbirliği yapmak için arayüzlere güvenebilirsiniz; tamamen değiştirilecektir (açıkça arayüze saygı göstererek).

1
Ciro Corvino

Önemsiz olmayan herhangi bir uygulama, bazı iş mantıklarını gerçekleştirmek için birbirleriyle işbirliği yapan iki veya daha fazla sınıftan oluşur. Geleneksel olarak, her nesne, birlikte çalıştığı nesnelere (bağımlılıkları) kendi referanslarını almaktan sorumludur. DI uygulandığında, nesnelere yaratılış sırasında bağımlılıklarını sistemdeki her bir nesneyi koordine eden bazı harici varlık tarafından verilir. Başka bir deyişle, bağımlılıklar nesnelere enjekte edilir.

Daha fazla ayrıntı için lütfen bkz. buraya link tanımını girin

0
Hisham Javed

DI, bir nesnenin başka bir nesnenin varlığından sorumlu olmadan, gerçek nesnelerin gerçekte birbirleriyle nasıl etkileşimde bulunduklarıdır. Nesneler eşit olarak ele alınmalıdır. Hepsi nesnelerdir. Kimse yaratıcı gibi davranmamalı. Nesnelerine adaleti böyle yaparsın.

Basit örnek

bir doktora ihtiyacınız olursa, basitçe gidip (mevcut) bir tanesini bulun. Size yardımcı olmak için sıfırdan bir doktor yaratmayı düşünmeyeceksiniz. O zaten var ve sana veya başka nesnelere hizmet edebilir. Amacınız bir veya daha fazla nesneye hizmet etmek olduğu için (tek bir nesnenin) ona ihtiyaç duyup duymadığına bakma hakkı vardır. Varlığına karar veren kişi, doğal seleksiyon değil, Yüce Allah'tır. Bu nedenle, DI'nin bir avantajı, evreninizin ömrü boyunca bir amaç olmadan yaşayan gereksiz gereksiz nesneleri oluşturmaktan kaçınmaktır (yani uygulama).

0
Shadi Namrouti