Is Kernel.Get<T>() threadsafe + good pattern to share the kernel among components
Asked Answered
J

2

10

Is Kernel.Get() threadsafe? My goal is share an instance of my kernel among all my componenets and they may all very well call Kernel.Get() at the same time on different threads.

Is Kernel.Get() thread safe?

What is the best pattern to share the application kernel among all application components which are sitting in different dll's? I prefer not to pass an instance of a factory to every component of my application if this makes sense.

Joaniejoann answered 14/6, 2011 at 2:55 Comment(0)
C
15

Get is threadsafe but creating new kernel instances (ctor) is currently not threadsafe.

Generally you should try to minimize your access to the kernel to an absolute minimum. Accessing the kernel form everywhere is a very bad design and makes your code much less reusable. See Service Locator Antipattern

The only situations where you access the kernel should be:

  • Once in the composite root of the application (e.g. Program.Main, App.xaml, MVC Controller creation)
  • Inside a factory if you don't know how many instances you need when the composite root is created
  • Inside a factory if you don't know which implementation is required when the composite root is created
  • Inside a factory if you need to create a component late due to memory/resource constraints.

In all cases limit the access to the kernel to the composite root and inject factories (class or Func<T>) to the classes where you need to create objects during runtime. The best way to give those factories access to the kernel is still constructor injection even if you do not prefer doing so. Or use Func<T> ( Does Ninject support Func (auto generated factory)? ).

Classified answered 14/6, 2011 at 15:56 Comment(2)
Thank for you answer. My code base is composed of several agents/components where I want each of my agents to have an independent instance of the service. Does this also apply to access the kernel.get method inside the passed around factory? Is there a better way to allow the many compoenets of your application to acquire an independent intance of the service through the IoC? Also, Would you please elaborate more on the Func<T> approach? Maybe a code sample of how to use it and what is the added value?Joaniejoann
@RemoGloor: Can you please explain how can the kernel be injected to the factories? I am confused, because we need Kernel to resolve dependencies, but then how is the kernel being injected itself?Grinder
D
2

Yes, it is thread safe; The primary app I work on has a single kernel that serves a large SAAS app. So it gets pounded and it does just fine. We also have a multi-threaded page generator test suite that exposed a thread issue in Ninject last fall, but has been fixed and has been fine since then. So I know for sure that it's ok.

There are lots of different patterns for exposing the kernel. We use a ServiceLocator pattern (basically a static container for the container.)

For the different dll's. We have a NinjectModule in each dll that does it's own bindings and then the app does a assembly scan for NinjectModules at startup when it sets of the ServiceLocator.

Dunne answered 14/6, 2011 at 11:58 Comment(2)
Would you please elaborate more on "For the different dll's. We have a NinjectModule in each dll that does it's own bindings and then the app does a assembly scan for NinjectModules at startup when it sets of the ServiceLocator."?Joaniejoann
The StandardKernel has a load method that takes a assembly name or array of names. It then scans each of those assemblies for public NinjectModule classes. see the test AssemblyScanningByFileName at github.com/ryber/Ninject-Examples/blob/master/src/…Dunne

© 2022 - 2024 — McMap. All rights reserved.