Using Ninject in MVC 3

Previously I have chatted about how to use Structured Map and Unity for Dependency Injections. Here is the link

https://kevww.wordpress.com/tag/dependency-injection/

Today I am going to discuss how to use Ninject for your DI container.

First of all, let’s add Ninject and Ninject.MVC3 to our web application using Nuget. Here is the command you can use to install them in Package Manager Console in VS2010.

PM> Install-Package Ninject

PM> Install-Package Ninject.MVC3 -Version 2.2.2.0

Then let’s get started. And modify the Global.asax to use NinjectHttpApplication instead of HttpApplication. It overrides CreateKernel to create a kernel and load all the modules.

public class MvcApplication : NinjectHttpApplication
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
       filters.Add(new HandleErrorAttribute());
   }
 
   public static void RegisterRoutes(RouteCollection routes)
   {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
       routes.MapRoute(
           "Default", // Route name
           "{controller}/{action}/{id}", // URL with parameters
           new
           {
               controller = "Home",
               action = "Index",
               id = UrlParameter.Optional
           });
   }
 
   protected override IKernel CreateKernel()
   {
       var kernel = new StandardKernel();
       kernel.Load(Assembly.GetExecutingAssembly());
       return kernel;
   }
 
   protected override void OnApplicationStarted()
   {
       base.OnApplicationStarted();
 
       AreaRegistration.RegisterAllAreas();
       RegisterGlobalFilters(GlobalFilters.Filters);
       RegisterRoutes(RouteTable.Routes);
   }
}

The only thing that has to be done is to add dependencies for controller constructor and configure the Ninject bindings for its dependencies. The controller itself will be found by Ninject even without adding a binding.

public class HomeController : Controller
{
    private readonly IWelcomeMessageService welcomeMessageService;
 
    public HomeController(IWelcomeMessageService welcomeMessageService)
    {
        this.welcomeMessageService = welcomeMessageService;
    }
 
    public void Index()
    {
        ViewModel.Message = this.welcomeMessageService.TodaysWelcomeMessage;
        return View();
    }
}
 
public class WelcomeMessageServiceModule : NinjectModule
{
    public override void Load()
    {
         this.Bind().To();
    }
}

Ninject provides contextual bindings. It allows you to register more than one binding for a type. There are 3 ways.

1. add condition to the bindings.

interface ICondition {
  bool Matches(T obj);
}

Bind().To();
Bind().To().Only(When.Context.Service.Name.StartsWith("Foo"));

2. Create Attribute

public class RangeAttribute : Attribute {}

public class Swordsman {
  [Inject] public IWeapon Weapon { get; set; }
}

public class Ninja {
  [Inject] public IWeapon MeleeWeapon { get; set; }
  [Inject, Range] public IWeapon RangeWeapon { get; set; }
}

3. Create Tags

public class Ninja {
  [Inject] public IWeapon MeleeWeapon { get; set; }
  [Inject, Tag("range")] public IWeapon RangeWeapon { get; set; }
}

Bind().To();
Bind().To().Only(When.Context.Tag == "range");

Here are some references you can read more about Ninject.

http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ ( This blog post shows you how to use Ninject for Attribute bindings.)

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

http://ninject.codeplex.com/wikipage?title=User%20Guide&referringTitle=Home (Ninject Home)

Advertisements

Dependency Injection with Structured Map in MVC 3

Regarding to my previous post – How to implement DI with Unity 2.0, to implement DI with structured map is very similar.

1. Download Structured Map from Gtihub, https://github.com/structuremap/structuremap/downloads and reference StructuredMap to your project.

2. Create a DependencyResolver class and implement interface IDependencyResolver

public class StructureMapDependencyResolver : IDependencyResolver
{
readonly IContainer _container;

public StructureMapDependencyResolver(IContainer container)
{
_container = container;

// TODO: if you haven't registered necessary interfaces somewhere else, you'll need to do so here.
}

public object GetService(Type serviceType)
{
if (serviceType.IsClass)
{
return GetConcreteService(serviceType);
}
else
{
return GetInterfaceService(serviceType);
}
}

private object GetConcreteService(Type serviceType)
{
try
{
// Can't use TryGetInstance here because it won’t create concrete types
return _container.GetInstance(serviceType);
}
catch (StructureMapException)
{
return null;
}
}

private object GetInterfaceService(Type serviceType)
{
return _container.TryGetInstance(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>();
}
}

public class StructureMapControllerActivator : IControllerActivator
{
private readonly IContainer _container;

public StructureMapControllerActivator(IContainer container)
{
_container = container;
}

public IController Create(RequestContext requestContext, Type controllerType)
{
return _container.GetInstance(controllerType) as IController;
}
}

3. Create a class StructurMapContainer with a static method for registering the our dependencies, and register the unity container as the service locator for the MVC application.

Here is an example of registering a SomeService type to the unity container. Of course you will need to write the implementaton of SomeService and implement ISomeService.

public class StructurMapContainer
{
public static IContainer InitContainer()
{
ObjectFactory.Initialize(x =>
{
x.For<IControllerFactory>().Use<DefaultControllerFactory>();
x.For<IControllerActivator>().Use<StructureMapControllerActivator>();
x.For<ISomeService>().Use<SomeService>();
});

return ObjectFactory.Container;
}
}

4. In the Global.asax.cs file, we will call the StructurMapContainer.InitContainer() method.

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

DependencyResolver.SetResolver(new StructureMapDependencyResolver(StructurMapContainer.InitContainer()));
}

5. Resolving dependencies, to modify HomeController.cs and add a constructor with dependent services


public class HomeController : Controller
{
    private ISomeService _service;
    public HomeController(ISomeService service)
    {
        _service = service;
    }
}

6. Alternatively, you can add the SomeService as a property of HomeController with Dependency attribute.


[Dependency]

public ISomeService SomeService {get;set;}

Dependency Injection with Unity 2.0 in MVC 3

ASP.NET MVC 3 provides better support for applying Dependency Injection (DI) and for integrating with Dependency Injection or Inversion of Control (IOC) containers.

MVC 3 supports the Common Service Locator library and any DI container that supports that library’s IServiceLocator interface. It also supports a new IDependencyResolver interface that makes it easier to integrate DI frameworks.

Here I am going to show you how to use DI with Unity and DependencyResolver,

1. Create a MVC 3 project and download Unity 2.0 from MSDN,  http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=9093 and add Microsoft.Practices.Unity to your project reference.

2. Create a DependencyResolver class and implement interface IDependencyResolver


public class UnityDependencyResolver : IDependencyResolver
{
IUnityContainer _container;

public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
}

public object GetService(Type serviceType)
{
object instance;
try
{
instance = _container.Resolve(serviceType);
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
return instance;
}
catch (Exception e)
{
return null;
}
}

public IEnumerable<object> GetServices(Type serviceType)
{
return _container.ResolveAll(serviceType);
}
}

3. Create a class UnityContainerSetup with a static method for registering the our dependencies, and register the unity container as the service locator for the MVC application.

Here is an example of registering a SomeService type to the unity container. Of course you will need to write the implementaton of SomeService and implement ISomeService.

     public class UnityContainerSetup
    {
        public static void SetUp()
        {
            var container = new UnityContainer();

            container.RegisterType<ISomeService, SomeService>();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
    }

4. In the Global.asax.cs file, we will call the UnityContainerSetup.Setup() method.

 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            UnityContainerSetup.SetUp();
        }

5. Resolving dependencies, to modify HomeController.cs and add a constructor with dependent services


public class HomeController : Controller
    {
        private ISomeService _service;
        public HomeController(ISomeService service)
        {
            _service = service;
        }
    }

6. Alternatively, you can add the SomeService as a property of HomeController with Dependency attribute.


[Dependency]

public ISomeService SomeService {get;set;}