2011-02-28 8 views
12

Recientemente he estado tratando de aprender COI, y tienen un par de preguntas basadas en el siguiente código:estoy confundido acerca de abstracciones de interfaz cuando se utiliza COI

public class WarriorModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IWeapon>().To<Sword>(); 
     Bind<Samurai>().ToSelf(); 
    } 
} 

estoy teniendo problemas para comprender el nuevo concepto de interfaces. Antes de crear una interfaz como IRunnable, implementando la función void Run(). Con IoC, ahora estoy viendo una interfaz como algo que solo se asigna a una sola clase concreta. Suponiendo que, , ¿cómo puedo mapear múltiples clases concretas en una interfaz? Sigo leyendo que puede asignar múltiples interfaces a una sola clase concreta, pero no al revés (a menos que sea aquí donde entra en juego la asignación contextual).

Suponiendo que las interfaces solo se asignan a un único objeto, ¿cuándo debería crear una interfaz en lugar de tener un objeto vinculado a sí mismo? De cualquier forma, ¿tendrá que cambiar la misma pieza de código cuando la asignación sea correcta?


Editar: Marqué la respuesta que hice porque me ayudó personalmente. Ambos comentarios son igualmente informativos.

Respuesta

16

Recientemente addressed this topic from a more general viewpoint. La conclusión es que existe una tendencia a que el código débilmente acoplado produzca una sobreabundancia de las interfaces 1: 1. Esto es contrario al Reused Abstractions Principle.

Sin embargo, esto es más un problema de diseño de la aplicación que es un problema con respecto a determinados contenedores de DI. Aunque no conozco Ninject, todos los demás contenedores con los que he trabajado (Castle Windsor, StructureMap, Spring.NET, Autofac, Unity e incluso MEF) pueden asignar múltiples implementaciones a la misma interfaz.La forma en que lo hacen difiere un poco, pero los cubro a todos en la parte IV de my book - desafortunadamente, Ninject no está cubierto en el libro.

+0

Esto me ayudó a retomar el rumbo: "hay una tendencia a que el código débilmente acoplado produzca una sobreabundancia de interfaces 1: 1". Gracias por eso. Siento que los conceptos finalmente se están hundiendo después de tres días. – Phil

18

contenedor Un buen COI no debería cambiar la forma se utilizan interfaces:

  1. Una interfaz debe diseñarse para el componente que está utilizando como la dependencia y no la clase que lo implementa. (principio de segregación de la interfaz)
  2. Una clase puede implementar varias interfaces. Pero esto solo debería hacerse si esas interfaces son para el mismo tipo de servicio, de modo que la clase haga exactamente una cosa. Si las interfaces son para dos cosas diferentes, deberían ser implementadas por dos clases diferentes. (principio de responsabilidad única)
  3. Varias clases pueden implementar la misma interfaz si necesita múltiples estrategias para este tipo de servicio.

Ninject permite el uso de interfaces de esta manera el uso de dos conceptos diferentes:

  1. fijaciones condicionales: Si varias clases implementan la misma interfaz que tiene que especificar qué aplicación se utiliza en este caso. Esto se hace usando condiciones:

    Bind<IWeapon>().To<Sword>().When(ctx => TodayIsSunday());

    Bind<IWeapon>().To<Dagger>().When(ctx => !TodayIsSunday());

  2. Múltiples interfaces: Véase mi entrada de blog http://www.planetgeek.ch/2010/12/08/ninject-extension-contextpreservation-explained/

+0

+1 Aunque no puedo comentar los detalles de Ninject, estoy totalmente de acuerdo con los puntos generales presentados aquí. –

Cuestiones relacionadas