2011-06-14 13 views
9

¿Kernel.Get() threadsafe? Mi objetivo es compartir una instancia de mi kernel entre todos mis componentes y todos muy bien pueden llamar a Kernel.Get() al mismo tiempo en diferentes subprocesos.Es Kernel.Get <T>() threadsafe + good pattern para compartir el núcleo entre los componentes

¿El subproceso Kernel.Get() es seguro?

¿Cuál es el mejor patrón para compartir el núcleo de la aplicación entre todos los componentes de la aplicación que están ubicados en diferentes dll? Prefiero no pasar una instancia de una fábrica a cada componente de mi aplicación si tiene sentido.

Respuesta

14

Obtener es seguro para la creación de hilos, pero la creación de nuevas instancias del núcleo (ctor) no es en la actualidad inseguro.

Por lo general, debe intentar minimizar su acceso al kernel a un mínimo absoluto. Acceder al formulario kernel en todas partes es un diseño muy malo y hace que su código sea mucho menos reutilizable. Ver Service Locator Antipattern

Las únicas situaciones en las que accede el núcleo debe ser:

  • Una vez en la raíz compuesta de la aplicación (por ejemplo Program.Main, App.xaml, la creación MVC Controller)
  • Dentro de una fábrica si no sabe cuántas instancias necesita cuando se crea la raíz compuesta
  • Dentro de una fábrica si no sabe qué implementación es necesaria cuando se crea la raíz compuesta.
  • Dentro de una fábrica si necesita crear un compuesto con retraso debido a restricciones de memoria/recursos.

En todos los casos limitar el acceso al núcleo de la raíz compuesta e inyectar fábricas (clase o Func<T>) a las clases en las que necesita para crear objetos en tiempo de ejecución. La mejor manera de dar acceso a esas fábricas al kernel sigue siendo la inyección de constructores, incluso si no lo prefiere. O use Func<T> (Does Ninject support Func (auto generated factory)?).

+0

Gracias por su respuesta. Mi base de código está compuesta de varios agentes/componentes donde deseo que cada uno de mis agentes tenga una instancia independiente del servicio. ¿Esto también se aplica para acceder al método kernel.get dentro de la fábrica pasada?¿Hay una mejor manera de permitir que los muchos componentes de su aplicación adquieran una integridad independiente del servicio a través del IoC? Además, ¿podría elaborar más sobre el enfoque Func ? ¿Tal vez una muestra de código de cómo usarlo y cuál es el valor agregado? – iCode

2

Sí, es seguro para subprocesos; La aplicación principal en la que trabajo tiene un kernel único que sirve una gran aplicación SAAS. Entonces se golpea y funciona bien. También tenemos un conjunto de prueba de generador de páginas de subprocesos múltiples que expuso un problema de subprocesos en Ninject el otoño pasado, pero se ha solucionado y ha estado bien desde entonces. Así que estoy seguro de que está bien.

Hay muchos patrones diferentes para exponer el kernel. Usamos un patrón de ServiceLocator (básicamente un contenedor estático para el contenedor).

Para las diferentes dll. Tenemos un NinjectModule en cada dll que hace sus propios enlaces y luego la aplicación hace un escaneo de ensamblaje para NinjectModules al inicio cuando establece el ServiceLocator.

+0

¿Podrían detallar más sobre "Para los diferentes dll. Tenemos un NinjectModule en cada dll que hace sus propios enlaces y luego la aplicación hace un escaneo de ensamblaje para NinjectModules al inicio cuando configura el ServiceLocator"? – iCode

+0

El StandardKernel tiene un método de carga que toma un nombre de conjunto o una matriz de nombres. Luego escanea cada una de esas asambleas para clases públicas de NinjectModule. vea la prueba AssemblyScanningByFileName en https://github.com/ryber/Ninject-Examples/blob/master/src/Chapter_01_Kernel_Registration.cs – ryber

Cuestiones relacionadas