48

I'm using NInject on a new web application and there are two things that are unclear to me:

  1. Don't I need to keep a reference to the Kernel around (Session/App variable) to insure that GC doesn't collect all my instances? For example, if I specify .Using() and then the Kernel object gets collected, aren't all my "singletons" collected as well?

  2. If I do need keep a reference to a Kernel object around, how do I allow the arguments passed in to WithArguments() to change or is that not possible.

Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
JC Grubbs
  • 39,191
  • 28
  • 66
  • 75

3 Answers3

29

It's true that you don't want to pass around the kernel. Typically, in a web app, I store the kernel in a static property in the HttpApplication. If you need a reference to the kernel, you can just expose a dependency (via constructor argument or property) that is of the type IKernel, and Ninject will give you a reference to the kernel that activated the type.

If you use WithArguments() on a binding, they will be used for all activations. If you use IParameters, they will only be used for that activation. (However, if the service you're activating has a re-usable behavior like Singleton, it won't be re-activated even if you pass different IParameters.)

Nate Kohari
  • 2,216
  • 17
  • 13
16

This is a common pitfall when starting to use a IoC container. See this related question.

In a nutshell:

  • It's bad practice to pass your container around (been there, done that, and it really hurts)
  • If you really need to invocate directly the container, first consider abstracting to an injected factory, then as a last resource consider using a static gateway to the container
Community
  • 1
  • 1
Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
  • I agree I don't want to pass the container around, but could I stash it in an Application variable for instance? My problem is that every time I do new StandardKernel(new CustomModule()) I get new instances of everything. – JC Grubbs Feb 26 '09 at 15:26
  • You only need one StandardKernel per app. If you need to load multiple modules just call kernel.Load(new MyModule()); kernel.Load(new AnotherModule()); etc – Mauricio Scheffer Feb 26 '09 at 15:49
  • Ok, so that makes sense. What I need to do is change the arguments in WithArguments() each time I ask for a type...is there any way to do this? Ultimately what I'm trying to do is implement a OnePerSessionBehavior and I want the binding to inject current arguments for each session. – JC Grubbs Feb 26 '09 at 16:04
  • That's a whole other question... post a new question with that issue specifically. – Mauricio Scheffer Feb 26 '09 at 16:14
  • New post is here: http://stackoverflow.com/questions/591362/implementing-onepersessionbehavior-in-ninject – JC Grubbs Feb 26 '09 at 16:42
-4

Mark Seeman -- author of Manning Dependency Injection Suggust to Use Hollywood principle Don't call us(IOC framework) instead We will call you ... .. The IOC container should be placed in the Application's Composition root.. and it needs to instantiated as requested.. like wat nate mentioned

.. For the Web Application the Composition root is Global.asax file where the u can use the override the startup events and There u can bind your Ninject to resolve the component

satish
  • 2,425
  • 3
  • 23
  • 40
  • -1, mainly because the answer is phrased in such a fuzzy and vague way. Also, the part that says _"it needs to [be] instantiated as requested"_ can mean really anything and is not helpful as a guideline at all. That being said, I would certainly support what's said about the "Hollywood principle" and the composition root being the only thing that should be retrieved directly from the DI container. – stakx - no longer contributing Apr 07 '11 at 03:53
  • This answer doesn't help, as it's only repeating the contents of the link. You haven't said what the Composition Root should be, so you can just cross out the words 'IOC Container' and write 'Composition Root' and it be the same question... – Tom W Apr 21 '11 at 16:34