-
Notifications
You must be signed in to change notification settings - Fork 529
Why Use Ninject
Once you break your application into components, you have to glue them back together. IoC containers solve this problem. Rather than writing the wiring code by hand or depending on a bunch of XML to describe how the pieces fit together, Ninject uses a powerful fluent interface. This lets you get the most out of the sharpest tools in your arsenal: your compiler and your IDE.
Ninject v1 wasn’t the first .NET Dependency Injection container to the party. Ninject 2 wasn’t completely backward compatible with v1. Why did we bother to make another one?
First, a number of other frameworks rely on XML configuration files to instruct the framework on how to wire up the components of your application. This has at least the following disadvantages:
- Your configuration is more complex and verbose; you often have to trot out the assembly-qualified name for each of your types etc.
- It’s much easier to break your application through a simple typing mistake.
In comparison, Ninject’s default modus operandi is a fluent interface (or if you prefer, an “embedded domain-specific language”) to declare type bindings.
For example, if you want to indicate that whenever your code requests an instance of IService
, that an instance of ServiceImpl
should be returned:
Bind<IService>().To<ServiceImpl>();
Second, many of the other frameworks are rather heavyweight, meaning you need to add several assembly dependencies to your project and/or take dependencies on all sorts of framework assemblies which may or may not be present in your context (think Client Profile etc.). For smaller projects, this can result in “framework bloat”. Ninject aims to keep things simple and straightforward.
Third, Ninject introduces an extremely powerful and flexible form of binding called contextual binding. Rather than bind based on a string identifier, Ninject is aware of its environment, and can alter the implementation for a given service during activation. For example:
Bind<IService>().To<RedImpl>().WhenTargetHas<RedAttribute>();
Bind<IService>().To<BlueImpl>().WhenTargetHas<BlueAttribute>();
class ConsumerA
{
public ConsumerA([Red] IService service)
{
// The "service" argument will be an instance of RedImpl.
}
}
class ConsumerB
{
public ConsumerB([Blue] IService service)
{
// The "service" argument will be an instance of BlueImpl.
}
}
Ninject is designed from the ground up to be highly modular. Internally, Ninject 2 and 3 rely on an inversion of control container of its own, reducing factory bloat and making extension of the core much simpler. The core assembly .DLL is in the realm of 100K in size.
Ninject v2 broke backward compatibility with some aspects of v1’s API surface. This decision was not taken lightly. The good news is that a large number of antipatterns and cognitive load resulting from having many different ways to do things simply isn’t present, making it easier to discover things without reading a 200 page manual.
That means you get an API that lands you in the pit of success without looking through massive method lists.
It also means the source is:
- compact and minimal with no random stuff that nobody remembers the reason for anymore
- beautifully consistent
- covered in tests which serve as great examples when the documentation isn’t helping you
- a good example of a modern TDD’d codebase (the tests use xUnit.net)
The current maintainers understand the size of installed base Ninject has and won’t be making any rash choices that’ll leave everyone with a big porting task; they’re careful about what goes into Core and make sure that anything that isn’t demonstrably long-term and core is an extension…
While Nate Kohari wrote and maintained the initial versions for a considerable length of time and the cleanliness of the design is a direct result of the desire, taste and effort of a single mind, he’s had other things on his plate for a long time. There’s currently a vibrant hard working set of maintainers who chase down WCF interaction subtleties, track ASP.NET MVC preview releases, and write powerful extensions. In addition to this, those same maintainers respond quickly on the mailing list and ensure stuff bearing the StackOverflow ninject tag is well-tracked and questions don’t go long unanswered.
In short, there isn’t a single point of failure – and the project is over the hump of moving from a single mind to a set of minds and has survived without the design integrity being lost.
Not to be underestimated is the fact that Ninject can and does take contributions (via github pull requests), and latest/‘nightly’ binaries are always available from the build server
Ninject today supports Silverlight, Mono, WP7.5 etc., and had .NET 4.0 specific builds early on. Similarly good integration with ASP.NET MVC 3 happened quickly. There is already a WinRT preview. While one should never take wild claims written on wikis at face value, it’s nice that your DI framework doesn’t inhibit you from porting code.
With extensions comes great power…
- ninject.web.mvc
- ninject.extensions.interception
- ninject.extensions.wcf
- ninject.extensions.logging
- ninject.extensions.conventions
- ninject.extensions.xml
- ninject.extensions.messagebroker
- ninject.extensions.weakeventmessagebroker
- ninject.mockingkernel
If Ninject can’t do something you need, chances are it can be extended to do so.
Continue reading: Getting Started
Licensed under Apache 2 License
Contents
- Home
- Why Use Ninject
- Getting Started
- Dependency Injection By Hand
- Dependency Injection With Ninject
- Injection Patterns
- Multi Injection
- Object Scopes
- Modules and the Kernel
- Providers, Factory Methods and the Activation Context
- The Activation Process
- How Injection Works
- Contextual Binding
- Conventions-Based Binding