Investigating Ninject

Whilst I’ve used IoC frameworks such as Unity, MEF, Spring.net etc. in the past, I’ve not gotten around to playing with Ninject. So time to have a play.

First off I created a simple interface, IService and corresponding implementing LocalService

public interface IService
{
   void Run();
}

public class LocalService : IService
{
   public void Run()
   {
      Console.WriteLine("Local Service");
   }
}

Now I created a simple client object

public interface IClient
{
   IService Service { get; }

   void Run();
}

public class Client : IClient
{
   public Client(IService service)
   {
      Service = service;
   }

   public IService Service { get; private set; }

   public void Run()
   {
      Service.Run();
   }
}

So as you can see the idea is simple. A client requires an IService passed by the IoC into the constructor. At some point we’ll call the client’s Run method and expect a LocalService to run. Obviously error handling etc. omitted for brevity.

Now let’s create the configuration/bindings to allow Ninject to inject the required service into the client.

var kernel = new StandardKernel();

kernel.Bind<IService>().To<LocalService>();
kernel.Bind<IClient>().To<Client>();

var client = kernel.Get<IClient>();
client.Run();

What about if we have multiple IService implementations, see the changes below which include the client accepting an array of IService and the kernel code includes an additional binding.

public class RemoteService : IService
{
   public void Run()
   {
     Console.WriteLine("RemoteService");
   }
}

public interface IClient
{
   IService[] Service { get; }

   void Run();
}

public class Client : IClient
{
   public Client(IService[] service)
   {
      Service = service;
   }

   public IService[] Service { get; private set; }

   public void Run()
   {
      foreach(IService service in Service)
         service.Run();
   }
}

var kernel = new StandardKernel();

kernel.Bind<IService>().To<LocalService>();
kernel.Bind<IService>().To<RemoteService>();
kernel.Bind<IClient>().To<Client>();

var client = kernel.Get<IClient>();
client.Run();

So using Ninject to inject into a constructor is simple. Now let’s make a change to the client constructor by removing the parameter and instead use property injection.

public class Client : IClient
{
   [Inject]
   public IService[] Service { get; set; }

  // the Run method remains unchanged as does the binding code
}