Ninject supports four patterns for injection, which are listed here. All injections are controlled by the "[Inject]" attribute. Each kind of injection has its own benefits and detriments, and you may find each to be useful in different circumstances.

Note! You will need to add a reference to Ninject.Core.dll to your project as well as add using/import Ninject.Core in your source to build the following examples.

Constructor Injection

The first (and arguably best) type is constructor injection. When activating an instance of a type, if the type has a constructor with an "[Inject]" attribute, Ninject will try to activate an object for each of the constructor's parameters.

C#:
class Samurai {
  private readonly IWeapon _weapon;

  [Inject]
  public Samurai(IWeapon weapon) {
    _weapon = weapon;
  }

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

VB.NET:
Public Class Samurai
  Private ReadOnly _sword As IWeapon

  <Inject()> _
  Public Sub New(ByVal weapon As IWeapon)
    _sword = weapon
  End Sub

  Public Sub Attack(ByVal target As String)
    _sword.Hit(target)
  End Sub
End Class

When in doubt, use constructor injection, because it lets you inject multiple dependencies at once, and add the readonly keyword to the fields that hold the injected values. (Using readonly is a matter of taste, and is entirely up to you. Ninject doesn't mind either way.)

An important note! You can only have one constructor of your type marked with an "[Inject]" attribute. If you put an "[Inject]" attribute on more than one constructor, Ninject will throw a NotSupportedException the first time an instance of the type is requested.

You also have the option to leave off the "[Inject]" attribute completely. This can help if you don't have access to the source code of a class, but you still want to inject dependencies into it. Here's the logic Ninject follows to choose which constructor to call, if none have an "[Inject]" attribute:
  1. If the type only has a single constructor, Ninject will call it.
  2. If the type has more than one constructor, but has a default (parameterless) constructor available, Ninject will call it. (This also applies to types that have no explicit constructors defined.)

Property Injection

Here's an example of our same Samurai class using property injection. Unlike constructor injection, you can have multiple properties decorated with an "[Inject]" attribute.

Be careful! The order of property injection is not deterministic, meaning there is no way to tell in which order Ninject will inject their values in. (However, you can also request notification when all injections are complete by implementing either the the IInitializable or the IStartable interface, discussed later.)

C#:
class Samurai {
  private IWeapon _weapon;

  [Inject]
  public IWeapon Weapon {
    get { return _weapon; }
    set { _weapon = value; }
  }

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

VB.NET:
Public Class Samurai
  Private  _sword As IWeapon

  <Inject()> _
   Public Property Weapon() As IWeapon
      Get
          Return _sword
      End Get
      Set(ByVal Value As IWeapon)
          _sword = Value
      End Set
  End Property

  Public Sub Attack(ByVal target As String)
    _sword.Hit(target)
  End Sub
End Class

Method Injection

Here's method injection. As with constructor injection, you can also inject multiple values at once via the same method. You can also have multiple methods decorated with the "[Inject]" attribute. They will all be called, but as with property injection, there is no guarantee on which order they will receive their injections.

C#:
class Samurai {
  private IWeapon _weapon;

  [Inject]
  public void Arm(IWeapon weapon) {
    _weapon = weapon;
  }

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

VB.NET:
Public Class Samurai
  Private  _sword As IWeapon

  <Inject()> _
  Private Sub Arm(ByVal weapon As IWeapon)
    _sword = weapon
  End Sub
  Public Sub Attack(ByVal target As String)
    _sword.Hit(target)
  End Sub
End Class

Field Injection

And finally, here's field injection. Same rules apply: multiple fields can have "[Inject]" attributes, but the order of their injections is not deterministic.

C#:
class Samurai {
  [Inject] private IWeapon _weapon;

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

VB.NET:
Public Class Samurai
  <Inject()> Private _sword As IWeapon
  Public Sub Attack(ByVal target As String)
     _sword.Hit(target)
  End Sub

End Class

Although its simplicity is tempting, you should generally try to avoid using field injection, since the value can then only be set via Ninject. This makes unit testing much more complex, since sometimes it's easiest to use dependency injection by hand to inject mock objects into your unit tests. (Unit testing with Ninject is covered in more depth later.)

Continue reading: Activation Behaviors

Last edited Sep 13, 2009 at 2:19 AM by nkohari, version 1

Comments

skrzeczowas Jun 5, 2012 at 9:32 AM 
Hi,
If one leave off InjectAttribute, then:

3. If the type has more than one constructor, and has no default (parameterless) constructor available, Ninject will call first ctor that even partially matches. For example we have test code:

using (IKernel kernel = new StandardKernel()) {
kernel.Bind<ITaxCalculator>().To<TaxCalculator>().WithConstructorArgument("rate", .2M);
var sale3 = kernel.Get<Sale3>();

Assert.IsNotNull(sale3);
}

And class to test:

public class Sale3 {

private ITaxCalculator _taxCalculator;

public Sale3(ITaxCalculator taxCalculator) {
_taxCalculator = taxCalculator;
}

public Sale3(ITaxCalculator taxCalc, int testInteger) {
_taxCalculator = taxCalc;
}
}

In this case test will be run successfully. If we reorder constructors that the one with integer as input parameter will be first, test will fail.

So I believe that under the hood Ninject searches for first constructor that accepts desired Interface as an input paramter and then invokes this ctor.

Am I correct?