¿Dónde debo hacer la inyección con Ninject 2+ (y cómo organizo mis módulos?)

Tengo una solución con dos proyectos relevantes (para esta pregunta) y algunos otros;

  1. Biblioteca de clases con funcionalidad utilizada por varios otros proyectos.
  2. Aplicación ASP.NET MVC.

Mi pregunta es básicamente dónde debo hacer IoC con Ninject 2, teniendo en cuenta …

  • La biblioteca de clases necesita un poco de amor DI, entre otras cosas en las clases de repository que necesitan objetos de sesión específicos de la solicitud web (piense en la Unidad de trabajo).
  • La aplicación MVC necesita DI ya que con Ninject 2 heredas básicamente de NinjectHttpApplication.
  • Las pruebas unitarias para la biblioteca de clases deben ser conscientes de esto para inyectar un conjunto diferente de repositorys.
  • Las pruebas unitarias para la aplicación web deben ser inyectadas por el mismo motivo.

Me he pintado en un rincón mental aquí, porque para comenzar vi solo tres opciones. DI en la biblioteca de la clase, DI en la aplicación web, o ambos, pero hay problemas con cada uno:

  • No puedo hacer DI solo en la biblioteca de clases ya que la aplicación MVC necesita heredar desde NinjectHttpApplication para empezar.
  • No puedo hacer DI solo en la aplicación MVC; la biblioteca de clases es utilizada por otras bibliotecas, después de todo, y la aplicación MVC no debería saber demasiado sobre las partes internas de la biblioteca de todos modos.
  • Supongo que esta es la única salida que puedo ver: IoC independiente para ambos proyectos. La biblioteca de clases y la aplicación MVC tienen su propia configuración de IoC y hacen DI para sus cosas sin preocuparse realmente por el otro.

¿Alguien tiene algunas “mejores prácticas” o pautas sobre cómo hacer algo como esto? No me puedo imaginar que soy la primera persona en terminar en esta situación, y sería bueno saber cuál es la forma “correcta” de hacer esto …

¡Gracias!

No conozco NInject, pero a menos que funcione de forma muy diferente a Windsor, StructureMap, etc., las respuestas tienden a permanecer igual, ya que hay algunos patrones DI comunes. Con eso en mente:

Lo primero es darse cuenta de que DI no está vinculado a un marco particular como NInject o Windsor. Es un conjunto de técnicas y patrones de diseño a seguir. Puedes hacer DI manualmente usando la llamada DI de Poor Man, pero obviamente se pone mucho mejor con un DI Container.

¿Por qué es esto relevante? Es relevante porque una vez que te das cuenta de esto, el corolario es que la gran mayoría del código de tu aplicación no debería tener conocimiento de lo que es el DI Contenedor.

Entonces, ¿dónde usas el DI Container? Solo debe usarse en una raíz de composición , que en su caso correspondería a Global.asax. Puede leer un poco más sobre esto en esta respuesta SO : aunque esa pregunta es sobre Windsor, el principio sigue siendo el mismo.

¿Qué tal las pruebas de su unidad entonces? También deberían ignorar por completo el contenedor DI. Vea esta otra respuesta SO para más detalles.

DI se puede lograr en su biblioteca con el uso copioso de Constructor Injection . No necesita hacer referencia a ningún Contenedor DI para hacer eso, pero hace la vida mucho más fácil si usa un Contenedor DI para resolver todas las dependencias de la Raíz de Composición.