Bağımlılık enjeksiyon stilleri arasındaki pratik fark nedir?


12

Bağımlılık enjeksiyonunda yeniyim ve uygulamalarımda hangi stili kullanmam gerektiği hakkında birkaç sorum var. Martin Fowler'ın Kontrol Kapsayıcılarının İnversiyonu ve Bağımlılık Enjeksiyon kalıbını yeni okudum , ancak yapıcı, ayarlayıcı ve arayüz enjeksiyonu arasındaki pratik farkı alamıyorum.

Bana öyle geliyor ki birini diğerinin üzerinde kullanma nedenleri sadece kod temizleme ve / veya netlik meselesi. Fark ne? Birini diğerinin üzerinde kullanmanın güçlü avantajları veya dezavantajları var mı, yoksa daha önce belirttiğim gibi mi?

Benim düşünceme göre, yapıcı enjeksiyonu en sezgisel ve arayüz enjeksiyonu en azdır. Öte yandan, ayarlayıcı enjeksiyonu orta vadeli bir terimdir, ancak başlangıçta enjekte ettiğiniz bağımlılık nesnesinin örneğini değiştirebilmeniz gerekiyor mu? Bu enjeksiyon tarzı, bağımlılığa ihtiyaç duyan nesneye her zaman enjekte edilmesini garanti ediyor mu? İnanmıyorum ama yanılıyorsam lütfen beni düzeltin.


Yol boyunca başka neler bulduğunuzdan veya okuduğunuzdan emin değilim. Burada ve burada benzer iplikler buldum . Ben kendim yeniyim ve alabileceğiniz cevapları merak ediyorum :)

@ user1766760 Bana o zaman burada yardım etmelisin, sorum kapatılacak oy, iki oy daha ve bitti !!! Soruyu oylayın ya da bir şey, kapanmayı önlemek için neler yapılabileceğini bilmiyorum.
ecampver

erm ... SO kendim için yeniyim, bu yüzden nasıl yardımcı olabileceğimden / neden kapatılmak için seçildiğinden emin değilim (herhangi bir gösterge görmüyorum ??). Bir tahminde bulunursam, belki de bu belirli bir programlama sorusu değil, daha fazla tartışmadır?

Soruyu biraz genişletmek isteyebilirsiniz. Bağımlılık enjeksiyonu, "Kontrolün İnversiyonu" nun bir biçimidir. Alternatifler var. Yararlı ancak istismar için uygun bir alternatif, örneğin Hizmet Konumudur.
Ian

Yanıtlar:


12

Yapıcı Enjeksiyonu , bağımlılığı açık hale getirme ve istemciyi bir örnek vermeye zorlama avantajına sahiptir. Ayrıca, istemcinin örneği daha sonra değiştiremeyeceğini de garanti edebilir. Bir (olası) dezavantaj, kurucunuza bir parametre eklemeniz gerektiğidir.

Setter Injection , yapıcıya bir parametre eklenmesini gerektirmemesi avantajına sahiptir. Ayrıca istemcinin örneği ayarlamasını da gerektirmez. Bu isteğe bağlı bağımlılıklar için kullanışlıdır. Bu, sınıfın örneğin varsayılan olarak gerçek bir veri havuzu oluşturmasını istiyorsanız da yararlı olabilir ve daha sonra bir testte ayarlayıcıyı test örneğiyle değiştirmek için kullanabilirsiniz.

Arayüz Enjeksiyonu , anlayabildiğim kadarıyla, ayarlayıcı enjeksiyonundan çok farklı değil. Her iki durumda da (isteğe bağlı olarak) daha sonra değiştirilebilecek bir bağımlılık ayarlarsınız.

Sonuçta bu bir tercih meselesi ve bağımlılığın gerekli olup olmadığıdır . Şahsen, neredeyse tamamen yapıcı enjeksiyon kullanıyorum. İstemciyi yapıcıda bir örnek sağlamaya zorlayarak bir sınıfın bağımlılıklarını açık hale getirir. Ben de müşteri gerçeği sonra örneği değiştiremezsiniz gibi.

Çoğu zaman, iki ayrı uygulamaya geçmemin tek nedeni test etmektir. Üretimde, ben geçebilirim DataRepository, ama testte, ben bir FakeDataRepository. Bu durumda genellikle iki kurucu sağlayacağım: biri parametresiz, diğeri ise a IDataRepository. Sonra, parametresiz kurucuda, ikinci kurucuya bir çağrıyı zincirleyeceğim ve a new DataRepository().

İşte C # 'da bir örnek:


public class Foo
{
  private readonly IDataRepository dataRepository;

  public Foo() : this(new DataRepository())
  {
  }

  public Foo(IDataRespository dataRepository)
  {
    this.dataRepository = dataRepository;
  }
}

Buna Zavallı Adamın Bağımlılık Enjeksiyonu denir. Seviyorum çünkü üretim istemcisi kodunda, kendime benzeyen birkaç tekrarlanan ifade alarak kendimi tekrar etmeme gerek yok

var foo = new Foo(new DataRepository());
Ancak, yine de test için alternatif bir uygulama geçirebilirim. Poor Man's DI ile bağımlılığımı zor kodladığımı fark ettim, ancak test için çoğunlukla DI kullandığım için bu benim için kabul edilebilir.


teşekkürler, bu oldukça yakın anlıyorum ne var, ama yine de, herhangi bir senaryo vardır olamaz kullanmak yapıcı enjeksiyon ?
ecampver

1
Muhtemelen isteğe bağlı bağımlılıklar için yapıcı enjeksiyonu kullanmak istemezsiniz. Kullanmamak için başka sebepler düşünemiyorum.
Mart'ta 17:13

Özellikle çok sayıda değer içeren bazı yapılandırma sınıflarını doldurmak için özellik ayarlayıcı enjeksiyonunu kullanıyorum. Başka bir yerde kullanmıyorum. Her zaman isteğe bağlı parametreler için bir dava açma konusunda biraz şüpheliyim çünkü tek sorumluluk kuralının ihlali için iyi bir şans var. Tabii ki kurallar çiğnenmeli, yani ...
Ian

@jhewlett - Bu harika, birim testi için çözümümü zorlaştırmayan iyi bir basit stubbing tekniği arıyordum - ve sanırım bu :)
Rocklan

2

Yapıcı ve setter enjeksiyonu arasındaki farklar yukarıda yeterince açıklanmıştır, bu yüzden bunlar üzerinde daha fazla ayrıntıya girmeyeceğim.

Arayüz enjeksiyonu, daha gelişmiş bir enjeksiyon şeklidir, çünkü bağımlılık, onu kullanacak nesnenin başlatılması sırasında kullanılma anında kararlaştırılmasına izin verir. Bu, bir dizi kullanışlı seçeneğe izin verir:

  • Bağımlılık, enjekte edildiği nesneye göre farklı bir kapsamda olabilir; örneğin, kullanıcı oturumu başına veya iş parçacığı başına bir global singletona bir nesne sağlamak için arabirim enjeksiyonu kullanabilirsiniz. Nesnenin bağımlılığa her ihtiyacı olduğunda, çerçeve tarafından sağlanan getter yöntemini çağırır ve bu, çağrıldığı duruma bağlı olarak farklı sonuçlar döndürebilir.

  • Tembel başlatmaya izin verir - bağımlılık kullanılacak olana kadar başlatılmasına gerek yoktur

  • Bağımlılıkların var olduklarında önbelleğe alınmış bir kopyadan yüklenmesine veya bulunmadığında yeniden başlatılmasına izin verir (örneğin SoftReference, Java'da bir kullanarak ).

Açıkçası bunun gibi ileri tekniklerin dezavantajları vardır; bu durumda, asıl sorun kodun daha az netleşmesi (kodunuzda kullanılan sınıfların soyut hale gelmesi ve bunların kullanılmadığı takdirde kafa karıştırıcı olabilecek belirgin bir somut uygulaması olmaması ve daha bağımlı hale gelmeniz) bağımlılık enjeksiyon çerçevenizde ( elbette nesnelerinizi manuel olarak başlatmak hala mümkündür , ancak diğer enjeksiyon stillerinden daha zordur).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.