Category Archives: Ninject

Ninject ActivationStrategy

The NInject ActivationStrategy allows us to create code which will be executed automatically by Ninject during activation and/or deactivation of an object.

So let’s say when we create an object we want it to be created in a two-phase process, i.e. after creation we want to initialize the object. In such a situation we might define an initialization interface, such as

public interface IObjectInitializer
{
   void Initialize();
}

We might have an object which looks like the following

public class MyObject : IObjectInitializer
{
   public MyObject()
   {
      Debug.WriteLine("Constructor");            
   }

   public void Initialize()
   {
      Debug.WriteLine("Initialized");
   }
}

Now when we want to create an instance of MyObject via NInject we obviously need to setup the relevant binding and get an instance of MyObject from the container, thus

StandardKernel kernel = new StandardKernel();

kernel.Bind<MyObject>().To<MyObject>();

MyObject obj = kernel.Get<MyObject>();
obj.Initialize();

In the above code we’ll get an instance of MyObject and then call the Initialize method and this may be a pattern we repeat often, hence it’d be much better if NInject could handle this for us.

To achieve this we can add an ActivationStrategy to NInject as follows

kernel.Components.Add<IActivationStrategy, MyInitializationStrategy>();

This will obviously need to be set-up prior to any instantiation of objects.

Now let’s look at the MyInitializationStrategy object

 public class MyInitializationStrategy : ActivationStrategy
{
   public override void Activate(IContext context, InstanceReference reference)
   {
      reference.IfInstanceIs<IObjectInitializer>(x => x.Initialize());
   }
}

In actual fact, the people behind NInject have already catered for a two-phase creation interface by supplying (and ofcourse adding the Components collection) an interface named InitializableStrategy which does exactly what MyInitializationStrategy does. They also use the same ActivationStrategy mechanism for several other strategies which are used to handle property injection, method injection and more.

Another strategy that we can use in our own objects is StartableStrategy which handles objects which implement the IStartable interface. This supports both a Start and a Stop method on an object as part of the activation and deactivation.

We can also implement code to be executed upon activation/deactivation via the fluent binding interface, for example

kernel.Bind<MyObject>().
   To<MyObject>().
   OnActivation(x => x.Initialize()).
   OnDeactivation(_ => Debug.WriteLine("Deactivation"));

Therefore in this instance we need not create the activation strategy for our activation/deactivation code but instead uses the OnActivation and/or OnDeactivation methods.

Note: Remember if your object supports IInitializable and you also duplicate the calls within the OnActivation/OnDeactivation methods, your code will be called twice

Binding Ninject to an instance based upon the dependency type

I want to bind the Common.Logging.ILog to an implementation which can take a type argument as it’s parameter, i.e. We can use the Common.Logging.LogManager.GetManager method by passing a type into it, as per the following code

LogManager.GetLogger(typeof(MyType));

So how can we simply declare a dependency on our type to ILog and have it automatically get the logger with the type parameter.

The code speaks for itself, so here it is

IKernel kernel = new StandardKernel();

kernel.Bind<ILog>().ToMethod(ctx =>
{
   Type type = ctx.Request.ParentContext.Request.Service;
   return LogManager.GetLogger(type);
});

In the above code we bind to a method, thus we can dynamically handle the binding. From the IContext ctx we can find which type requested the binding and then use this in the call to GetLogger.

So with this the dependency object simply includes the following

public class MyClass
{
   // other methods, properties etc.

   [Inject]
   public ILog Logger { get; set; }
}

and everything “magically” binds together to get the logger with the type set to typeof(MyClass).

NinjectModules

NinjectModules allow us to define bindings in assemblies without the need to resort to passing around an instance of the IKernel.

So let’s look at an example. We have an EXE project and another project which contains the common interfaces used in the application. Let’s assume we have an IAdministrationSettings interface in the “common” project. The main application has classes and/or properties which have service dependencies on IAdministrationSettings.

Now we create a third project which will contain the implementations of the interfaces used in our application. So it’s got a reference to the common interfaces project/DLL but has no knowledge of the EXE and likewise the EXE has no knowledge of the implementation project.

So we want to now bind our implementation to the interface and have it automatically injected into our EXE.

In the implementation project we add the usual NInject references (or use NuGet to do it) and create a file, mines called Module.cs but the name doesn’t matter. Then we place the following code into the file

public class Module : NinjectModule
{
   public override void Load()
   {
      Bind<IAdministrationSettings>().To<AdministrationSettings>().InSingletonScope();
   }
}

We’ve declared a NinjectModule (there could be more than one) which define the bindings of our interface(s) to implementation(s), but we now need Ninject in the EXE to load these modules and hence allow it to bind the correct implementation, so we use the following code in the EXE

IKernel kernel = new StandardKernel();
kernel.Load("*.dll");

The above used the wildcard to load any/all DLL’s which have NinjectModules, alternatively we could store the implementations in “known” locations or ofcourse put the actual path to the DLL into this method.

Now Ninject will automatically handle the bindings.

Caliburn Micro and inversion of control using Ninject

Caliburn Micro comes with it’s own built in mechanism for creating objects as and when required. However it’s bootstrapper comes with methods which allow us to override the default behaviour. The methods such as GetInstance, GetAllInstances and BuildUp are used to resolve dependencies in a user supplied IoC container.

I’m the built in mechanism is more than adequate for most peoples usage, but I tend to rather like Ninject. So here are the steps (which ofcourse can be used with your own preferred IoC framework).

Create a bootstrapper as per the following (where ShellViewModel is replaced with your view model name)

public class AppBootstrapper : Bootstrapper<ShellViewModel>
{
   protected override void Configure()
   {
   }

   protected override void OnExit(object sender, EventArgs e)
   {
   }

   protected override object GetInstance(Type service, string key)
   {
   }

   protected override IEnumerable<object> GetAllInstances(Type service)
   {
   }

   protected override void BuildUp(object instance)
   {
   }
}

These are the methods we need to override and implement the code for, to allow Caliburn Micro to use our preferred Ioc framework.

Configure

The configure method is used to configure Caliburn Micro to use our IoC framework, so basically this is where we instantiate the StandardKernel in Ninject. Firstly add a class level variable as follows

private IKernel kernel;

Next override the Configure method to both create the kernel and set-up default bindings

protected override void Configure()
{
   kernel = new StandardKernel();

   kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
   kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
}

We’re going to want to have access to the WindowManager and EventAggregator within our code, so we’ll set up the bindings for them. If we’re passing a class to the generic argument of the Bootstrapper this this is enough code for the Configure method, but if, as I often prefer, we have something like

public class AppBootstrapper : Bootstrapper<IShellViewModel>

i.e. an interface passed as the generic argument, then we need to also set up the bindings within Ninject to resolve this interface. Hence adding the line

kernel.Bind<IShellViewModel>().To<ShellViewModel>().InSingletonScope();

to the end of the Configure method.

OnExit

Now we’ve created the instance of the kernel, the OnExit method allows us to place cleanup code such as

protected override void OnExit(object sender, EventArgs e)
{
   kernel.Dispose();
   base.OnExit(sender, e);
}

This is (as you can see from the arguments, a event handler that Caliburn Micro hooks up to the Application.Exit event.

GetInstance

This must be overridden when providing our own IoC container. The method is used get the service for a given service, so we can simply call the following

protected override object GetInstance(Type service, string key)
{
   if (service == null)
      throw new ArgumentNullException("service");

   return kernel.Get(service);
}

GetAllInstances

This method must be overridden when supplying our own IoC container and is used to get all instances of a service. We can override it thus

protected override IEnumerable<object> GetAllInstances(Type service)
{
   return kernel.GetAll(service);
}

BuildUp

Finally, and again required when supplying our own IoC container, we need to override the BuildUp method. This is used inject instances into the IoC container and can be written as

protected override void BuildUp(object instance)
{
   kernel.Inject(instance);
}

Full Code

The full code for this is as follows

public class AppBootstrapper : Bootstrapper<ShellViewModel>
{
   private IKernel kernel;

   protected override void Configure()
   {
      kernel = new StandardKernel();

      kernel.Bind<IWindowManager>().To<MetroWindowManager>().InSingletonScope();
      kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();

      kernel.Bind<IShellViewModel>().To<ShellViewModel>().InSingletonScope();
   }

   protected override void OnExit(object sender, EventArgs e)
   {
      kernel.Dispose();
      base.OnExit(sender, e);
   }

   protected override object GetInstance(Type service, string key)
   {
      if (service == null)
         throw new ArgumentNullException("service");
			
      return kernel.Get(service);
   }

   protected override IEnumerable<object> GetAllInstances(Type service)
   {
      return kernel.GetAll(service);
   }

   protected override void BuildUp(object instance)
   {
      kernel.Inject(instance);
   }
}

NInject ChildKernel

I’ve been working on an application which is basically a glorified scheduler. Within it I have the concept of projects which are made up triggers, tasks etc. So we have a parent child relationship going on between the project and the child elements, the triggers etc.

One problem I came across was that the application holds a StandardKernel (as one might expect) and injects dependencies etc. into the projects, triggers and tasks but I wanted to use the same mechanism to allow me to inject the current instance of a project into the children, i.e. the triggers and tasks could (if they wanted) get access to the parent project instance.

Obviously if I add the project to the application wide kernel, all triggers and tasks would get a project object, but not necessarily the project which acts as their parent (actually it’d probably fail to allow me to resolve to multiple instances of a project anyway). Of course I could pass the instance of the project to each trigger or task at construction or explicitly calling the relevant method/property, but I wanted to reuse the NInject mechanisms so as to keep a standard way of injecting objects into this application.

Enter the ChildKernel. A Ninject extension class available via GitHub.

Using the ChildKernel we can create a new kernel, which (if you like) inherits the bindings from a parent kernel and then we add further bindings specific to it’s use, as per

ChildKernel child = new ChildKernel(kernel);
child.Bind<IProject>().ToMethod(_ => currentProject);

kernel would be our StandardKernel acting as the parent kernel.

Now we simply Get or Inject using this child kernel and if a dependency is not resolved using the child, it is passed to the parent kernel to resolve.

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
}