How to use Ninject to insert dependency using constructor pattern

Download Sample Application

Recently I was working on a prototype for implementation of logging mechanism for my application. Previously I used to use Unity for Dependency Injection (DI) to inject different logging frameworks into the application for integration and unit testing. Now I am switching to using Ninject for DI. In this post I will how you can to use Ninject in your applications. I will not go into details why I chose Ninject and not Unity for future projects. That will be topic for discussion for another day. For now I will summarize it in one line that Ninject is light weight and easy to use framework as compared to Unity.

Download Ninject Framework

You can download Ninject from Codeplex. Or better option is to get it using NuGet manager. Add reference to Ninject.dll in your project.

Create Interface and Classes for DI

For my logger, I created interface IAppLogger that will act as interface for all logging methods for my application. Following snippet shows sample of this interface.

public interface IAppLogger
{
  void Log(..............);
  void Log(..............);
}
    

Following code snippet shows sample of concrete class implementation for this interface. This class implements logging mechanism using Log4Net.

public class Log4NetLogger : IAppLogger
{
 private static readonly ILog MyLog = LogManager.GetLogger(typeof(Log4NetLogger));

 public Log4NetLogger()
 {
   BasicConfigurator.Configure();
 }
       
 public void Log(string id, string context, string methodName, 
                 string methodParams, string value)
 {
    MyLog.Info("Start");
    MyLog.Error(string.Format("{0} {1} {2} {3} {4}", 
        id, context, methodName, methodParams, value));
    MyLog.Info("End");
 }

 public void Log(string id, string context, string methodName, Exception ex)
 {
   MyLog.Info("Start");
   MyLog.Fatal(context, ex);
   MyLog.Info("End");
 }
}
    

Now that we have interface and class set up to include in DI, we can now look at how Ninject makes it easy to implement DI.

Implement Ninject Module

First step in using Ninject is to bind interface to object that will need to be created when application encounters DI. Create a class that derives from NinjectModule. Override Load method to include bindings. In this sample I will just use a simple implementation of Bind method. There are more advanced overloaded methods available to control the binding in more controlled way. For this sample, the following simple implementation will work.

public class LoggerModule : NinjectModule
{
  public override void Load()
  {
    Bind<IAppLogger>().To<Log4NetLogger>().InSingletonScope();
  }
}
    

What this code means is that every time there is an instance of IAppLogger to be injected into the application, create an instance of Log4NetLogger class. Since we need singleton instance for logger, we call InSingletonScope method that indicates to Ninject to create singleton Log4NetLogger class.

You can include all bindings of your application in one module. But it is preferred that you create multiple modules and include binding related to certain sections of the application into appropriate modules.

Add NinjectModules into framework

Now that we have implemented our NinjectModule we need a way to tell Ninject framework about this. You can add one more modules into IKernel object of Ninject. Following method show how DI framework gets to know about our modules.

static void SetupDI()
{
  NinjectKernel = new StandardKernel(new LoggerModule());
}
    

Add DI to class using Inject attribute

Now we have DI framework set up for our logger interface. Lets see how we are going to use DI in our classes. In this sample, I have create AmazonRepositary class. I would like to inject IAppLogger object into this class so I can log any errors or information into my logger. Following code snippet shows how I used Inject attribute to insert IAppLogger to class. In this case I am using Constructor Injection pattern.

public class AmazonRepository
{
   private IAppLogger _appLogger;
        
   [Inject]
   public AmazonRepository(IAppLogger appLogger)
   {
     _appLogger = appLogger;
   }

   public void GetProducts(SearchParameters searchParams, string ip)
   {
        .....
   }
}
    

Inject attribute lets Ninject framework know that when Ninject kernel is used to create an instance of AmazonRepository object, it will create an instance of IAppLogger object and inject that into class constructor. Following code shows how kernel object is used to create this class.

var repo = NinjectKernel.Get<AmazonRepository>();
    

You can see that your implementation does not need to know what logger class is going to be used when creating instance of injected interface. You have already set up the binding in NinjectModule. By writing few lines of code we have managed to use Ninject as our DI framework. In subsequent posts, I will discuss other DI patterns and some advanced use of binding mechanisms.

Sample Code

I have attached sample project with this post that I used for demonstrate use of constructor patterns for DI. This project was created using VS11 and .Net 4.5. There is nothing specific to .Net4.5 used in this implementation. You should just be able to use the same code in VS2010.

comments powered by Disqus

Blog Tags