Constructor Injection is typically a more favorable technique than Property injection, because Property Injection causes the Temporal Coupling code smell. Property Injection should, therefore, only be used for dependencies that are truly optional (which it isn't in your case). Dependencies, however, should hardly ever be optional. Even in case there is no implementation for a dependency, it's generally better to create and inject a Null Object implementation compared to injecting a null
reference. Instead of using Property Injection, prefer injecting all required dependencies through the constructor.
Another practice that leads to considerable downsides is when you let your application code take a dependency on the DI Container itself (or an abstraction that represents the resolve-API of the container). This is an anti-pattern called Service Locator. The only place you should reference the container is inside your Composition Root. The Program
class in your example represents the Composition Root.
Instead your Hello
class should simply accept World
as required constructor argument:
class Hello
{
private readonly World theWorld;
public Hello(World world)
{
this.theWorld = world ?? throw new ArgumentNullException("world");
}
public override string ToString()
{
return this.theWorld.ToString();
}
}
Notice how any reference to the container was completely removed from this class. This makes the class simpler, more maintainable, more testable, and even makes it possible to compose this class without using a DI Container; a practice commonly known as Pure DI. When your application is small, Pure DI can even be a better option than using a container.
Here's how your Program
class can look like using Ninject:
class Program
{
static void Main(string[] args)
{
// Configure
var kernel = new StandardKernel();
kernel.Bind<Hello>().ToSelf();
kernel.Bind<World>().ToSelf();
// Resolve
var hello = kernel.Get<Hello>();
// Use
Console.WriteLine(hello.ToString());
Console.ReadLine();
}
}
Without a container, it would be as follows:
class Program
{
static void Main(string[] args)
{
// Resolve
var hello = new Hello(new World());
// Use
Console.WriteLine(hello.ToString());
Console.ReadLine();
}
}