I\'m still a newbie at DI, and I am trying to understand if I am thinking of things the wrong way. I am working on a toy problem when I want to represent a Die object that has
You could use ConstructorArgument
together with Kernel.Get
in this particular situation.
Here is full sample.
public class ExampleKernel : NinjectModule
{
public override void Load()
{
Bind<IRandomProvider>()
.To<RandomProvider>();
Bind<Die>()
.ToSelf()
.WithConstructorArgument("numSides", 6);
// default value for numSides
}
}
var d6 = kernel.Get<Die>(); // default numSides value
var d20 = kernel.Get<Die>(new ConstructorArgument("numSides", 20)); // custom numSides
Assert.That(d6.NumSides == 6);
Assert.That(d20.NumSides == 20);
An inversion of control container is not a factory. Don't use it to resolve business objects like your Die
class. Inversion Of Control is pattern used to let the container take control over the lifetime of your objects. A bonus of that is that it also supports the dependency injection pattern.
Business objects is typically created, changed and disposed. Hence no need to use the container for them. And as you just noticed, they do take their mandatory parameters in the constructor which makes it hard to use the container for them.
You can register a DieFactory
in the container and let it take the IRandomProvider
in the constructor:
public class DieFactory
{
public DieFactory(IRandomProvider provider)
{}
public Die Create(int numberOfSides)
{
return new Die(numberOfSides, _provider);
}
}
But it would of course be better to create a factory used to create all related business objects. Then you can take the kernel as a dependency:
public class AGoodNameFactory
{
public DieFactory(IKernel kernel)
{}
public Die CreateDie(int numberOfSides)
{
var provider = _kernel.Resolve<IRandomProvider>();
return new Die(numberOfSides, provider);
}
// other factories.
}
Or you could just take the IRandomProvider
as a dependency directly in the class that creates the Die
class.