1

Lets say we have a class X like this:

class X
{
   X(Z a, Z b)
   { }
}

And the Z class would have a Y dependency:

class Z
{
   Z(Y c)
   { }
}

What's the proper way to bind these classes such that two instances of Z, each of them with a different instance of Y, get injected into X?

I know these have to do with Context Binding, but I'm not sure how to go about it.

EDIT:

The Y class would be:

class Y
{
    Y(string someString)
    { }
}

I want the two instances of Y with a different string as well.

Thanks

Jassel
  • 63
  • 7
  • I'm sorry to those who answered, I just edited it, but basically the example is the same. – Jassel Jan 28 '15 at 22:56
  • What you're trying to achieve is not supported in any special way by ninject. You can use a `ToMethod` or `IProvider` binding to put the logic of creating the `X` with it's specific `Z`s there. – BatteryBackupUnit Jan 29 '15 at 10:01

3 Answers3

1

You could used Named Bindings. Other types of contextual bindings can be found here.

Bind<X>().To<XA>().Named("A");
Bind<X>().To<XB>().Named("B");

public class Z {
    public Z([Named("A")] X x1, [Named("B")] X x2) {}
}
slvnperron
  • 1,323
  • 10
  • 13
  • You put it upside down, but anyhow my question is, how you tell the two instances of X to be injected also with different instances of Y – Jassel Jan 28 '15 at 22:58
  • And preferably without having to put the Named attribute in the Z constructor, if possible – Jassel Jan 28 '15 at 23:02
0

If your bindings for X and Y are not scoped, then each time an X object is requested from the kernel, it will get constructed with two unique Z objects (each having a unique instance of Y). This will happen by default.

Kingmaker
  • 35
  • 3
  • Yes you're right! but what if I want the two Y instances to recive a different string ? – Jassel Jan 29 '15 at 02:19
  • Will the constructor argument a (class Z) always receive the same string? Will the constructor argument b (class Z) always receive the same string? – Kingmaker Jan 29 '15 at 03:28
0

pass your dependencies that implement the same interface as an IEnumerable. Otherwise, Ninject will yell at you if you have multiple bindings for one interface. Use the .WithConstructorArgument() method to define your string. If the string is not constant, you can use .ToMethod() instead and have the string determined at runtime.

public class Z
{
    public Z(IEnumerable<Y> dependencies)
    {
        if (dependencies == null) throw new ArgumentNullException("dependencies");
        _dependencies = dependencies;
    }
}

static void Main() // or other entry point
{
    var kernel = new StandardKernel();
    kernel.Bind<Z>().To<ZImplementation>();
    kernel.Bind<Y>().To<YImplementation1>().WithConstructorArgument("c", "string to inject 1");
    kernel.Bind<Y>().To<YImplementation2>().WithConstructorArgument("c", "string to inject 2");
}
Scope Creep
  • 811
  • 7
  • 14