This project is read-only.
Quite a bit of magic happens inside of Ninject when you call the kernel's Get() method. Here's a rough sketch of the procedure:
  1. The binding of the type is resolved.
  2. The binding is used to create an activation plan, which describes the means by which the instance will be created and injected.
  3. An instance of the type is requested from the behavior defined in the activation plan. Depending on the behavior's implementation, the behavior may simply return an existing instance of the type, in which case the rest of the activation process is not executed.
  4. If the behavior indicates that a new instance of the type is necessary, it is requested from the binding's provider. The provider resolves any necessary arguments and calls the injection constructor.
  5. All properties are injected according to the activation plan.
  6. All methods are injected according to the activation plan.
  7. All fields are injected according to the activation plan.
  8. If the type implements the IInitializable interface, its Initialize() method is called.
  9. If the type implements the IStartable interface, its Start() method is called.

This entire activation procedure can also be customized by altering the strategy chain used by the Activator kernel component. (More on customizations later.)

Returning to our earlier example, we had a WarriorModule:

C#:
class WarriorModule : StandardModule {
  public override Load() {
    Bind<IWeapon>().To<Sword>();
    Bind<Samurai>().ToSelf();
  }
}

VB.NET:
Public Class WarriorModule
  Inherits StandardModule

  Public Overrides Sub Load()
      Bind(Of IWeapon).To(Of Sword)()
      Bind(Of Samurai).ToSelf()
  End Sub
End Class

And we activated an instance of Samurai like this:

C#:
class Program {
  public static void Main() {
    IKernel kernel = new StandardKernel(new WarriorModule());
    Samurai warrior = kernel.Get<Samurai>();
    warrior.Attack("the evildoers");
  }
}

VB.NET:
Module Module1
  Sub Main()
    Dim kernel As IKernel = New StandardKernel(New WarriorModule())
    Dim warrior As Samurai = kernel.Get(Of Samurai)()
    warrior.Attack("evil doers")
  End Sub
End Module

The activation process for the Samurai type is as follows. The number to the left indicates the depth at which the activation is occurring, and some steps have been left out for clarity:
  • (1) The kernel resolves the self-binding for the Samurai type that was defined in the WarriorModule.
  • (1) The kernel asks the Samurai's TransientBehavior to resolve an instance.
  • (1) The Samurai's TransientBehavior asks the binding's provider to create a new instance.
  • (2) The Samurai's StandardProvider asks the kernel to resolve an instance of IWeapon.
  • (2) The kernel resolves the binding from IWeapon to Sword that was defined in the WarriorModule.
  • (2) The kernel asks the Sword's TransientBehavior to resolve an instance.
  • (2) The Sword's TransientBehavior asks the binding's provider to create a new instance.
  • (2) The Sword's StandardProvider calls the Sword's parameterless constructor.
  • (2) The kernel returns the newly-created instance of Sword.
  • (1) The Samurai's StandardProvider calls the Samurai's injection constructor, passing it the instance of Sword as an argument.
  • (1) The kernel returns the newly-created instance of Samurai to the site of the method call in Main().

Whew! After all that, we end up with a Samurai armed with a Sword, and the call to its Attack() method results in the same output as our original example: Chopped the evildoers clean in half. Although this might look like a lot of work just to get the same outcome, keep a few things in mind:
  1. All of this happens in the background, and you rarely have to think about what's really happening. It Just Works.
  2. It actually adds much less overhead than it seems. Honest. :)
  3. This is an overly simplistic example. The more complex your application becomes, the more the power of Ninject will appear.

Continue reading: How Injection Works

Last edited Oct 12, 2009 at 4:26 PM by NotMyself, version 2

Comments

No comments yet.