-
Notifications
You must be signed in to change notification settings - Fork 529
Changes in Ninject 2
Ninject 2 represented 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.
Version 3 implements a more generalised version of this capability which is leveraged by custom scopes such as (in WCF where one is not integrating into the HttpContext pipeline) InScope( ()=> OperationContext.Current)
, i.e., any context where the OnePerRequestModule
automatic HttpContext.Current
-scoped cleanup will not be sufficient.**
In the original v2 release, OnePerRequestModule
is hooked in by the Core code in Ninject.dll automatically (this is excluded in builds with NO_WEB #defined).
In the original v2 release, OnePerRequestModule
is hooked in as long as you Kernel.Load
the Ninject.Web extension.
- 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 has registrations for (or throw if there isn’t a single on satisfying that criteria). - If no constructors are defined, Ninject will select the default public 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:http://msdn.microsoft.com/en-us/library/system.linq.enumerable.first.aspx 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