2011-07-01 39 views
19

Özellikleri etkinleştiren/devre dışı bırakan global bayraklara sahibim. Bazı bayraklara bağlı olarak bazı bağımlılıklar enjekte etmek istiyorum. Bazı özellikler yoğun olarak oluşturulmuş sınıflar gerektirir, bu yüzden bayrağın değeri yanlışsa ve aksi takdirde gerçek bağımlılık varsa null enjekte etmek istiyorum. Ninject, enjekte edilmesine izin vermiyor. Başka seçenek var mı?Ninj. İsteğe Bağlı Enjeksiyon

Güncelleme: Kurucu argümanları OptionalAttribute özniteliği ile dekore edilebilir. Bu durumda, karşılık gelen bir bağlanma bulunmadığında boş değer enjekte edilir. Burada bir sorun var: Hedef sınıfın düzgün bir şekilde oluşturulabileceğini doğrulayamıyorum. Başarılı bir şekilde oluşturulabileceğini doğrulayan her bir kamu bağımlılığı için bir test yapıyorum. Bayrağın değerinin doğru olması durumunda, OptionalAttribute özniteliği ile ilişkilendirilen bağımlılık düzgün bir şekilde yapılamadığında bu hatayı bulamaz. Bunu yalnızca bağlayıcı düzeyde yönetmek istiyorum.

cevap

17

bir fabrika yöntemini (yani ToMethod) kullanılarak bağlanarak enjeksiyon davranışı değişebilir ve bu kapsayıcının AllowNullInjection ayar yapılandırarak null enjeksiyonuna izin mümkündür.

Başka bir alternatif, bir fabrika yöntemini kullanmak ve ağır sınıfınız yerine hafif bir kukla nesne sağlamak olabilir. Arayüzler kullanıyorsanız, bu basit olurdu, sadece hiçbir şey yapmadan arayüzün uygulamaları var. Bu mankenleri sizin için inşa etmek için FakeItEasy gibi alaycı bir çerçeve bile kullanabilirsiniz.

public void Configure() 
{ 
    bool create = true; 

    IKernel kernel = new StandardKernel(); 

    kernel.Settings.AllowNullInjection = true; 

    kernel.Bind<IFoo>().ToMethod(ctx => create ? ctx.Kernel.Get<Foo>() : null); 

    DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>(); 
} 

private interface IFoo {} 

private class Foo : IFoo {} 

private class DependendsOnIFoo 
{ 
    public DependendsOnIFoo(IFoo foo) {} 
} 
: Burada fayda, kukla istemcileri null kontrol etmek gerekmez yani müşterilerine şeffaf özel davranış vb

fabrika yöntemini kullanarak bir örnek, artı AllowNullInjection ve boş değerlere sağlamasıdır

ve hafif bir nesne işaretine bağlı olarak ikame edilen bir örnek:

public void Configure() 
{ 
    bool heavy = true; 

    IKernel kernel = new StandardKernel(); 

    kernel.Bind<IFoo>() 
    .ToMethod(ctx => heavy ? ctx.Kernel.Get<HeavyFoo>() : (IFoo)new DummyFoo()); 

    DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>(); 
} 

private interface IFoo {} 

private class HeavyFoo : IFoo {} 

private class DummyFoo : IFoo { } 

private class DependendsOnIFoo 
{ 
    public DependendsOnIFoo(IFoo foo) {} 
} 
12

null adlı enjekte genellikle bir fikir değildir.

public interface IFoo 
{ 
    void Do(); 
} 

public class Foo : IFoo 
{ 
    public void Do() 
    { 
     DoSomething(); 
    } 
} 

public class UglyNullCheckingBar 
{ 
    IFoo foo; 
    public Bar(IFoo foo) 
    { 
     this.foo = foo; 
    } 

    public void Do() 
    { 
     if (this.foo != null) 
     { 
      this.foo.Do(); 
     } 
    } 
} 

bu durumda daha iyi bir yol kesinlikle hiçbir şey yapmaz bir null Nesne uygulamak ve yerine bu bir enjekte etmektir: Aşağıdaki kodu tarafından gösterildiği gibi nesne null veya değilse bu çeklerle kodunuzu kirletir boş. Bu kodunuzu temiz tutar.

public class NullFoo : IFoo 
{ 
    public void Do() {} 
} 

public class Bar 
{ 
    IFoo foo; 
    public Bar(IFoo foo) 
    { 
     this.foo = foo; 
    } 

    public void Do() 
    { 
     this.foo.Do(); 
    } 
}