views:

567

answers:

2

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.

+2  A: 

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
Mauricio Scheffer
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
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
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
That's a whole other question... post a new question with that issue specifically.
Mauricio Scheffer
New post is here: http://stackoverflow.com/questions/591362/implementing-onepersessionbehavior-in-ninject
JC Grubbs
+7  A: 

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
That sounds like exactly what I want...can you post some code for this?
JC Grubbs
@Nate: not entirely related, but do you have any ETA on the CommonServiceLocator adapter? I see there's an adapter on the experiments branch for ninject2...
Mauricio Scheffer