Bağımlılık enjeksiyonu dile nasıl entegre edilebilir? [kapalı]


10

Biraz bağımlılık enjeksiyonunun doğrudan C # diline nasıl daha iyi entegre edilebileceğini düşünüyordum. Fikrinizi duymak istediğim potansiyel bir çözüm buldum. Çok fazla bağımlılık enjeksiyon çerçevesi kullanmadım, bu yüzden göz ardı ettiğim bir şey olabilir

Her neyse, fikir bir anahtar kelime kullanarak özellikleri "enjekte edilebilir" olarak ilan edebilmektir. Bir nesne başlatıldığında ve bu özellik yapıcı veya nesne başlatıcı aracılığıyla başlatılmadığında, bazı global hizmetlerden bu özellik türünün bir örneğini ister.

Benzer şekilde, enjekte edilen özellik türünü başlatabilmeniz için bu hizmete farklı türler için işleyiciler kaydedersiniz.

Bu tür IMO mimarisini kullanmanın tersi, oldukça esnek ve kullanımı kolay olmasıdır. Dezavantajı, enjeksiyonlu bir sınıfı her başlattığınızda singletona ek bilgi yapmanın bazı yükleri olabilir.

Daha sonra bu sadece yüksek performanslı bir çözümde sık sık başlatılan sınıflar için bir konudur, bu yüzden çok fazla sorun olmamalıdır. Belki de bu gibi durumlarda bir çeşit fabrika kullanabilirsiniz.

Düşünce, sorunlar, sorular, daha iyi fikirler?

kod

public class SomeClass
{

  public SomeClass()
  {
     //implicit behavior if Animal is not set in constructor or initializer
    this.Animal =  GlobalInjector.Get(this,typeof(Mammal))

  }

  public injectable Mammal Animal  
  {
   get;
   set;
  }
}


 GlobalInjector.Register(typeof(Mammal), () => return new Mammal(someParameter));

DI'ye aşina olmayanlarımız için sahte bir kod örneği verebilir misiniz? PS. Belki DI ile ilgili soruma da cevap verebilirsin? :)
Steven

2
Anladığımdan emin değilim. Bunların hepsini bir global DI kapsayıcısı ve bir anahtar kelime yerine '[Enjekte edilebilir]' özelliğiyle alabilirsiniz, değil mi?
nikie

Merhaba,
Sorunuzla

nikie: Evet, sanırım gerçek mekanizmayı farklı şekillerde uygulayabilirsin, altta yatan mantık
sağlamsa

Peki, bu ve mevcut IoC arasında ekstra anahtar kelimeniz dışında ne fark var?
Matthew

Yanıtlar:


7

Dile ait şeyler ve olmayan şeyler vardır. Uzun zaman önce C, bilgisayar modelinin dışında olduğu ve fonksiyon kütüphaneleriyle uygulanabildiği için IO'nun dile ait olmadığını fark etti.

Bağımlılık Enjeksiyonu böyle. Dilin dışındadır ve uygun çerçevelerle uygulanabilir.

Modern dillerle ilgili sorunlardan biri, çok fazla şey yapmaya çalışmalarıdır. Sonunda, programcılar daha basit dillere kaçarken bu diller kendi ağırlıkları altında çöküyor.


Teoriye katılıyorum, her fonksiyonun şişirilmeden dilin bir özelliği olduğu bir dile sahip olamazsınız. Bununla birlikte, her zaman daha iyi kod yazmamıza yardımcı olan yeni yüksek soyutlamalara yer vardır. Belki de bağımlılık enjeksiyonu kendi başına çözülmesi gereken bir sorun değil, ele aldığı sorun yani bağımlılıkları azaltmamızı kolaylaştırmanın bir yoludur. Bu olsa yapmak için en iyi yolu olmayabilir :)
Homde

5

Gerekli değil

Kullandığım en iyi DI çerçeveleri hakkında en sevdiğim şeylerden biri, üst düzey yapılandırma kodunun DI hakkında bilmeniz gereken kodunuzun tek kısmı olmasıdır. Otomatik kablolama, konteyner ve yapılandırma / "modül yükleme" düzeyinde yapılır ve uygulama kodunuz bundan tamamen habersiz olabilir.

Bu, nitelikler, sihirli dizeler, konvansiyon yok demektir. Her kod parçası yalnızca yapıcısında kodu kabul ettiğini bilir (/ properties / method) ve hepsi bu.

Böyle bir tasarımla Bağımlılık Enjeksiyonunu desteklemek için dili değiştirmeniz gerekmez.

Potansiyel olarak tehlikeli

Bir dile entegre bağımlılık enjeksiyon sistemi hakkında en çok korktuğum şey, diğer herhangi bir uygulamaya karşı bir engel oluşturacağı, ancak muhtemelen bir yönüyle kendini köşeye boyayacağıdır.

Kendini bir köşeye boyayabileceği bazı yollar:

  • Yalnızca XML tabanlı yapılandırmayı veya yalnızca kod tabanlı yapılandırmayı destekler
  • Fabrika tasarım desenini temiz bir şekilde destekleyememe (yalnızca geçici bileşenler değil: çalışma zamanı tarafından oluşturulan bileşenler)
  • Bir şekilde kodumu değiştirerek bağımlılık enjeksiyonunu kullanmak zorunda kaldım ve sadece birim testleri için sınıfımı başlatamadım
  • Özel yaşam döngülerini desteklemiyor
  • Genişletilemezlik
  • Daha fazla özelleştirmeye ihtiyaç duyduğum durumlarda değiştirilemez
  • Henüz anlamadığımız bir şekilde kırılmak, çünkü biz .Net kullanıcıları DI tuzaklarını bilecek kadar uzun süre kullanmıyorlar

4

.NET 4 ile birlikte gelen Yönetilebilir Genişletilebilirlik Çerçevesi'ni gördünüz mü ? İşte bazı örneklerle yazdığım bir makale . Temel olarak, çalışma zamanı keşfedilebilirliğinin ek özellikleri ile .NET'e yerleşik bir bağımlılık enjeksiyonudur.

Mülkiyet enjeksiyonları şöyle görünür:

class Program
{
    [Import]
    public IMessageSender MessageSender { get; set; }
}

Yapıcı enjeksiyonları şöyle görünür:

class Program
{
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    ...
    }
}

Meta verileri kullanarak tembel içe aktarma da dahil olmak üzere alanları içe aktarabilir, isteğe bağlı içe aktarma, hizmet koleksiyonlarını içe aktarabilirsiniz, böylece örneklemek için uygun bir hizmeti arayabilirsiniz. Hatta yeni uzantıları aramak için çalışma zamanında yeniden içe aktarabilirsiniz.


MEF eklenti şeyler için gerçekten havalı olsa da, genel bir DI mekanizması olarak kullanmak istediğimi düşünmüyorum
Homde

1
@MKO - Neyin eksik olduğunu açıklayabilir misiniz? Glenn Block'un insanlara MEF'in tüm DI çerçevelerinin yerine geçmediğine dair güvence vermek için yarıştığı tüm makalelerin farkındayım , ancak ayrıntılara bakarsanız, bunun her şeyden çok siyasi bir ifade olduğu açıktır. Bununla birlikte, MEF'in diğer DI çerçevelerine kıyasla eksik olduğu özelliklerin iyi bir listesini verebilirseniz, insanların bilinçli bir karar vermelerine yardımcı olur. Ayrıca, soru C # DI çerçeveleri hakkında ve MEF açıkça .NET framework bir DI kapsayıcısı.
Scott Whitlock

2
  1. IMHO'nun zor olduğu yapılandırma mekanizmasını gerçekten tanımlamıyorsunuz. Bir iş parçacığında çalışan tüm kodların DB-connection A ve diğer iş parçacığı B bağlantılarındaki tüm kodları nasıl kullanmasını sağlarsınız? Şu anda oturum açmış olan kullanıcının erişmesine izin verilmediğinden, belirli bir kaynağın enjeksiyonunu nasıl engellersiniz?
  2. Küresel bir enjektör kullanmayın. Hiç küresel bir şey kullanmayın ya da global değişkenleri de kullanabilirsiniz. Hayır, global yerine singleton veya "static" gibi OOP-konuşma kullanmak küresel niteliklerini değiştirmez.
  3. Dinamik olarak kapsamlı bir kapsayıcı düşünün. Sözcüksel kapsam belirleme, dinamik kapsamlamaya karşı haklı olarak kazanmış olsa da, dinamik kapsamın küresel kapsamın yerine geçeceğine inanıyorum. Diferansiyel kalıtım güzel bir uygulama olacaktır (prototip tabanlı kalıtım gibi).
  4. Ben bir dil zorunlu DI-mekanizması gerçekten basit olması gerektiğine inanıyorum, hiçbiri C # ve Java norm olan bu kurumsal şeyler. Basit yapılandırma katmanı üstte olan dinamik bir kapsam belirleme mekanizması hile yapabilir. Girişimci çözümler üçüncü şahıslar tarafından üst sıralara yerleştirilebilir.
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.