How to Use Ninject as Dependency Injection with ASP.NET MVC
Table of Contents
- Introduction
- About Ninject
- Get Ninject Library
- Interface
- Class
- Dependency Resolve Class in Ninject
- Set Up Ninject Dependency in Application Global Class
- Setup Ninject Dependency in Ninject Module
- Use Ninject Dependency in ASP.NET MVC Controller
- Unit Test in Ninject + ASP.NET MVC App
- Mocking Data in Unit Test - Ninject + Moq
- Conclusion
- Other Choices for Dependency Injection in .NET
Introduction
This post demonstrates how to use Ninject as a dependency injection framework in an ASP.NET MVC application, including setup, unit testing, and mocking with Moq.
About Ninject
-
Blog - About Ninject in C#
-
Code Project - Ninject Example
Get Ninject Library
Install-Package Ninject -Version 3.2.2
Interface
In C#, for using Dependency Injection you'll define your interface and a class that implements this interface. Once you define the interface and bind the relation via Ninject, you can use this interface at other layers without knowing the detail implementation.
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 GetServices(Type serviceType)
{
return _resolutionRoot.GetAll(serviceType);
}
}
}
Set Up Ninject Dependency in Application Global Class
With Ninject, you can either set up binding as follows, or set up binding as individual modules by inheriting from the NinjectModule class.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// setting for Ninject
IKernel kernel = new StandardKernel();
kernel.Bind().To();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
Setup Ninject Dependency in Ninject Module
public class MyModule : NinjectModule
{
public override void Load()
{
Bind().To()
.WithConstructorArgument("kernel" , this .Kernel);
}
}
Use Ninject Dependency in ASP.NET MVC Controller
The beauty of doing dependency injection in an ASP.NET MVC controller is passing the interface to the constructor. The user/client doesn't need to know about the interface's implementation 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 benefit of dependency injection with Ninject is unit testing. Because everything is interface-based, you can set up different data in unit tests 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 temporary data for the interface and pass it 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;
}
Conclusion
Ninject is a useful C# .NET library for dependency injection. However, it appears that it is no longer actively maintained, so it may become a legacy dependency injection library in the future.
Other Choices for Dependency Injection in .NET
I would recommend using Autofac. It is well documented and supports different .NET libraries, such as ASP.NET Web Forms, MVC, WebAPI 1, WebAPI 2, SignalR, RIA, OWIN, WCF, MEF, NHibernate, and Moq.
-
Autofac
-
Castle Windsor
-
StructureMap
-
Spring.NET
-
Unity
-
Puzzle.NFactory
-
Ninject
-
S2Container.NET
-
PicoContainer.NET
-
LinFu