Rather than spending time doing the "busy work" of creating and connecting your objects, you just tell Ninject which objects depend on which, and it figures out the rest. This is done most easily through the "[Inject]" attribute. (There are other more advanced ways to instruct Ninject to inject dependencies, covered later.)

C#:
class Samurai {
  private 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 Ninject sees the "[Inject]" attribute on a type's constructor, it tries to resolve a value for each of the constructor's arguments. But wait a second... IWeapon is an interface. You can't create an instance of an interface itself, so how does Ninject know what implementation of IWeapon to inject?

This is accomplished through type bindings. A type binding (or just binding) is a mapping between a service type (generally an interface or abstract class), and an implementation type. Bindings are typically expressed via Ninject's fluent interface. For example, to arm our Samurai with a Sword, we could declare the following binding:

C#:
Bind<IWeapon>().To<Sword>();

VB.NET:
Bind(Of IWeapon).To(Of Sword)()

Or, if you prefer, there's a version without generics, which can be useful for automating:

C#:
Bind(typeof(IWeapon)).To(typeof(Sword));

VB.NET:
Bind(GetType(IWeapon)).To(GetType(Sword))

This means that whenever Ninject encounters a dependency on IWeapon, it will resolve an instance of Sword and inject it. This dependency resolution process is a recursive one; that is, if Sword has any dependencies of its own, they will also be resolved before the Samurai's constructor is called. (Also, if the Sword's dependencies have dependencies as well, they will be resolved in turn, and so on.) In this way, Ninject can wire up an entire graph of objects for you, with minimal work on your end. You just need to set up the path, and Ninject will follow it.

This idea of type bindings is common in dependency injectors. However, most of the existing frameworks rely on XML mapping files to set up the bindings between types. Through its fluent interface, Ninject allows you to take advantage of the features of your language (like type-safety) and your IDE (like IntelliSense and code completion).

There are other kinds of bindings too. Some of them are more advanced, and will be covered later. Of note is a self-binding. You can use the same type as both the service and the implementation. For example, the following line binds the Samurai type to itself:

C#:
Bind<Samurai>().ToSelf();

VB.NET:
Bind(Of Samurai).ToSelf()

Bear in mind that only concrete types can be self-bound; abstract types and interfaces won't work. Also, if you request an instance of a type that can be self-bound, and there are no bindings defined for the type, Ninject will automatically create an implicit self-binding. It's up to you whether you want to define your bindings explicitly, or let Ninject figure it out.

You can also have multiple bindings for one service type, controlled by conditions that examine the context in which the instance is being resolved. This is the contextual binding system mentioned earlier, and is the key to unlocking the full power of Ninject. Don't worry, it's discussed in excruciating detail later. :-)

Continue reading: Injection Patterns

Last edited Sep 13, 2009 at 3:15 AM by nkohari, version 1

Comments

hbrizuela Apr 11, 2012 at 9:12 PM 
ooops... I guess I should keep reading

hbrizuela Apr 11, 2012 at 9:10 PM 
having Bind<IWeapon>().To<Sword>();
means whenever I instantiate the class samurai my instance will have a weapon of type sword. Am I wrong?
what if I want to create a list or Enumerable of samurai with different kind of weapon.
will I have to do it by hand?

swingsetacid Feb 1, 2010 at 10:15 PM 
You should probably keep reading. If you get two more sections ahead, it's all written out in fairly crystal clear detail. Not only will you see the benefits of a container, but it will also let you extrapolate how it would save you *tons* of effort in a more complex scenario.

jsmorris Dec 12, 2009 at 4:28 AM 
It is hard to appreciate what an IoC "saves" until you need to construct an object that contains many dependencies that contain dependencies, which also contain dependencies and so on and so forth. These are just trivial examples to show the concept of DI via IoC (ninject). You wouldn't want to add the complexity of an IoC, unless you had and architecture that was suited to it: all objects that composed the final object followed the DI pattern.

SittenSpynne Dec 8, 2009 at 11:27 PM 
Perhaps it would be more clear how this saves effort if the example showed how something would instantiate a Samurai instance once the attribute is in place? You have to call a constructor and pass an IWeapon, so what's Ninject doing that's not on display here?

dschobel Dec 8, 2009 at 9:58 PM 
@Vaccanoll See this post on Stacked Overflow which answers your question: http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code . In short, for simple applications you don't gain much, but as the complexity of the application grows, it makes it a lot easier to maintain the wiring of your application and swap out implementations.

Vaccanoll Dec 7, 2009 at 10:38 PM 
Maybe I am just dense, but I am not getting what this saves yet? All the code from the "by hand" method seems to still be needed and the Samurai class is the same except it has the [Inject] tag.

Though I do get that this is better than other models due to it not needing XML.... But what do we gain over doing it by hand?