Reputation: 1022
I am creating a new project in ASP.net using MVC 4.
I want to setup dependency injection using Ninject
. But before I proceed what are the best practices when setting up dependency injection?
Currently I have a binder class setup within the webproject which will reference data projects within the solution.
The binder class is as shown below:
Public static class Binder
{
static Ninject.IKernel _kernel;
static Binder()
{
_kernel = new Ninject.StandardKernel();
_kernel.Bind<IConfig>().To<AppSettingsConfig>();
_kernel.Bind<IDocuments>().To<DocumentsClass.Documents>();
}
public static T GetImplementation<T>()
{
return _kernel.Get<T>();
}
}
Then within my controller i use the GetImplementation method to use the exact require dependency rather than registering all on application startup.
Example code from controller:
Public ActionResult Get (int id)
{
var repository = Binder.GetImplementation<IDocuments>();
// do some stuff with the repository here
}
Not sure if this would be a good approach? Any advice would be good.
Upvotes: 9
Views: 4387
Reputation: 32725
Best practice for Ninject is to use the MVC extension for Ninject: https://github.com/ninject/ninject.web.mvc/wiki/MVC3
Upvotes: 4
Reputation: 172
You are linked to the instance of your Binder class inside controller. It makes your class not reusable and it must be refactored, because it is not resposibility of controller to get correct instance of IDocuments implementation. There is must be some external dependency resolver(like example - Ninject) which have to make constructor injection or property injection.
Upvotes: 0
Reputation: 48230
What you have now is an example of the Service Locator anti-pattern. Google for more details as it has been discussed many times.
In short, rather than relying on the service locator
public class SomeController
{
public ActionResult Get (int id)
{
var repository = Binder.GetImplementation<IDocuments>();
// do some stuff with the repository here
}
}
you should have your service injected into the client class (rely on constructor injection)
public class SomeController
{
private IDocuments documentService { get; set; }
public SomeController( IDocuments documentService )
{
this.documentService = documentService;
}
public ActionResult Get (int id)
{
var repository = documentService;
// do some stuff with the repository here
}
}
In this specific case, you could set up your controller factory to use your IoC container to resolve your controllers.
Upvotes: 16