Since you're using NinjectWebCommon
, I assume you have a web application of some sort. You really should only access the Ninject kernel in one place - at the composition root. It is the place where you are building the object graph and the only place you should ever need an access to the IoC container. To actually get the dependencies you need, you typically employ constructor injection.
In case of MVC web applications, for example, you have a controller factory using the Ninject kernel and that's the only place which references it.
To expand on your particular situation, your class would accept ICustomerBusiness
in its constructor, declaring that it needs an instance of ICustomerBusiness
as its dependency:
class CustomerBusinessConsumer : ICustomerBusinessConsumer
{
private readonly ICustomerBusiness customerBusiness;
public CustomerBusinessConsumer(ICustomerBusiness customerBusiness)
{
this.customerBusiness = customerBusiness;
}
...
}
Now, whichever class uses ICustomerBusinessConsumer
as its dependency, would follow the same pattern (accepting an instance of ICustomerBusinessConsumer
as its constructor parameter). You basically never construct your dependencies manually using new
(specific exceptions aside).
Then, you just have to make sure your classes get their dependencies and it's this composition root where you do this. What exactly is composition root depends on the type of an application you are writing (console application, WPF application, web service, MVC web application...)
EDIT: To get myself familiar with the situation in the ASP.NET WebForms realm
I had to look up the details since I've never used it. Unfortunately, WebForms require you to have a parameterless constructor at each of your Page classes, so you can't use constructor injection all the way from the top of the object graph down to the bottom.
However, after consulting Mark Seeman's chapter on composing objects in WebForms, I can rephrase how to deal with this framework's inefficiency, while still acting in line with good DI practices:
Have a class responsible for resolving the dependencies, using the Ninject's kernel you have set up. This may be a very thin wrapper around the kernel. Let's call it DependencyContainer
.
Create your container and save it in the application context, so that it's ready when you need it
protected void Application_Start(object sender, EventArgs e)
{
this.Application["container"] = new DependencyContainer();
}
Let's suppose your page class (let's call it HomePage
) has a dependency on ICustomerBusinessConsumer
. Then DependencyContainer
has to allow us to retrieve an instance of ICustomerBusinessConsumer
:
public ICustomerBusinessConsumer ResolveCustomerBusinessConsumer()
{
return Kernel.Get<ICustomerBusinessConsumer>();
}
Than in the MainPage
class itself, you will resolve its dependencies in the default constructor:
public MainPage()
{
var container = (DependencyContainer) HttpContext.Current.Application["container"];
this.customerBusinessConsumer = container.ResolveCustomerBusinessConsumer();
}
Few notes:
having the dependency container available in the HttpContext
must not be tempting to consider it a service locator. In fact, the best practice here (at least from the standpoint of being true to DI) is to have some kind of "implementor" classes to which you will relay the functionality of your page classes.
For example, each action handled by MainPage
will be only relayed to its implementor class. This implementor class will be a dependency of MainPage
and, as all other dependencies, will be resolved using the container.
The important part is that these implementor classes should be in assemblies not referencing the ASP.NET assemblies and thus without a chance to access the HttpContext
having to write so much code to achieve this is certainly not ideal, but it is only a consequence of the framework's limitation. In ASP.NET MVC applications, for example, this is dealt with in a much better way. There you have single point where you can compose the object graphs and you don't have to resolve them in each top-level class as you have to in WebForms.
the good thing is that while you have to write some plumbing code in the page class constructors, from there down the object graph you can employ constructor injection