2010-01-03 16 views
46

He decidido usar los principios de IoC en un proyecto más grande. Sin embargo, me gustaría aclarar algo que me ha estado molestando por mucho tiempo. La conclusión a la que me he llegado es que un contenedor de IoC es un patrón arquitectónico, no un patrón de diseño. En otras palabras, ninguna clase debe conocer su presencia y el contenedor en sí debe usarse en la capa de aplicación para unir todos los componentes. Esencialmente, se convierte en una opción, además de un modelo bien diseñado orientado a objetos. Habiendo dicho eso, ¿cómo es posible acceder a tipos resueltos sin rociar contenedores IoC por todos lados (independientemente de si son abstraídos o no)? La única opción que veo aquí es utilizar fábricas abstractas que usan un contenedor IoC para resolver tipos concretos. Esto debería ser lo suficientemente fácil como para cambiar para un conjunto de fábricas estándar. ¿Es este un buen enfoque? ¿Alguien aquí lo usó y qué tan bien funcionó para usted? ¿Hay algo más disponible?¿Patrón de fábrica abstracto sobre IoC?

Gracias!

Respuesta

69

Como ya se ha dado cuenta, Dependency Injection (DI) en sí misma es solo una colección de patrones y técnicas.

En la raíz de la aplicación conectamos todos los gráficos de objetos necesarios. Este lugar se llama Composition Root, y podemos usar un DI Container para hacer este cableado por nosotros, o podemos hacerlo manualmente (Poor Man's DI).

El punto es que solo hay un lugar en su aplicación donde hay una fuerte referencia a una tecnología en particular (su contenedor DI). El resto de la aplicación es felizmente ignorante de cómo el gráfico de objetos se cablea - todo lo que importa es que todas las dependencias requeridas fueron inyectados correctamente (y se puede utilizar Constructor inyección con nulos Guardia para garantizar que esto es así)

El patrón deAbstract Factory es un modelo útil muy cuando se trata de DI. En esencia, use Abstract Factory cuando:

  • Debe proporcionar uno o más parámetros conocidos en tiempo de ejecución para poder resolver una dependencia.
  • La duración de la dependencia es conceptualmente más corta que la vida del consumidor.

Ejemplos y más información está disponible aquí:

+1

Creo que ya casi estoy allí. Quédate aquí conmigo :) Digamos que tengo la interfaz IFruit que implementa la clase Apple. Después de registrar este tipo concreto, quiero usarlo en mi evento de clic de botón en Windows Form. ¿Cómo llegaría a la clase de Apple sin acceder explícitamente al contenedor IoC desde el evento button? –

+7

Eso depende: ¿hay muchas instancias de IFruit en su aplicación, o solo una? Si solo hay uno, ya debería haberse inyectado en la clase con el controlador de clic de botón. Si hay muchos, lo más probable es que necesite una IFruitFactory que pueda crear una instancia de IFruit a partir de otros valores de tiempo de ejecución. En este último caso, IFruitFactory sería la dependencia inyectada. –

+0

Considerando que solo existe una instancia de IFruit, la única forma en que lo veo inyectado en la clase Form con el evento click del botón es si cambio el constructor del formulario para incluir la interfaz IFruit y luego registro el Formulario mismo con el contenedor IoC para realizar el constructor inyección. ¿Esto suena correcto? Gracias por ayudar! –

4

Bueno, en la parte superior de su aplicación, necesitará una clase Bootstrap que cargue el contexto de IOC. Este contexto proporcionará los objetos instanciados y, por lo tanto, actuará como una fábrica.

Pero esto solo debería ocurrir con muy pocos objetos y el usuario de su clase Bootstrap/Factory debería saber tan poco acerca de la arquitectura subyacente como sea posible. Por ejemplo, si configuró un objeto de servidor HTTP completamente a través de IOC y desea iniciarlo, su clase Bootstrap solo necesita proporcionar un método getHttpServer(). Entonces, el método principal de su programa solo necesita llamar a Bootstrap.getHttpServer(). Start() para que se ejecute.

El cableado de sus otros objetos ya se ha realizado según el contexto de la aplicación, p. usted configura el Objeto A a través de IOC, que es parte del Objeto B, por lo que configura el Objeto B con la referencia al Objeto A. Ninguno de ellos normalmente necesita conocer el contenedor ni la fábrica.

Cuestiones relacionadas