2012-01-17 6 views
9

Normalde bir veya daha fazla hizmeti başka bir servise enjekte etmem gerektiğinde, her birini açıkça enjekte ederim. Bununla birlikte, servis kabının enjekte edilmesinin gerçekten işleri kolaylaştıracağı bir durum var. Bunun önerilen bir uygulama olmadığını biliyorum, ancak teknik nedenlerin bunu engellemek için ne olduğunu merak ediyorum. Çok yoğun bir kaynak gibi meşru bir şey mi yoksa çok dağınık olduğu için daha kişisel bir duygu mu?Hizmet konteynerini bireysel servisler yerine enjekte etmekten kaçınmanın teknik nedenleri nelerdir?

cevap

13

Konteynırı enjekte ederseniz, bağımlılıkları netleştirmezsiniz. Aslında, onları eskisinden daha fazla engellediniz. Böyle bir sınıfınız varsa, bağımlılıkların neler olduğunu görebilirsiniz. Ayrıca, DocumentCreator'ı ayırdığınızdan ve herhangi bir sınama başarısızlığının kodlarının bir bağımlılık özelliklerinden biri yerine kodun bir sonucu olduğunu bildiğinden emin olmak için, birim sınamaları için bu bağımlılıkları kolayca atabilirsiniz.

Öte yandan, bunu, varsa

...

class DocumentCreator(IDependencyContainer container) 
{ ... } 

... Eğer bağımlılıkları gizlenmiş ettik. Sınıfın iç yapısını incelemeden, bir IFileNamer ve bir İpitorum gerektirdiğini bilemezsiniz.

Ayrıca, DocumentCreator'ı test etmek için kapsayıcıya hangi alayların yerleştirmeniz gerektiğini kolayca öğrenemezsiniz. IDependencyContainer alay etmek size hiç yardımcı olmaz; Sınıfınızın test edilmesinde hala başarısız olmanız gerekir, çünkü sınıfın iç kısımlarını gerekli olduklarını görmek için incelemezseniz, kapsayıcı bir IFileNamer ve bir İpileyici içermeyecektir.

4

Bu yaklaşımdaki en temel sorun bağımlılıkları açıkça görmemenizdir. Başka bir problem, test etmek daha zor olabilir.

+0

İlk kısımda kesinlikle katılıyorum ve bu yüzden nadir durumlar haricinde özel hizmetler vermeye devam ediyorum. Ama test etmenin nasıl daha zor olacağından emin değilim? –

+1

Bu, kapsayıcı nesnesini oluşturmayı ve bunlara doğrudan enjekte etmek yerine alaylı (veya alay edilmemiş) hizmetleri enjekte etmeyi ima eder, bu da bir adım daha yapar. – greg0ire

+0

Hmm, bu kesinlikle büyük bir dezavantaj. –

3

Tanımladığınız şey bir ServiceLocator. Bu modern uygulama tasarımında bir anti-desen olarak kabul edilir. This article nedenini açıklıyor.

+0

Yanlış. İnsanların gerçekten o adamın bloğuna bağlanmayı bırakması gerekiyor. İşte daha yetenekli bir usta ustasından gelen fikir. http://www.martinfowler.com/articles/injection.html – Colin

+1

@Colin Mark Seemann'ın ServiceLocator'a bir anti-pattern bildirme gerekçesini hiç okudunuz mu? Tam bağımlılık enjeksiyonunun avantajlarından sadece birkaçı kazanırsınız, ancak faydaların bir kısmını (yani bağımlılıkların anında görünürlüğünü) özlersiniz. SL eklenmesi, kapsülleme gibi yazılım tasarımının çeşitli kurallarını ihlal ediyor http://blog.ploeh.dk/2015/10/26/service-locator-violates-encapsulation/ veya SOLID http://blog.ploeh.dk/2014/05/15/service-locator-violates-solid/ –

+0

Evet, ve bu saçmalık. Aslında argümanının tersi doğrudur. Örneğin, "kapsülleme ganimeti" der, ama kapsülleme noktasının tamamı, arayanın ilgilenmemesi gereken sınıfın iç detaylarını (örneğin, örnekleminde dışa vurduğu doğrulama gibi) gizlemektir. DI'nin açık uygulamaları ve faydaları vardır, ancak "altın çekiç" değildir; Bu bir anti-desen. TraceListeners içinde Trace.WriteLine() veya Debug.WriteLine() her çağırdığınızda geçirmeniz gerektiğini düşünün! Keşke insanlar, Bay Seeman'a bir uzman gibi davranmayı bırakacaklardı. o sadece bir düşünen blogcu. – Colin

İlgili konular