如何使用Ninject支持动态多注入,其中可能没有绑定项目

时间:2016-09-21 07:38:24

标签: ninject

在以下单元测试中,TestDirectRetrieval_WithNoImplementationsTestInjection_WithNoImplementations失败

[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 个答案:

答案 0 :(得分:1)

ninject不使用

GetAll进行注射,但是当你发现它提供了所需的行为时。要使用0-n语义启用注入,我通常会使用自己的“集合”,不完整/伪代码版本如下所示:

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>创建一个接口并将其绑定可能是有意义的。