Search code examples
c#dependency-injectionninject

Using NInject, resolving IEnumerable<T> fails when injecting a a ctor arg, but not when doing Get<IEnumerable<T>>()


When using NInject if I set up a binding for IEnumerable<T>, it will work if I directly request an IEnumerable<T>, but not if another bound object requires an IEnumerable<T>. Is this by design?

class Program 
{
    static void Main(string[] args)
    {
        var k = new StandardKernel();
        k.Bind<IEnumerable<int>>().ToMethod(GetInts);
        k.Bind<IFoo>().To<Foo>();   // Has an IEnumerable<int> constructor arg
        var works = k.Get<IEnumerable<int>>();   // returns the array of ints
        var tst = k.Get<IFoo>();  // Empty integer array is passed in by ninject???
        tst.Get();   // returns an empty integer array?
        return;
    }

    public static int[] GetInts(IContext ctx)
    {
        return new int[] { 1, 2, 3, 4, 5 };
    }
}

public interface IFoo
{
    IEnumerable<int> Get();
}

public class Foo : IFoo
{
    private int[] _vals;

    public Foo(IEnumerable<int> vals)
    {
        _vals = vals.ToArray();
    }

    public IEnumerable<int> Get()
    {
        return _vals;
    }
}

Solution

  • You're seeing Multi Injection happening.

    You could override it by adding an explicit Get to your binding:

    k.Bind<IFoo>().To<Foo>()
        .WithConstructorArgument( "vals", ctx=>ctx.Kernel.Get<IEnumerable<int>>());
    

    (Though if you look at the source, I'm sure you'll find a way to inhibit Multi Injection.)