Monday, February 22, 2010

Creating an ASP.NET MVC 2 Controller Factory with Ninject

Introduction



Recently I've been getting into Test Driven Development and one useful thing that helps me out with this is making use of the Inversion of control principle. This makes it easy to pass a Mock version of all my services for the purposes of testing.

However this presents a challenge with the standard MVC Controller Factory. It only supports the parameterless contructors. However, one of the great things about ASP.NET MVC (2) is that it allows you to override most aspects of the framework. It doesn't restrict you as much as it's ASP.NET webforms predecessor. So to avoid the so call "Anti Pattern" of having both a Parameterless Constructor for your "Real Services" and an overloaded constructor for your testing/Mock Services, you can follow this guide to create a Controller Factory which uses ninject. Then you'll only have 1 constructor and you'll sleep soundly.

Creating Ninject Controller Factory




  • Now let's create a new MVC 2 Project
  • Once it open's we'll need to add a reference to ninject.core.dll

  • Next, let's create a helper method for our ninject controller factory called NinjectControllerFactory.cs

  • We'll need to inherit from the default controller factory. Mainly so we don't have to re-invent the wheel and we can just override one part of it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace NinjectIoc
{
    public class NinjectControllerFactory : DefaultControllerFactory
    {
    }
}

  • For the purposes of this demo we'll need to create an example service and interface, to demo the Ioc process and ninject.

namespace ExampleServices
{
    public interface IExampleInterface
    {
        void Method1();
        string Property1 { get; }
    }

    public class ExampleConcreteClass : IExampleInterface
    {

        #region IExampleInterface Members

        public void Method1()
        {
            // Do Nothing.
        }

        public string Property1
        {
            get
            {
                return "Hello World";
            }
        }

        #endregion
    }
}
  • Now we can setup a ninject Module which returns our ExampleConcreteClass when given the IExampleInterface.
  • We do this by creating a class which inherits from ninjects standardmodule and overrides the Load Method

private class ExampleConfigModule : StandardModule
    {
        public override void Load()
        {
            Bind<IExampleInterface>().To<ExampleConcreteClass>();
        }
    }
  • Finally we'll override the GetControllerInstance Method from the DefaultControllerFactory using ninject to return a controller complete with any parameters in the controllers constructor.
public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel kernel = new StandardKernel(new ExampleConfigModule());

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            // We don't want to pass null to ninject as we'll get a strange error.
            return controllerType == null ? null
                                          : (IController)kernel.Get(controllerType);
        }
    }
  • Now we'll need to tell the MVC 2 framework to use our new Controller Factory insted of the defaultControllerFactory.
  • To do this we'll need to edit the global.asax.cs file
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 } // Parameter defaults
            );

            // Setup Our new Controller Factory.
            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

        }
  • That's it for the setup. Now we'll need to test it out.
  • Let's update the default Home Controller to include a parameter in it's constructor
public class HomeController : Controller
    {
        #region Testing Our Controller Factory

        private IExampleInterface _example;

        public HomeController(IExampleInterface exampleInterface)
        {
            // Test our our new Ninject Controller Factory
            _example = exampleInterface;
        }

        #endregion

        public ActionResult Index()
        {
            // Will it work?? 
            ViewData["Message"] = _example.Property1;

            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }

  • Now if this work's we should see the word's "Hello World" on the home page.

  • Cool. it worked.

Conclusion


It would be very easy to swap out Ninject for another Ioc container. So i hope it helps someone out there. If you want to get a copy of the example code then I've copied it up to my



Enjoy.

23 comments:

  1. I'm not able to download a copy of your example, can you check that your link is good please ?

    ReplyDelete
  2. Hey.. thanks for that. I've updated the link and it works ok now.. please try again ;)

    ReplyDelete
  3. Great post, still cannot get why "Type controllerType" may be null?

    ReplyDelete
  4. The blog gave me idea to create asp net mvc 2 controller My sincere thanks for sharing this post please continue to share this post
    Dot Net Training in Chennai

    ReplyDelete
  5. Excellent post. you have post an very informative information. Keep it up. Salesforce Training in Chennai | Selenium Training in Chennai

    ReplyDelete
  6. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru ASP.NET Essential Training Online . Nowadays Dot Net has tons of job opportunities on various vertical industry.
    or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete
  7. Interesting post! This is really helpful for me. I like it! Thanks for sharing!
    Mobile application developers in Chennai | PHP developers Chennai

    ReplyDelete
  8. Thanks for sharing this niche useful informative post to our knowledge.
    brochure designers in chennai | brochure design company in chennai

    ReplyDelete
  9. Home Mart is a site about Home Improvement, Furniture, Home Appliances and many more.
    Check out the best
    home office desks nz
    coffee table nz
    bookshelves
    balance bike

    ReplyDelete
  10. Para penjudi akan dengan mudah untuk memenangkan permainan judi ceme keliling. Hanya dengan menggunakan situs ini dan menggunakan cara ini maka para penjudi akan dengan mudah untuk mendapatkan banyak kemenangan
    asikqq
    http://dewaqqq.club/
    http://sumoqq.today/
    interqq
    pionpoker
    bandar ceme terpercaya
    freebet tanpa deposit
    paito warna
    syair sgp

    ReplyDelete
  11. Nice Post. If you wish to get study abroad in any course. The below information will suit you.
    Skolarrssolutions
    Mbbs in Russia
    Mbbs in UK
    Mbbs in Malaysia

    ReplyDelete
  12. Wow it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot. it is really explainable very well and i got more information from your blog.
    Blockchain online training

    ReplyDelete
  13. Great blog thanks for sharing Looking for the best creative agency to fuel new brand ideas? Adhuntt Media is not just a digital marketing company in chennai. We specialize in revamping your brand identity to drive in best traffic that converts.

    ReplyDelete
  14. Nice blog thanks for sharing Choosing the right place to buy your first plant isn’t that hard of a choice anymore. Presenting the best plant nursery in Chennai - Karuna Nursery Gardens is proud to showcase more than 3000+ plants ready to be chosen from.

    ReplyDelete
  15. Excellent blog thanks for sharing Run your salon business successfully by tying up with the best beauty shop in Chennai - The Pixies Beauty Shop. With tons of prestigious brands to choose from, and amazing offers we’ll have you amazed.

    ReplyDelete
  16. Awesome blog thanks for sharing While choosing your perfect ride for driving, Accord Cars comes with and the best packages for you to pick from. Car rentals for self drive in Chennai are done the easier. Just pick out your plan from hourly, daily, weekly and even monthly plans available.

    ReplyDelete
  17. Very useful blog thanks for sharing With over a three decade of beauty expertise at our fingertips, we believed that everyone has the right to be beautiful. And so began the journey of our very own Pearl’s Beautician course in Chennai.

    ReplyDelete
  18. I found your blog while searching for the updates, I am happy to be here. Very useful content and also easily understandable providing.. Believe me I did wrote an post about tutorials for beginners with reference of your blog.
    Devops certification training
    Devops online course
    Devops online training
    Devops training course

    ReplyDelete
  19. I just loved your article on the beginners guide to starting a blog.If somebody take this blog article seriously in their life, he/she can earn his living by doing blogging.thank you for thizs article. blockchain online training

    ReplyDelete