2010-04-19 11 views
5

Ninjects ConstructorArgument kullanıldığında, belirli parametrelere enjekte edilecek tam değeri belirtebilirsiniz. Neden bu değer null olamaz, ya da nasıl çalıştırabilirim? Belki Örnek .. Eğer yapmak istediğiniz bir şey değil, ama benim birim testlerinde kullanmak istiyorum: kurucu bağımsız değişkeni de değer türleri olamaz çünküNinjects ConstructorArgument ile null değerini niçin enjekte edemiyorum?

public class Ninja 
{ 
    private readonly IWeapon _weapon; 
    public Ninja(IWeapon weapon) 
    { 
     _weapon = weapon; 
    } 
} 

public void SomeFunction() 
{ 
    var kernel = new StandardKernel(); 
    var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", null)); 
} 
+0

Ninject ile aşina değilim, ama konu IoC-container uygun bir kurucu bulmak için tip bilgileri kullanır ve boş değer tarafından bulamıyor olduğunu düşünüyorum. Dokümantasyonda veya kodunda cevap aramak daha iyi olur. Karşılık gelen Type nesnesinin örneğini kullandığım bir kitaplıkta null yerine geçirilmesi gerekir. Burada da benzer bir çözüm olabilir. – SergGr

+0

Teşekkür ederim efendim :-) – stiank81

cevap

7

Değer Türünü geçirme veya boş olmayan bir Referans Türü) yapar.

geçici çözüm Nesne için null adlı dökme şudur: -

var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", (object)null)); 

Ninject 2 kaynak:

public class ConstructorArgument : Parameter 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="ConstructorArgument"/> class. 
    /// </summary> 
    /// <param name="name">The name of the argument to override.</param> 
    /// <param name="value">The value to inject into the property.</param> 
    public ConstructorArgument(string name, object value) : base(name, value, false) { } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="ConstructorArgument"/> class. 
    /// </summary> 
    /// <param name="name">The name of the argument to override.</param> 
    /// <param name="valueCallback">The callback to invoke to get the value that should be injected.</param> 
    public ConstructorArgument(string name, Func<IContext, object> valueCallback) : base(name, valueCallback, false) { } 
} 

Repro:

public class ReproAndResolution 
{ 
    public interface IWeapon 
    { 
    } 

    public class Ninja 
    { 
     private readonly IWeapon _weapon; 
     public Ninja(IWeapon weapon) 
     { 
      _weapon = weapon; 
     } 
    } 

    [Fact] 
    public void TestMethod() 
    { 
     var kernel = new StandardKernel(); 
     var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", (object)null)); 
    } 
} 

Ders? En son kaynağı indirmemeli ve ona bakmamalısın. Harika yorumlar, güzel temiz kod tabanı. Bu ipucu/prodding için @Ian Davis'e tekrar teşekkürler! Benim biriminde kullanmak istiyorum

+0

+1 Nice - ilginç şeyler. Açıklama için – Finglas

+0

Thx. Nesneleri boşuna çevirmek istediğimi düşünmüyorum ama bu soruya cevap veriyor! Belki de en son kaynağı kontrol etmeliyim :-) – stiank81

+0

@ stiank81: @Finglas'ın cevabı üzerine yorum yaptığım gibi (bunun kabul edilsem bile Kabul Edilebilir Bir: P olması gerektiğine inanıyorum), çirkin olmasının nedeni çünkü normal kullanımda yapılması amaçlanmamıştır (ConstructorArgument'i başka bir soruda hatalı bir varsayılan yaklaşım olarak görmedik mi?): P) @Finglas: Teşekkürler, ve diğer şeyleri çıkardığınız için teşekkürler –

0

Bu muhtemelen desteklenmiyor.

+0

Bu, gerçek cevabı yanlış bulduğu için bulmamı istedi. Ama aynı zamanda, Brian'ın cevabına katılmama konusunda da düşünmemi sağladı (Ben +0'ı ama diğerini geri almak için çok geç ayrılıyorum ve her ikisi de kavramsal anlayış sağlasa da, Ninject'in teşvik/önlemeye çalıştığı her şeyi temsil ettiğine inanmıyorum. kuvvet) –

3

Ninjeni bilmiyorum, ancak AFAIK yapıcı enjeksiyonu, zorunlu bağımlılıklar için yaygın olarak kullanılır ve bu nedenle null, bu bağlamda çok az anlam ifade etmez. Bağımlılık zorunlu değilse, türünde varsayılan bir kurucu bulunmalı ve bunun yerine özellik enjeksiyonu kullanılmalıdır. Ek bilgi sağlayan

This post.

(normal kullanım daha ConstructorArgument ctor farklı bir aşırı bağlanma örneğin, nereye çünkü Bu: kaynak (P ve atlanmış bir reproing göre var yığın izleme) bakıldığında

+0

I + 1d, çünkü Gerrie'nin cevabından daha mantıklı görünüyordu.Yansıma üzerinde Değer Türleri ve Referans Türleri için kullanılabileceğinden ve bu bağlamda gerçekten iyi bir noktaya dönüşmediği için gerçekten hemfikir değilim. Karşı korunmak istenen, belirsiz, rastgele başlatılmamış ve/veya bağımlılıkların açık bir şekilde belirtilmemiş araçların bağımlılık zincirlerini tanımlamanıza yardımcı olabileceği anlamına gelir. –

+0

Mülkiyet enjeksiyonu bunun için kabul edilebilir bir çözümdür? Eğer öyleyse bu mantıklı bir şey gibi geliyor. Bağlantı için Thx. – stiank81

+0

@ stiank81: Mülk enjeksiyonu elde etmeye çalıştığınız temel şeyi (çok sayıda "null" değeri) gerçekleştirirken, bunu yaparken Code Cleanliness'de çok fazla kaybedersiniz. @Finglas'ın cevabına başvur. –

3

no need to use an IOC container for unit tests yoktur test eder. Uygulamayı çalışma zamanında birbirine bağlamak için kabı kullanmalı ve başka bir şey yapmamalısınız. Bu zarar vermek başlar eğer, sınıfınızı belirten onun kokusu çığırından çıkıyor edilir

Kişisel birim test bu örnekte olurdu (SRP ihlali?):

var ninja = new Ninja(null); 

üzerindedir okunaklı C# kodu ve birim sınama için boş bir başvurunun geçirilmesi, bağımlılığa ihtiyaç duymayan birim test alanlarının mükemmel bir şekilde geçerli bir yoludur.

+0

+1 Yanıt vermese bile önemli bir nokta sorusu (bu durumun gerçektiren nedeni muhtemelen bu sorunun neden (null) durumunda yanlış yüklenmeye karar vermesi) bir sorun olarak görülmemiştir. –

+0

@Ruben: Sorun değil, bunun yanında İyileştirme ve öğrenme. – Finglas

İlgili konular