2016-09-21 35 views
0

在下面的單元測試,TestDirectRetrieval_WithNoImplementationsTestInjection_WithNoImplementations失敗如何支持動態multiinjection與Ninject,那裏可能沒有項目勢必

[TestFixture] 
public class KernelTests 
{ 
    [Test] //Passes 
    public void TestDirectRetrieval_WithMultipleImplementations() 
    { 
     //Arrange 
     var kernel = new StandardKernel(); 
     kernel.Bind<Foo>().ToConstant(new Foo("a")); 
     kernel.Bind<Foo>().ToConstant(new Foo("b")); 
     //Act + Assert 
     Assert.DoesNotThrow(() => kernel.GetAll<Foo>().ToList()); 
    } 

    [Test] //Passes 
    public void TestInjection_WithMultipleImplementations() 
    { 
     //Arrange 
     var kernel = new StandardKernel(); 
     kernel.Bind<Foo>().ToConstant(new Foo("a")); 
     kernel.Bind<Foo>().ToConstant(new Foo("b")); 
     //Act + Assert 
     Assert.DoesNotThrow(() => kernel.Get<Bar>()); 
    } 

    [Test] //Fails 
    public void TestDirectRetrieval_WithNoImplementations() 
    { 
     //Arrange 
     var kernel = new StandardKernel(); 
     //Act + Assert 
     Assert.DoesNotThrow(() => kernel.GetAll<Foo>().ToList()); 
    } 

    [Test] //Fails 
    public void TestInjection_WithNoImplementations() 
    { 
     //Arrange 
     var kernel = new StandardKernel(); 
     //Act + Assert 
     Assert.DoesNotThrow(() => kernel.Get<Bar>()); 
    } 

    #region Test helper classes 

    class Foo 
    { 
     public Foo(string someArgThatCantBeAutomaticallyResolvedByNinject){} 
    } 

    class Bar 
    { 
     private List<Foo> myFoos; 

     public Bar(IEnumerable<Foo> foos) 
     { 
      myFoos = foos.ToList(); 
     } 
    } 
    #endregion 
} 

在一個場景中的人是基於一些結合東西常數/實現動態的情況下,他們怎麼能支持這個案子一無是處?

回答

1

GetAll ninject不用於注射,但正如你發現它提供了所需的行爲。爲了使注射0-n的語義我經常推出自己的「收藏」,一個uncomplete /僞代碼版本是這樣的:

class OptionalItems<T> : IEnumerable<T> 
{ 
    private readonly T[] items; 

    public OptionalItems(IResolutionRoot resolutionRoot) 
    { 
     this.items = resolutionRoot.TryGetAll(T).ToArray(); 
    } 

    public IEnumerator<T> GetEnumerator() { 
     return this.items.GetEnumerator(); 
    } 
} 

現在注入OptionalItems,而不是IEnumerable<T>IList<T>。 由於可測試性原因,爲OptionalItemspublic interface IOperationalItems<T> : IEnumerable<T>創建一個接口並將其綁定可能是有意義的。

+0

您是否一般只是將一個'IOptionalItems' /'OptionalItems'與一個開放的泛型參數綁定在一起,還是爲每個可選類型綁定一個? – Landerah

+0

而且我注意到這有解決IEnumerable時解決的效果。這與注入IEnumerable時的行爲有什麼不同?我發現[這](https://github.com/ninject/ninject/issues/128)(也許你的要求?),但它似乎沒有實施。 (顯然懶惰是不完全相同的,因爲它只是'一次'的分辨率) – Landerah

+0

我通常將它與一個開放的泛型綁定在一起。如果您需要針對特定​​類型的特定範圍('InSingletonScope()','InRequestScope()'),則可能還必須創建特定的綁定。我的問題#128是由我創建的。我們與曾在Ninject背後長期維護和推動力量的Remo-Gloor進行了討論,他自己也表示在ctor中* not *實現IEnumerable是危險的。所以我做這件事的方式是安全和推薦的方式。 – BatteryBackupUnit

相關問題