Greetings :)

Hi, I'm Louis!
I like to code, but I don't do enough of it.

This blog is about trying my best to keep up with the ever evolving stream of technology.

Friday, December 17, 2010

ASP.NET MVC dependency injection

Dependency Injection frameworks such as Ninject can be used to 'inject' dependencies into your ASP.NET MVC web application.

Steps with Ninject:

  1. Download Ninject
  2. Reference the Ninject.dll library
  3. Next we have to stop making ASP.NET MVC call controller classes directly, and instead call the controllers through the Dependency Injection framework.

    In order to do this, we do the following:

      * Create a subclass of ASP.NET MVC's DefaultControllerFactory class, overriding the GetControllerInstance method. (To make this call existing controllers like normal, return new StandardKernel.Get(controllerType)

      * Inside the Global.asax.cs file's Application_Start() method, set the new DefaultControllerFactory class's subclass as the current controller factory (i.e. ControllerBuilder.Current.SetControllerFactory(new MyNewClassName());
OK, so that's done, I'll explain the next bit with my subclass of DefaultControllerFactory, the only extra bit here is that I've set up some keys in my web.config.

Here's my subclass:
public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel kernel = new StandardKernel(new SportsStoreServices());
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            if(controllerType == null)
            {
                return null;
            }
            return (IController) kernel.Get(controllerType);
        }

        private class SportsStoreServices : NinjectModule
        {
            public override void Load()
            {
                Bind()
                    .To()
                    .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);
                Bind()
                    .ToSelf().WithConstructorArgument("numberOfItems",int.Parse(ConfigurationManager.AppSettings["ProductsPerPage"]));
            }

        }
    }


And here's the relevant bits in my web.config:

<connectionstrings>
    <add connectionstring="Server=.\SQLEXPRESS;Database=SportsStore;Trusted_Connection=yes;" name="AppDb">
  </add></connectionstrings>

  <appsettings>
    <add key="ProductsPerPage" value="5">
  </add></appsettings>
Yeah, so that's pretty much it - now my controller takes a IProductsRepository, as well as a ItemsPerPage (an int wrapper) object which I inject. The cool thing I find with this is that now I can make my configuration in my web.config; so I can make changes to my application without writing a line of code :)