48

estoy usando ninject en una nueva aplicación web y hay dos cosas que no están claras para mí:NInject: ¿Dónde guarda su referencia al Kernel?

  1. ¿No necesito mantener una referencia al núcleo alrededor (Sesión/variable de la aplicación) a asegurarme de que GC no recopile todas mis instancias? Por ejemplo, si especifico .Using() y luego se recopila el objeto Kernel, ¿no se recogen también todos mis "singletons"?

  2. Si necesito mantener una referencia a un objeto Kernel alrededor, ¿cómo puedo permitir que los argumentos pasados ​​a WithArguments() cambien o no es posible?

Respuesta

15

Esto es una trampa común al comenzar a usar un contenedor de IoC. Ver this related question.

En pocas palabras:

  • Es una mala práctica para aprobar el recipiente alrededor (estado allí, hecho eso, y me duele mucho)
  • Si realmente necesita invocate directamente del contenedor, en primer lugar considerar la abstracción a una fábrica inyectada, luego como último recurso considere utilizar una puerta de enlace estática al contenedor
+0

Acepto que no quiero pasar el contenedor, pero ¿podría esconderlo en una variable de aplicación, por ejemplo? Mi problema es que cada vez que hago un nuevo StandardKernel (nuevo CustomModule()) obtengo nuevas instancias de todo. –

+0

Solo necesita un StandardKernel por aplicación. Si necesita cargar múltiples módulos, simplemente llame a kernel.Load (new MyModule()); kernel.Load (new AnotherModule()); etc. –

+0

Ok, entonces eso tiene sentido. Lo que tengo que hacer es cambiar los argumentos en WithArguments() cada vez que pido un tipo ... ¿hay alguna manera de hacer esto? En última instancia, lo que intento hacer es implementar un OnePerSessionBehavior y quiero que el enlace inyecte los argumentos actuales para cada sesión. –

29

Es cierto que no desea pasar el kernel. Normalmente, en una aplicación web, almaceno el kernel en una propiedad estática en HttpApplication. Si necesita una referencia al núcleo, puede exponer una dependencia (a través del argumento o propiedad del constructor) que sea del tipo IKernel, y Ninject le dará una referencia al kernel que activó el tipo.

Si usa WithArguments() en un enlace, se usarán para todas las activaciones. Si usa IParameters, solo se usarán para esa activación. (Sin embargo, si el servicio que está activando tiene un comportamiento reutilizable como Singleton, no se volverá a activar incluso si pasa diferentes parámetros de IPara)

+0

Eso suena exactamente a lo que quiero ... ¿puedes publicar algún código para esto? –

+0

@Nate: no del todo relacionado, pero ¿tiene alguna ETA en el adaptador CommonServiceLocator?Veo que hay un adaptador en la rama de experimentos para ninject2 ... –

+0

Hola @Nate, ¿puedes publicar el código fuente? –

-4

Mark Seeman - autor de Manning Dependency Injection Suggust to Use Principio de Hollywood No nos llame (marco IOC) en su lugar Le llamaremos ... .. El contenedor IOC debe colocarse en la raíz de composición de la aplicación ... y debe crearse una instancia según lo solicitado ... como wat nate mencionado

.. Para la aplicación web, la raíz de la composición es el archivo Global.asax donde puede usar el comando para anular los eventos de inicio y allí puede enlazar su Ninject para resolver el componente

+0

-1, principalmente porque la respuesta está redactada de manera difusa y vaga. Además, la parte que dice _ "necesita [ser] instanciada como se solicite" _ puede significar realmente cualquier cosa y no es útil como una guía en absoluto. Una vez dicho esto, sin duda apoyaría lo que se dice sobre el "principio de Hollywood" y la raíz de la composición es lo único que se debe recuperar directamente del contenedor DI. – stakx

+0

Esta respuesta no ayuda, ya que solo repite el contenido del enlace. No has dicho lo que debe ser la Raíz de Composición, así que puedes tachar las palabras 'Contenedor IOC' y escribir 'Composition Root' y será la misma pregunta ... –

Cuestiones relacionadas