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