How to store Ninject Kernel in an ASP.NET Application?
Asked Answered
A

1

2

I'm really confused about small, partial, one-file examples where there's a Ninject kernel everywhere without showing how to really get to that kernel in the application.

(1) Should we instantiate one Kernel and keep it in "static" context? Or should we instantiate a different one on every request (*in Application_BeginRequest*)

(2) If it is "kernel per request", then why Initialize() method of the NinjectWebCommon.cs (gets when you install the NuGet package) is called on Application_Start since it calls bootstrapper.Initialize(CreateKernel) - NinjectWebCommon.cs

(3) If it is "one global static kernel" then the "InRequestScope()" doesn't work. It executes the following code and that returns null because at ApplicationStart() time there's no request.

kernel.Components.GetAll<INinjectHttpApplicationPlugin>()
  .Select(c => c.RequestScope)
  .FirstOrDefault(s => s != null);

(4) Again, if it is "kernel per request", where will we save the kernel? HttpContext.Current? Then what is meaning of using InRequestScope() if I'm going to use HttpContext.Current anyway?

Adamec answered 29/7, 2013 at 8:30 Comment(6)
Can you include some detail as to why you don't like the Ninject.MVC3 Package's code spit? What's not working? What ahve you tried? (It's likely to be a different question when you do, so asking a new question might be the best thing to do)Amble
I have a ModelView class, and in ModelBase class I do kernel.Inject(this) where kernel is a global static object, and InRequestScope() doesn't work, it initializes every class again in the same request.Adamec
I've did it all over step by step from the controller to model, and right now it works, only one instance, very weird.Adamec
Firstly, you should not be injecting models (yes, trust me, go look there are lots of Q&As covering that). If you were as a hack, you'd still use Ninject.MVC3 and use it to store a ref the single kernel after Initialize. You def dont want to get into 2 kernels or 2 sets of registrations or you'll get lots of confusion for lots of reasonsAmble
Okay now this is a little bit different than the original question, however if I shouldn't be injecting into models and should inject into the controller, how am I going to achieve "thin controller, thick model" methodology. I even have Repositories, like UserRepo to manipulate users. So should I pass the dependency like this: Controller -> Model -> UserRepo, it seems like lots of effort.Adamec
As you say - an entirely separate discussion - not appropriate for a comment stream here - there is no short answer and you should research that as a separate matter, sorry!Amble
C
6

(1) Should we instantiate one Kernel and keep it in "static" context? Or should we instantiate a different one on every request (*in Application_BeginRequest*)

One and single kernel.

(2) If it is "kernel per request", then why Initialize() method of the NinjectWebCommon.cs (gets when you install the NuGet package) is called on Application_Start since it calls bootstrapper.Initialize(CreateKernel) - NinjectWebCommon.cs

It isn't kernel per request.

(3) If it is "one global static kernel" then the "InRequestScope()" doesn't work. It executes the following code and that returns null because at ApplicationStart() time there's no request.

kernel.Components.GetAll() .Select(c => c.RequestScope) .FirstOrDefault(s => s != null);

That's perfectly normal. You cannot expect to get an instance from your kernel which you explicitly registered with InRequestScope outside of an HTTP Request.

(4) Again, if it is "kernel per request", where will we save the kernel? HttpContext.Current? Then what is meaning of using InRequestScope() if I'm going to use HttpContext.Current anyway?

Nowhere. You DON'T SAVE THE KERNEL. You use the kernel to configure your DI container only once at your application startup and then all dependencies are automatically injected. If you need the kernel somewhere in your application, other than the place where you configured your dependencies you have a serious design problem because you are no longer using Dependency Injection but Service Location which is an anti-pattern.

Coincidental answered 29/7, 2013 at 8:40 Comment(4)
So how to use InRequestScope()? See: img407.imageshack.us/img407/1325/gt17.jpgAdamec
You use InRequestScope when registering some dependency in your DI container which you want to be resolved at each HTTP request. For example your controller action could take some dependency that is not Singleton but is injected a different instance on each request. It will all depend on what you need and what you are trying to achieve.Coincidental
:) Yes, and it doesn't work. That's exactly what I'm trying to do, please check my this comment under the question post: #17919814Adamec
I've did it all over step by step from the controller to model, and right now it works, only one instance, very weird. Thanks for the answers btw Darin, I've got my head more clear about it.Adamec

© 2022 - 2024 — McMap. All rights reserved.