I apologize in advance if this is a dumb question: I am quite new to NInject.
I need to initialize my application with several collections, each having several identical objects. Without IoC, that would look like:
public ICollection<ICollection<IBusinessObject>> Piles = new ICollection<ICollection<IBusinessObject>>();
public MyCollectionContainer()
{
Piles.Add(new List<IBusinessObject>({ new ObjectA(), new ObjectA() });
Piles.Add(new List<IBusinessObject>({ new ObjectB(), new ObjectB() });
Piles.Add(new List<IBusinessObject>({ new ObjectC(), new ObjectC() });
}
I'd like to instruct NInject to do that job for me, so that a call to Kernel.Get<MyCollectionContainer>()
would do the same job as above, with some extra flexibility, of course.
In other words, I want, at bind time, to instruct NInject to
Kernel.Bind<ICollection<ICollection<IBusinessObject>>>().To< /* A list of 3 */>();
Kernel.Bind<IList<IBusinessObject>>().To< /* A List of 2 IBusinessObject */>();
Kernel.Bind<IBusinessObject>().To< /* a different type depending on the container */>();
Side question: Should I better use Kernel.Get<MyCollectionContainer>()
or Kernel.Get<ICollection<ICollection<IBusinessObject>>>()
EDIT: While searching for a solution, I tried to define a custom binding for my collections in the model of
Kernel.Bind<IList<IBusinessObject>>()
.ToConstructor(x => new List<IBusinessObject>(
x.Inject<IList<IBusinessObject>>())
);
With an extension method IConstructorArgumentSyntax.InjectMany(int i)
:
Kernel.Bind<IList<IBusinessObject>>().To<ObjectA>();
Kernel.Bind<IList<IBusinessObject>>()
.ToConstructor(x => new List<IBusinessObject>(
x.InjectMany<IList<IBusinessObject>>(2))
);
public static T InjectMany<T>(this IConstructorArgumentSyntax x, int numberOfInjections)
{
/* loop */
{
x.Inject<T>();
}
}
Sadly NInject refuses to call x.Inject(); complaining that I've dived too deep into their magic:
System.InvalidOperationException :
This method is for declaration that a parameter shall
be injected only! Never call it directly.