Home > .Net, C#, MVC, Sitecore 6, Unit Testing > Sitecore MVC new Ninject Controller Factory – clean version

Sitecore MVC new Ninject Controller Factory – clean version

In this post we will have  revisit my last blog post, using Ninject with Sitecore MVC. In this new approach we will simplify the code to do the exactly same thing as in the last post LINK.
So what we want is to be able to inject Concrete implementation in the our Sitecore Controller.
We will do this by creating a ninjectc controller factory and forwarding  to the default Sitecore controller factory, so our implementation is used when Sitecore creates it’s controller. By doing it this way all standard Sitecore MVC functionality will still work, but we now have the possibility to inject our concrete implementation on creation time of the controllers.

First we need a Factory for creating the Ninject kernel


 public class NinjectKernelFactory
 {
   public IKernel Create()
   {
    return LoadAssembliesIntoKernel(new StandardKernel());
   }

   private IKernel LoadAssembliesIntoKernel(IKernel kernel)
   {
     foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
     {
      try
      {
        kernel.Load(assembly);
      }
      catch (Exception)
      {
         //Empty Catch used because ninject have problem
         //with loading some of the Sitecore MVC assemblies.
        // Method .ToString()
      }
    }
     return kernel;
   }
 }

With that in place we can create the the NinjectControllerFactory


 public class NinjectControllerFactory : DefaultControllerFactory
 {

  private IKernel _kernel;
  public NinjectControllerFactory(IKernel kernel)
  {
    _kernel = kernel;
  }

  public override void ReleaseController(IController controller)
  {
    _kernel.Release(controller);
  }

  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  {
    return (IController)_kernel.Get(controllerType);
  }
 }

]

All that is left is now for binding it all together in a new InitilizeContollerFactory


 public class InitializeNinjectControllerFactory
 {
   public virtual void Process(PipelineArgs args)
   {
    SetControllerFactory(args);
   }

  protected virtual void SetControllerFactory(PipelineArgs args)
  {
    NinjectKernelFactory kernelFactory = new NinjectKernelFactory();
    NinjectControllerFactory ninjectControllerFactory = new NinjectControllerFactory(kernelFactory.Create());
    SitecoreControllerFactory sitecoreControllerFactory = new SitecoreControllerFactory(ninjectControllerFactory);
    ControllerBuilder.Current.SetControllerFactory(sitecoreControllerFactory);
  }
 }

And off course we need to swap the originale InitlizeControllerFactory with our new one.

Sitecore default :

</pre>
<processor type="Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory, Sitecore.Mvc"/>

Replaced with this:


<processor type="SitecoreNinjectModule.InitializeNinjectControllerFactory, SitecoreNinjectModule"/>

Now Lets try it our I have created a really simple example first an Item with a controller rendering on.

And the sourcode for the controller


public class StoryController : SitecoreController

{
 private ITestInterface _testInterface;
 public StoryController(ITestInterface testInterface)
 {
 _testInterface = testInterface;
 }

public ActionResult From()
 {

ViewBag.Froms = _testInterface.Get();
 return View();
 }
 }

And now to the View Code

And our RazerView


@model dynamic
 <h2>From vIew</h2>

@ViewBag.Froms

And a simple TestInterface and TestClass


public interface ITestInterface
 {
 string Get();
 }


public class TestClass : ITestInterface
 {
 public string Get()
 {
 return "Hallo From Test";
 }
 }

And the output of it all

There we are a much nicer and cleaner solution presented then I came up with in my last blog post and without breaking any Sitecore functionalit, and off course you can still unit test the controller.

  1. 23/10/2012 at 22:45

    Thanks, that’s a very nice explanation of using a DI mechanism cleanly with Sitecore MVC.

  1. 20/01/2016 at 15:58

Leave a reply to kevinobee Cancel reply