-
Notifications
You must be signed in to change notification settings - Fork 530
Changes in Ninject 2
Ninject 2 represents a ground-up rewrite of the original Ninject, created to take advantage of new language features and re-dedicate the project to obsessive minimization and simplicity.
- Cache-and-collect lifecycle management: Rather than using binding behaviors, Ninject 2 uses a scoping system and leverages the garbage collector to reclaim instances. (This is explained in detail below.)
-
Multi-injection: The kernel in Ninject 2 now has
GetAll<T>()
methods, and supports injection of multiple targets with typesIEnumerable<T>
,List<T>
, and arrays ofT
. - Constrained resolution: Rather than just declaring conditional bindings, constraining predicates can now flow into a resolution request from the point of injection.
- Common Service Locator support: Because of multi-injection, Ninject 2 now has full support for the Common Service Locator.
- Optional modules: You can now register bindings directly on the kernel; modules are optional. If you register bindings in a module, and then unload the module, the bindings will be un-registered.
- Automatic module scanning: Ninject 2 can scan directories for assemblies that contain modules, and load them into the kernel.
- Simplified extension model: Internally, Ninject 2 relies on an inversion of control container of its own, reducing factory bloat and making extension of the core much simpler.
- Mono support: Ninject 2 finally has proper support for the Mono project’s version of the CLR.
- Support for .NET 2.0: Since Ninject 2 relies on LINQ, .NET 2.0 support is now no longer possible.
- Field injection: This is a bad practice, and has been cut for minimization.
-
Behavior attributes: Since behaviors have been cut and replaced by the new cache-and-collect system, attributes like
[Singleton]
no longer make sense.
Some things have been moved from the core to extensions as well, including aspect-oriented programming support (interception) and logging.
The structure of instance re-use has been completely revamped in Ninject 2, which now allows any POCO to become a scoping object. This is explained in further detail on Nate’s blog. The details aren’t particularly important; all you need to know is that the syntax for defining lifecycle is a little different:
Lifecycle | Ninject 1 | Ninject 2 |
---|---|---|
Transient | Bind<A>().To<B>().Using<TransientBehavior>() |
Bind<A>().To<B>().InTransientScope() |
Singleton | Bind<A>().To<B>().Using<SingletonBehavior>() |
Bind<A>().To<B>().InSingletonScope() |
One-Per-Thread | Bind<A>().To<B>().Using<OnePerThreadBehavior>() |
Bind<A>().To<B>().InThreadScope() |
One-Per-Request | Bind<A>().To<B>().Using<OnePerRequestBehavior>() |
Bind<A>().To<B>().InRequestScope() |
One caveat: Since this system relies on the garbage collector to deactivate and release activated instances, this can cause memory bloat in some scenarios, particularly for request-bound instances. Because of this, there is a built-in OnePerRequestModule
, an HTTP module that you can load into your ASP.NET application which will deterministically collect cached instances synchronously during the teardown phase of the relevant request processing lifecycle (this is excluded in builds with NO_WEB #defined). The Ninject.Web extension automatically hooks this in for you. There’s work in progress to extend this capability to custom scopes such as (in WCF) InScope( ()=> OperationContext.Current)
, i.e., any context where the OnePerRequestModule
automatic HttpContext.Current
-scoped cleanup will not be sufficient.
- If a constructor has an
[Inject]
attribute, it is used. If multiple constructors have an[Inject]
attribute, Ninject will throw aNotSupportedException
. - If no constructors have an
[Inject]
attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve. - If no constructors are defined, Ninject will select the default parameterless constructor.
-
IModule
has been replaced withINinjectModule
-
StandardModule
has been replaced withNinjectModule
- There is no more
InlineModule
, you can bind directly against the kernel. - The
Ninject.Core
namespace no longer exists. -
Get<T>
calls are now implemented as extension methods. - Extensions are now broken out into their own projects rather than bundled into the core.
- If the kernel has more than one binding for a type and is being asked to inject just one (not an array) a
ActivationException
will be thrown. Previously the kernel would return the first binding that satisfied the requirement.
Go back to the Home page or the Table of Contents
Continue reading: Why Use Ninject?
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