Diferencia entre la inyección de dependencia (DI) y la inversión de control (COI)

117

He estado viendo muchas referencias de Dependency Injection (DI) e Inversion Of Control (IOC), pero realmente no sé si hay una diferencia entre ellas o no.

Me gustaría comenzar a usar uno o ambos, pero estoy un poco confundido sobre cómo son diferentes.

mosquito
fuente
La inversión de control generalmente se refiere a los "contenedores", mientras que la inyección de dependencia se refiere al patrón real. Pero van de la mano. Recomendaría leer el artículo de Martin Fowler para conocer el tema.
Ben Hoffstein
La inyección de dependencia es algo que haces, lo que lleva a una estructura de comando llamada Inversión de control. Están inherentemente vinculados.
2
DI es una forma de IoC, di una explicación bastante detallada de DI e IoC en esta respuesta
2
Yo diría que DI es un caso especial de COI. El control tradicional va módulo-> módulo de solicitud del administrador del módulo, en DI se invierte al administrador del módulo-> obtener dependencias solicitadas del módulo.
Rafał Dowgird
En otras palabras, básicamente IoC es una implementación del uso de DI. ¿Lo estoy entendiendo correctamente?
dance2die

Respuestas:

53

Definiciones

La inversión del control es un paradigma de diseño con el objetivo de reducir el conocimiento de implementaciones concretas del código de marco de la aplicación y dar más control a los componentes específicos del dominio de su aplicación. En un sistema tradicional diseñado de arriba hacia abajo, el flujo lógico de la aplicación y la conciencia de dependencia fluye desde los componentes superiores, los diseñados primero, hasta los diseñados por último. Como tal, la inversión de control es una inversión casi literal de la conciencia de control y dependencia en una aplicación.

La inyección de dependencia es un patrón utilizado para crear instancias de clases en las que otras clases dependen sin saber en el momento de la compilación qué implementación se utilizará para proporcionar esa funcionalidad.

Trabajando juntos

La inversión del control puede utilizar la inyección de dependencia porque se necesita un mecanismo para crear los componentes que proporcionan la funcionalidad específica. Existen otras opciones y se utilizan, por ejemplo, activadores, métodos de fábrica, etc., pero los marcos no necesitan hacer referencia a esas clases de utilidad cuando las clases marco pueden aceptar las dependencias que necesitan.

Ejemplos

Un ejemplo de estos conceptos en el trabajo es el marco de plug-in en Reflector . Los complementos tienen un gran control del sistema a pesar de que la aplicación no sabía nada sobre los complementos en el momento de la compilación. Se llama a un único método en cada uno de esos complementos, Inicializar si la memoria sirve, que pasa el control al complemento. El marco no sabe lo que harán, simplemente les permite hacerlo. El control se ha tomado de la aplicación principal y se le ha dado al componente que realiza el trabajo específico; Inversión de control.

El marco de la aplicación permite el acceso a su funcionalidad a través de una variedad de proveedores de servicios. Un complemento recibe referencias a los proveedores de servicios cuando se crea. Estas dependencias permiten que el complemento agregue sus propios elementos de menú, cambie la forma en que se muestran los archivos, muestre su propia información en los paneles apropiados, etc. Dado que las dependencias se pasan por interfaz, las implementaciones pueden cambiar y los cambios no interrumpirán código siempre que el contrato permanezca intacto.

En ese momento, se utilizó un método de fábrica para crear los complementos utilizando información de configuración, reflexión y el objeto Activador (al menos en .NET). Hoy en día, existen herramientas, MEF para una, que permiten una gama más amplia de opciones al inyectar dependencias, incluida la capacidad de un marco de aplicación para aceptar una lista de complementos como dependencia.

Resumen

Si bien estos conceptos se pueden usar y proporcionar beneficios de forma independiente, juntos permiten escribir código mucho más flexible, reutilizable y comprobable. Como tales, son conceptos importantes en el diseño de soluciones orientadas a objetos.

Arrojar
fuente
3
No, IoC es un concepto antiguo y es independiente de DI (que no depende de IoC). Por ejemplo, tome el marco Struts (Java): depende en gran medida de IoC, pero no utiliza DI.
Rogério
1
@ Rogério: Usted señala que los dos conceptos no se requieren entre sí. Actualicé mi respuesta para aclarar eso y luego describí rápidamente cómo algunos marcos los usan juntos para permitir un código que se acopla más libremente.
Chuck
La aplicación más simple de IoC, probablemente sería ActionListener. En lugar de manejar el código procesalmente, el código de manejo de eventos se delega en un código personalizado. Por la presente invierte el control.
Mike
0

Buen artículo para entender IOC y DI http://martinfowler.com/articles/injection.html

COI (Inversión de control)

COI significa

  1. codificación a la interfaz (un componente debe depender de la interfaz de otro componente y no de la impl), y por ejemplo

    interface iComp_2 {...}
    
    class Comp_1 {
        iComp_2 c2 = ….;
    }
    
  2. eliminar el código específico de implementación del componente, por ejemplo

    Comp_1 {
        iComp_2 c2 = getComp_2_Impl(); // not new Comp_2_Impl();
    }
    

El COI se puede lograr por cualquiera de los siguientes:

1. DI (inyección de dependencia)

3 types of DI

1.1 Constructor Injection

1.2 Setter Injection

1.3 Interface Injection

2. Localizador de servicios

Contenedor DI (inyección de dependencia)

Determinación impl de tiempo de ejecución y no tiempo de compilación: determina en el tiempo de ejecución qué implementación concreta de una interfaz se utilizará en función de algún archivo de configuración (por lo que en el momento de la compilación no sabemos qué impl se va a utilizar y, por lo tanto, aumenta la configurabilidad de la aplicación) . Es una implementación donde la relación concreta entre los diferentes módulos se decide en "tiempo de ejecución".

Creación de instancias de impl después de la inyección de dependencia: después de determinar la impl, crea una instancia de esa impl creando primero todas sus dependencias (especificadas en el archivo de configuración) y luego inyectando esas dependencias en esa impl

Gestión del ciclo de vida de la instancia: los contenedores DI generalmente solo guardan una referencia a los objetos para los que necesita gestionar los ciclos de vida, o que se reutilizan para futuras inyecciones, como singletons o flyweights. Cuando se configura para crear nuevas instancias de algunos componentes para cada llamada al contenedor, el contenedor generalmente solo se olvida del objeto creado. De lo contrario, el recolector de basura tendría dificultades para recolectar todos estos objetos cuando ya no se usen.

Yatendra Goel
fuente
66
¿Realmente leíste el artículo de "inyección"? COI no significa lo que dice esta respuesta, en absoluto.
Rogério
-3

Yo diría que "Inversión de control" es una forma de diseñar un sistema donde todos los módulos están pensados ​​en entidades abstractas.

Y, "Dependency Injection" es una implementación donde la relación concreta entre los diferentes módulos se decide en "tiempo de ejecución".

megabyte.
fuente
-4

La inversión del control es un concepto general, en los lenguajes funcionales generalmente se realiza utilizando continuaciones. Esto le permite escribir una API donde ambos lados son 'llamante' y ninguno es el 'llamante'. En otros entornos más estáticos, no tiene esta facilidad, por lo que necesita este truco para insertar sugerencias en el flujo de control.

Javier
fuente