How to Use Ninject as Dependency Injection with ASP.NET MVC
About Ninject
Get Ninject Library
Last update is Sunday, January 4, 2015, looks like no one update/maintain it anymore...
Install-Package Ninject -Version 3.2.2
Interface
In C# for using Dependency Injection, you'll define your interface and class which will implement this interface. Once you defined interface and bind the relation via Ninject, then you could use this interface at other layer or same layer and without knowing what's the detail implementation about the specific interface.
namespace NinjectConstructorInjectionWeb
{
public interface ISamurai
{
string GetData();
}
}
Class
namespace NinjectConstructorInjectionWeb
{
public class Samurai : ISamurai
{
public string GetData()
{
return "my data";
}
}
}
Dependency Resolve class in Ninject
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Ninject.Syntax;
using Ninject;
namespace NinjectConstructorInjectionWeb
{
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IResolutionRoot _resolutionRoot;
public NinjectDependencyResolver(IResolutionRoot kernel)
{
_resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
return _resolutionRoot.TryGet(serviceType);
}
public IEnumerable
Set up Ninject Dependency in application Global Class
By using Ninject, you could either setup binding as following, or setup
binding as each module by inherict from NinjectModule
class.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// setting for Ninject
IKernel kernel = new StandardKernel();
kernel.Bind<ISamurai>().To<Samurai>();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
Setup Ninject Dependency in Ninject Module
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<ISamurai>().To<Samurai >()
.WithConstructorArgument("kernel" , this .Kernel);
}
}
Use Ninject Dependency in ASP.NET MVC Controller
The beauty of doing Depenency Injection in ASP.NET MVC controller is by passing the interface to the contructor of the MVC controller. User/Client don't need to know about the interface's logic.
private readonly ISamurai _samurai;
public HomeController(ISamurai samurai)
{
_samurai = samurai;
}
public ActionResult Test()
{
// you should see "my data" here.
ViewBag.Hi = _samurai.Attach();
return View();
}
Unit test in Ninject + ASP.NET MVC App
Another important thing with Dependency Inject in Ninject is, UnitTest. Because everything is interface, you could setup different data at UnitTest to test your actual logic.
[TestMethod ]
public void Product()
{
ISamurai testService = new Samurai();
HomeController controller = new HomeController (testService);
controller.Product();
}
Mocking data in Unit Test - Ninject + Moq
Use Ninject + Moq + Unit Test, so you can mock the temp data to the interface and pass to your controller.
public static IProductBzService GetProductService()
{
Mock mock = new Mock ();
mock.SetupGet(x => x.Id).Returns(1);
mock.SetupGet(x => x.Name).Returns("test name" );
mock.SetupGet(x => x.Price).Returns(11.11m);
mock.SetupGet(x => x.Unit).Returns(2);
mock.Setup(x => x.Total()).Returns(999.999m);
return mock.Object;
}
In conlusion
Ninject is cool C# .NET library for dependency injection, about couple years ago. looks like no one update it anymore, I would think this will be a legacy Denepencey Injection Library in the future.
What's my other choice for Dependency in .NET?
I would recommand use Autofac, it is well document, support different .NET library, such as ASP.NET Web Forms, MVC, WebAPI 1, WebAPI 2, Signal R, RIA, OWIN, WCF, MEF, NHibernate, Moq.
- Autofac
- Castle Windsor
- StructureMap
- Spring.NET
- Unity
- Puzzle.NFactory
- Ninject
- S2Container.NET
- PicoContainer.NET
- LinFu