2010-01-13 14 views
58

Soy un novato completa a ninject¿Cuál es la intención de los módulos de Ninject?

que he estado tomando el código aparte de otra persona y encontré varios ejemplos de módulos ninject - clases que se derivan de Ninject.Modules.Module, y tener un método de carga que contiene la mayor parte de su código.

Estas clases se invocan invocando el método LoadModule de una instancia de StandardKernel y pasándole una instancia de la clase de módulo.

Tal vez me falta algo obvio aquí, pero ¿cuál es el beneficio de esto sobre la simple creación de una vieja clase simple y llamar a su método, o tal vez una clase estática con un método estático?

módulos

 

Respuesta

61

El Ninject son las herramientas utilizadas para registrar los distintos tipos con el recipiente COI. La ventaja es que estos módulos se guardan en sus propias clases. Esto le permite poner diferentes niveles/servicios en sus propios módulos.

// some method early in your app's life cycle 
public Kernel BuildKernel() 
{ 
    var modules = new INinjectModule[] 
    { 
     new LinqToSqlDataContextModule(), // just my L2S binding 
     new WebModule(), 
     new EventRegistrationModule() 
    }; 
    return new StandardKernel(modules); 
} 

// in LinqToSqlDataContextModule.cs 
public class LinqToSqlDataContextModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IRepository>().To<LinqToSqlRepository>(); 
    } 
} 

Tener varios módulos permite separar las preocupaciones, incluso dentro de su contenedor de IoC.

El resto de su pregunta parece que se trata más de IoC y DI en conjunto, y no solo de Ninject. Sí, podría usar objetos de configuración estáticos para hacer casi todo lo que hace un contenedor IoC. Los contenedores IoC se vuelven realmente agradables cuando tienes múltiples jerarquías de dependencias.

public interface IInterfaceA {} 
public interface IInterfaceB {} 
public interface IInterfaceC {} 

public class ClassA : IInterfaceA {} 

public class ClassB : IInterfaceB 
{ 
    public ClassB(IInterfaceA a){} 
} 

public class ClassC : IInterfaceC 
{ 
    public ClassC(IInterfaceB b){} 
} 

Building ClassC es un dolor en este punto, con múltiples profundidades de interfaces. Es mucho más fácil pedirle al kernel un IInterfaceC.

var newc = ApplicationScope.Kernel.Get<IInterfaceC>(); 
+1

¿LinqToSqlDataContextModule debería extender StandardModule? –

+1

@Mark Gibaud no en Ninject 2. StandardModule se ha ido y reemplazado con NinjectMdule - http://github.com/enkari/ninject/tree/master/src/Ninject/Modules/ –

+1

Ese es un buen ejemplo, pero ¿qué pasa con la capacidad de prueba? Constantemente escucho cómo un contenedor DI/IoC puede ayudarme con la capacidad de prueba, pero estoy teniendo dificultades para encontrar un ejemplo real que muestre que Ninject no contaminará mi código y también facilitará la capacidad de prueba. ¿Hay algún proyecto de código abierto del mundo real que yo pueda ver para entender la idea? –

9

Tal vez me estoy perdiendo algo obvio aquí, pero ¿cuál es el beneficio de esta sobre sólo la creación de una clase a secas y llamando a su método, o tal vez una clase estática con un método estático ?

Sí, puede llamar a un grupo de instrucciones Bind<X>().To<Z>() para configurar los enlaces, sin un módulo.

La diferencia es que si pones estas declaraciones en un módulo a continuación:

  • IKernel.Load(IEnumerable<Assembly>) puede descubrir dinámicamente dichos módulos a través de la reflexión y cargarlos.
  • los enlaces se agrupan lógicamente bajo un nombre; se puede utilizar este nombre para descargarlos de nuevo con IKernel.Unload(string)
3

Tal vez me estoy perdiendo algo obvio aquí, pero ¿cuál es el beneficio de este sobre sólo la creación de una clase a secas y llamando a su método, o tal vez una clase estática con un método estático?

Para nosotros, es la capacidad de agregar pruebas en otro momento muy fácilmente. Simplemente anule algunas ataduras con objetos simulados y voila .....en el código heredado sin una DI que conectó "todo", es casi imposible comenzar a insertar casos de prueba sin una nueva revisión. Con una DI en su lugar Y siempre y cuando se haya utilizado correctamente donde el DI conectó todo, es muy simple hacerlo incluso con el código heredado que puede ser muy feo.

En muchos marcos DI, puede utilizar el módulo de producción para su prueba con un módulo de prueba que anula enlaces específicos con objetos simulados (dejando el resto del cableado en su lugar). Pueden ser pruebas de sistema más que pruebas unitarias, pero tiendo a preferir pruebas de nivel más alto que el desarrollador promedio, ya que prueba la integración entre clases y es una gran documentación para alguien que se une al proyecto y puede ver toda la función en acción (en cambio de solo partes de la característica) sin tener que configurar un sistema completo).

Cuestiones relacionadas