Inversión de control vs inyección de dependencia


525

Según el artículo escrito por Martin Fowler , la inversión de control es el principio en el que se invierte el flujo de control de un programa: en lugar de que el programador controle el flujo de un programa, las fuentes externas (marco, servicios, otros componentes) toman el control de eso. Es como si conectamos algo a otra cosa. Mencionó un ejemplo sobre EJB 2.0:

Por ejemplo, la interfaz Session Bean define ejbRemove, ejbPassivate (almacenado en el almacenamiento secundario) y ejbActivate (restaurado del estado pasivo). No puedes controlar cuándo se llaman estos métodos, solo lo que hacen. El contenedor nos llama, nosotros no lo llamamos.

Esto lleva a la diferencia entre framework y biblioteca:

La inversión del control es una parte clave de lo que hace que un marco sea diferente a una biblioteca. Una biblioteca es esencialmente un conjunto de funciones a las que puede llamar, en estos días generalmente organizadas en clases. Cada llamada hace algo de trabajo y devuelve el control al cliente.

Creo que el punto de vista de que DI es IOC significa que la dependencia de un objeto está invertida: en lugar de controlar sus propias dependencias, ciclo de vida ... algo más lo hace por usted. Pero, como me contó sobre la DI a mano, la DI no es necesariamente un COI. Todavía podemos tener DI y no IOC.

Sin embargo, en este documento (de pococapsule, otro IOC Framework para C / C ++), sugiere que debido a IOC y DI, los contenedores IOC y los marcos DI son mucho más superiores a J2EE, ya que J2EE mezcla el código marco en los componentes , por lo que no lo convierte en Objeto Java / C ++ simple (POJO / POCO)

Inversión de contenedores de control que no sean el patrón de inyección de dependencia (enlace de archivo)

Lectura adicional para comprender cuál es el problema con el antiguo Marco de desarrollo basado en componentes, que conduce al segundo documento anterior: Por qué y qué de la Inversión de control (Enlace de archivo)

Mi pregunta : ¿Qué es exactamente COI y DI? Estoy confundido. Basado en pococapsule, IOC es algo más significativo que la simple inversión del control entre objetos o programadores y marcos.


2
Aquí hay una buena reseña sobre el tema, IoC vs DI (Inyección de dependencia) vs SL (Localizador de servicio): tinyurl.com/kk4be58 - Extracto de la url: IoC vs DI (Inyección de dependencia)? IoC es el concepto general donde el control del flujo se invierte del código del cliente al marco, que "hace algo por el cliente". SL (Service Locator) y DI (Dependency Injection) son dos patrones de diseño derivados de IoC.
Swab.Jat

Para agregar mis dos centavos, si uno está interesado en cómo la inyección de dependencia puede ser útil en el tema de una cafetería, he escrito un artículo sobre eso aquí: digigene.com/design-patterns/dependency-injection-coffeeshop
Ali Nem

3

Inversión de dependencia: depende de abstracciones, no de concreciones. Inversión de control: Principal vs Abstracción, y cómo Principal es el pegamento de los sistemas. Estas son algunas buenas publicaciones que hablan de esto: coderstower.com/2019/03/26/… coderstower.com/2019/04/02/… coderstower.com/2019/04/09/…
Daniel Andres Pelaez Lopez

lea sobre este profundo, borrará todos martinfowler.com/articles/…
Dushman

Respuestas:


644

IoC es un término genérico que significa que en lugar de que la aplicación llame a los métodos en un marco, el marco llama a las implementaciones proporcionadas por la aplicación.

DI es una forma de IoC, donde las implementaciones se pasan a un objeto a través de búsquedas de constructores / establecedores / servicios, de las cuales el objeto 'dependerá' para comportarse correctamente.

IoC sin usar DI , por ejemplo, sería el patrón de Plantilla porque la implementación solo se puede cambiar a través de subclases.

Los Frameworks DI están diseñados para hacer uso de DI y pueden definir interfaces (o Anotaciones en Java) para facilitar el paso de las implementaciones.

Los IoC Containers son marcos de trabajo DI que pueden funcionar fuera del lenguaje de programación. En algunos, puede configurar qué implementaciones usar en los archivos de metadatos (por ejemplo, XML) que son menos invasivos. Con algunos puedes hacer IoC que normalmente sería imposible como inyectar una implementación en los puntos de corte .

Vea también este artículo de Martin Fowler .


2
Gracias por la respuesta. Pero el otro artículo sugiere que con IOC, los contenedores de IOC son mucho más superiores a EJB, mientras que Martin Fowler sugiere que EJB es un ejemplo típico de IOC.
Amumu 01 de

55
La administración de EJB es realmente un ejemplo típico de IoC. Puede verlo por el hecho de que el ciclo de vida de un EJB es administrado por el contenedor, no por el programador. El programador no crea ni destruye una instancia de EJB porque el control se delega al servidor . Ese es el concepto de IoC: el código externo controla cuándo se llama a su código, que generalmente es lo contrario de lo que se hace la mayor parte del tiempo.
brandizzi

2
IoC es un término genérico que significa que en lugar de que la aplicación llame a los métodos en un marco, el marco llama a las implementaciones proporcionadas por la aplicación. ¿Puedes explicarlo más sobre esto?
Imad Alazani

21
Al principio de Hollywood , "no nos llames, te llamaremos". Deja la invocación hasta el marco en lugar de la aplicación.
Garrett Hall

@ImadAlazani, será mejor que lea el artículo que adjuntó Garrett, que es una discusión detallada sobre cómo invertir el control del código de la aplicación al marco.
MengT

210

En resumen, IoC es un término mucho más amplio que incluye, entre otros, DI

El término Inversión de control (IoC) originalmente significaba cualquier tipo de estilo de programación donde un marco general o tiempo de ejecución controlaba el flujo del programa

Antes de que DI tuviera un nombre, las personas comenzaron a referirse a los marcos que gestionan las dependencias como inversión de contenedores de control, y pronto, el significado de IoC se desvió gradualmente hacia ese significado particular: inversión de control sobre dependencias.

La inversión de control (IoC) significa que los objetos no crean otros objetos en los que confían para hacer su trabajo. En cambio, obtienen los objetos que necesitan de una fuente externa (por ejemplo, un archivo de configuración xml).

La inyección de dependencia (DI) significa que esto se realiza sin la intervención del objeto, generalmente mediante un componente de marco que pasa los parámetros del constructor y establece las propiedades.


1
Parece que IoC es solo otro término para el principio de Inversión de dependencia, ¿no?
Todd Vance

@ToddVance: Sí, creo que IoC y DIP son lo mismo. DIP y DI no son lo mismo. IoC se puede hacer sin DI, pero DI no se puede hacer sin IoC.
Eljay

2
@ToddVance: no, DIP e IoC no son sinónimos y no están relacionados.
TSmith

3
Ja, por eso estoy aquí en este hilo ... "Inversión de Control vs Inyección de Dependencia"
Todd Vance

50

ingrese la descripción de la imagen aquí
fuente

COI ( I nVersión o f C ontrol): - Es un término genérico e implementado de varias formas (eventos, delegados, etc.).

DI ( D ependency I njection): - DI es un subtipo de IoC y se implementa mediante inyección de constructor, inyección de setter o inyección de interfaz .

Pero Spring solo admite los siguientes dos tipos:

  • Inyección de Setter
    • La DI basada en Setter se realiza llamando a los métodos de establecimiento en los beans del usuario después de invocar un constructor sin argumentos o un método de fábrica estático sin argumentos para instanciar su bean.
  • Inyección de constructor
    • La DI basada en el constructor se realiza invocando a un constructor con varios argumentos, cada uno representando un colaborador. Con esto podemos validar que los beans inyectados no son nulos y fallan rápidamente (fallan en el tiempo de compilación y no en el tiempo de ejecución). al iniciar la aplicación en sí obtenemos NullPointerException: bean does not exist. La inyección de constructor es la mejor práctica para inyectar dependencias.

1
no es correcto declarar que Spring no admite la inyección de propiedades. Lo hace. Y es una mala práctica, estoy de acuerdo.
kekko12

Spring @Autowired annotation es una forma de inyección de propiedad en mi opinión
Sajith

49

DI es un subconjunto de IoC

  • IoC significa que los objetos no crean otros objetos en los que confían para hacer su trabajo. En cambio, obtienen los objetos que necesitan de un servicio externo (por ejemplo, archivo xml o servicio de aplicación única). 2 implementaciones de IoC, utilizo, son DI y ServiceLocator.
  • DI significa que el principio de IoC de obtener un objeto dependiente se realiza sin usar objetos concretos sino abstracciones (interfaces). Esto hace que la cadena de todos los componentes sea comprobable, ya que el componente de nivel superior no depende del componente de nivel inferior, solo de la interfaz. Los simulacros implementan estas interfaces.

Aquí hay algunas otras técnicas para lograr IoC .


No diría que IoC significa no crear objetos. Cuando llama no al método de clase directamente, sino al método de interfaz, esto es una inversión de control (como en este caso, la persona que llama no depende del código de llamada) y no está relacionado en absoluto con la creación de objetos. Un ejemplo más de IoC son los eventos y los delegados
Eugene Gorbovoy,

20

IOC (Inversión de control) : dar control al contenedor para obtener una instancia del objeto se llama Inversión de control, significa que en lugar de crear un objeto con el nuevo operador, deje que el contenedor lo haga por usted.

DI (inyección de dependencia) : la forma de inyectar propiedades a un objeto se llama inyección de dependencia .

Tenemos tres tipos de inyección de dependencia :

  1. Inyección de constructor
  2. Inyección de Setter / Getter
  3. Inyección de interfaz

Spring solo admite la inyección de constructor y la inyección de setter / getter .


19

Como todas las respuestas enfatizan la teoría, me gustaría demostrar con un primer enfoque de ejemplo:

Supongamos que estamos creando una aplicación que contiene una función para enviar mensajes de confirmación por SMS una vez que se ha enviado el pedido. Tendremos dos clases, una es responsable de enviar el SMS (SMSService) y otra responsable de capturar las entradas del usuario (UIHandler), nuestro código se verá a continuación:

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

La implementación anterior no está mal, pero hay algunos problemas:
-) Suponga que en el entorno de desarrollo, desea guardar los SMS enviados a un archivo de texto en lugar de usar la puerta de enlace de SMS, para lograr esto; terminaremos cambiando la implementación concreta de (SMSService) con otra implementación, estamos perdiendo flexibilidad y nos vemos obligados a reescribir el código en este caso.
-) Terminaremos mezclando las responsabilidades de las clases, nuestro (UIHandler) nunca debe saber acerca de la implementación concreta de (SMSService), esto debe hacerse fuera de las clases usando "Interfaces". Cuando se implementa esto, nos dará la capacidad de cambiar el comportamiento del sistema intercambiando el (SMSService) utilizado con otro servicio simulado que implementa la misma interfaz, este servicio guardará los SMS en un archivo de texto en lugar de enviarlo a mobileNumber.

Para solucionar los problemas anteriores, utilizamos interfaces que serán implementadas por nuestro (SMSService) y el nuevo (MockSMSService), básicamente la nueva interfaz (ISMSService) expondrá los mismos comportamientos de ambos servicios como el código a continuación:

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

Luego cambiaremos nuestra implementación (SMSService) para implementar la interfaz (ISMSService):

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

Ahora podremos crear un nuevo servicio de simulación (MockSMSService) con una implementación totalmente diferente usando la misma interfaz:

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

En este punto, podemos cambiar el código en (UIHandler) para usar la implementación concreta del servicio (MockSMSService) fácilmente de la siguiente manera:

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Hemos logrado mucha flexibilidad e implementado la separación de preocupaciones en nuestro código, pero aún necesitamos hacer un cambio en la base del código para cambiar entre los dos Servicios de SMS. Entonces, necesitamos implementar la inyección de dependencia .

Para lograr esto, necesitamos implementar un cambio en nuestro constructor de clase (UIHandler) para pasar la dependencia a través de él, al hacer esto, el código que usa (UIHandler) puede determinar qué implementación concreta de (ISMSService) usar:

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Ahora el formulario de interfaz de usuario que hablará con la clase (UIHandler) es responsable de pasar qué implementación de interfaz (ISMSService) consumir. Esto significa que hemos invertido el control, el (UIHandler) ya no es responsable de decidir qué implementación usar, lo hace el código de llamada. Hemos implementado el principio de Inversión de control , que es un tipo de DI.

El código del formulario de la interfaz de usuario será el siguiente:

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

Gran explicación
ZiviMagic

5

Pero la documentación de primavera dice que son lo mismo.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

En la primera línea " IoC también se conoce como inyección de dependencia (DI) ".


1
Supongo que lo que estaban tratando de abordar es que DI es un sabor muy utilizado del patrón de diseño de IoC que casi se puede llamar IoC aka DI, a menos que la documentación tenga alguna referencia explícita que sugiera lo contrario.
ha9u63ar

55
"IoC también se conoce como inyección de dependencia (DI)" ... ¡jinetes!
MikeM

5

IoC - Inversión de control es un término genérico, independiente del lenguaje, en realidad no es crear los objetos sino describir en qué objeto de moda se está creando.

DI - Inyección de dependencias es un término concreto, en el que proporcionamos dependencias del objeto en tiempo de ejecución mediante el uso de diferentes técnicas de inyección, a saber. Setter Injection, Constructor Injection o por Interface Injection.


4

La inversión de control es un paradigma de diseño con el objetivo de dar más control a los componentes específicos de su aplicación, los que realizan el trabajo.
La inyección de dependencia es un patrón utilizado para crear instancias de objetos de los que dependen otros objetos sin saber en el momento de la compilación qué clase se utilizará para proporcionar esa funcionalidad.

Existen varias técnicas básicas para implementar la inversión de control. Estos son:

  • Usando un patrón de fábrica
  • Usar un patrón de localizador de servicios
  • Usando una inyección de dependencia de cualquiera de los siguientes tipos:

    1). Un constructor de inyección
    2). Una inyección de setter
    3). Una inyección de interfaz

4

DI e IOC son dos patrones de diseño que se centran principalmente en proporcionar un acoplamiento suelto entre componentes , o simplemente una forma en la que desacoplamos las relaciones de dependencia convencionales entre objetos para que los objetos no estén unidos entre sí.

Con los siguientes ejemplos, estoy tratando de explicar estos dos conceptos.

Anteriormente estamos escribiendo código como este

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

Con la inyección de dependencia, el inyector de dependencia se encargará de la creación de instancias de los objetos.

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

El proceso anterior de otorgar el control a otro (por ejemplo, el contenedor) para la creación de instancias y la inyección puede denominarse Inversion of Control y el proceso en el que el contenedor IOC inyecta la dependencia para nosotros puede denominarse inyección de dependencia.

El COI es el principio en el que se invierte el flujo de control de un programa: en lugar de que el programador controle el flujo de un programa , el programa controla el flujo al reducir la sobrecarga al programador, y el proceso utilizado por el programa para inyectar dependencia se denomina DI

Los dos conceptos trabajan juntos y nos proporcionan una forma de escribir código mucho más flexible, reutilizable y encapsulado, lo que los convierte en conceptos importantes en el diseño de soluciones orientadas a objetos.

También recomiendo leer.

¿Qué es la inyección de dependencia?

También puedes consultar una de mis respuestas similares aquí

Diferencia entre inversión de control e inyección de dependencia


3

La inversión de control es un principio de diseño genérico de la arquitectura de software que ayuda a crear marcos de software modulares reutilizables que son fáciles de mantener.

Es un principio de diseño en el que el flujo de control se "recibe" de la biblioteca genérica escrita o del código reutilizable.

Para entenderlo mejor, veamos cómo solíamos codificar en nuestros primeros días de codificación. En los lenguajes de procedimiento / tradicionales, la lógica empresarial generalmente controla el flujo de la aplicación y "llama" al código / funciones genéricos o reutilizables. Por ejemplo, en una aplicación de consola simple, mi flujo de control está controlado por las instrucciones de mi programa, que pueden incluir las llamadas a algunas funciones reutilizables generales.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

En contraste, con IoC, los Frameworks son el código reutilizable que "llama" a la lógica de negocios.

Por ejemplo, en un sistema basado en Windows, un marco ya estará disponible para crear elementos de la interfaz de usuario como botones, menús, ventanas y cuadros de diálogo. Cuando escribo la lógica de negocios de mi aplicación, serían los eventos del marco los que llamarán a mi código de lógica de negocios (cuando se dispara un evento) y NO lo contrario.

Aunque, el código del marco no tiene conocimiento de mi lógica comercial, todavía sabrá cómo llamar a mi código. Esto se logra utilizando eventos / delegados, devoluciones de llamada, etc. Aquí el control de flujo se "invierte".

Por lo tanto, en lugar de depender del flujo de control de los objetos enlazados estáticamente, el flujo depende del gráfico general del objeto y de las relaciones entre los diferentes objetos.

La inyección de dependencias es un patrón de diseño que implementa el principio de IoC para resolver dependencias de objetos.

En palabras más simples, cuando intente escribir código, creará y usará diferentes clases. Una clase (Clase A) puede usar otras clases (Clase B y / o D). Entonces, las clases B y D son dependencias de la clase A.

Una analogía simple será un auto de clase. Un automóvil puede depender de otras clases como motor, neumáticos y más.

La inyección de dependencia sugiere que, en lugar de que las clases dependientes (Class Car aquí) creen sus dependencias (Class Engine y class Tire), la clase debería ser inyectada con la instancia concreta de la dependencia.

Vamos a entender con un ejemplo más práctico. Considere que está escribiendo su propio TextEditor. Entre otras cosas, puede tener un corrector ortográfico que le brinde al usuario la posibilidad de revisar los errores tipográficos en su texto. Una implementación simple de dicho código puede ser:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

A primera vista, todo parece rosado. El usuario escribirá algo de texto. El desarrollador capturará el texto y llamará a la función CheckSpellings y encontrará una lista de errores tipográficos que le mostrará al usuario.

Todo parece funcionar muy bien hasta un buen día cuando un usuario comienza a escribir francés en el Editor.

Para proporcionar soporte para más idiomas, necesitamos tener más correctores ortográficos. Probablemente francés, alemán, español, etc.

Aquí, hemos creado un código estrechamente acoplado con SpellChecker "inglés" estrechamente acoplado con nuestra clase TextEditor, lo que significa que nuestra clase TextEditor depende de EnglishSpellChecker o, en otras palabras, EnglishSpellCheker es la dependencia de TextEditor. Necesitamos eliminar esta dependencia. Además, nuestro editor de texto necesita una forma de mantener la referencia concreta de cualquier corrector ortográfico basado en el criterio del desarrollador en tiempo de ejecución.

Entonces, como vimos en la introducción de DI, sugiere que la clase debería ser inyectada con sus dependencias. Por lo tanto, debería ser responsabilidad del código de llamada inyectar todas las dependencias a la clase / código llamado. Entonces podemos reestructurar nuestro código como

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

En nuestro ejemplo, la clase TextEditor debería recibir la instancia concreta del tipo ISpellChecker.

Ahora, la dependencia se puede inyectar en Constructor, una Propiedad pública o un método.

Intentemos cambiar nuestra clase usando Constructor DI. La clase TextEditor modificada se verá así:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

Para que el código de llamada, al crear el editor de texto, pueda inyectar el tipo de corrector ortográfico apropiado en la instancia del editor de texto.

Puedes leer el artículo completo aquí.


3

IOC (Inversión de control): dar control al contenedor para obtener la instancia del objeto se llama Inversión de control. Significa que, en lugar de crear un objeto con un nuevo operador , deje que el contenedor lo haga por usted.

DI (Inyección de dependencia): Pasar los parámetros (propiedades) requeridos desde XML a un objeto (en POJO CLASS) se llama inyección de dependencia.


2

IOC indica que las clases externas que administran las clases de una aplicación, y las clases externas significan que un contenedor administra la dependencia entre la clase de la aplicación. El concepto básico de IOC es que el programador no necesita crear sus objetos, sino que describe cómo deben crearse.

Las tareas principales que realiza el contenedor IoC son: crear una instancia de la clase de aplicación. para configurar el objeto. para ensamblar las dependencias entre los objetos.

DI es el proceso de proporcionar las dependencias de un objeto en tiempo de ejecución mediante la inyección de setter o la inyección de constructor.


2

IOC (Inversion of Control) es básicamente un concepto de patrón de diseño para eliminar dependencias y desacoplarlas para hacer que el flujo no sea lineal, y permite que el contenedor u otra entidad gestione el aprovisionamiento de dependencias. De hecho, sigue al director de Hollywood "No nos llames, te llamaremos". Entonces resumiendo las diferencias.

Inversión de control: - Es un término genérico para desacoplar las dependencias y delegar su aprovisionamiento, y esto se puede implementar de varias maneras (eventos, delegados, etc.).

Inyección de dependencia: - DI es un subtipo de IOC y se implementa mediante inyección de constructor, inyección de setter o inyección de método.

El siguiente artículo describe esto muy claramente.

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

Creo que la idea se puede demostrar claramente sin entrar en malezas orientadas a objetos, que parecen confundir la idea.

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

Si inclina la cabeza y entrecierra los ojos, verá que DI es una implementación particular de IoC con preocupaciones específicas. En lugar de inyectar modelos y comportamientos en un marco de aplicación u operación de orden superior, está inyectando variables en una función u objeto.


0

Comencemos con D de SOLID y veamos DI e IoC del libro de Scott Millett "Patrones de diseño profesional ASP.NET":

Principio de inversión de dependencia (DIP)

El DIP se trata de aislar sus clases de implementaciones concretas y hacer que dependan de clases o interfaces abstractas. Promueve el mantra de la codificación de una interfaz en lugar de una implementación, lo que aumenta la flexibilidad dentro de un sistema al garantizar que no esté estrechamente vinculado a una implementación.

Inyección de dependencia (DI) e Inversión de control (IoC)

Estrechamente vinculados al DIP están el principio DI y el principio IoC. DI es el acto de suministrar una clase dependiente o de bajo nivel a través de un constructor, método o propiedad. Utilizadas en conjunto con DI, estas clases dependientes pueden invertirse en interfaces o clases abstractas que conducirán a sistemas libremente acoplados que son altamente comprobables y fáciles de cambiar.

En IoC , el flujo de control de un sistema se invierte en comparación con la programación de procedimientos. Un ejemplo de esto es un contenedor de IoC , cuyo propósito es inyectar servicios en el código del cliente sin que el código del cliente especifique la implementación concreta. El control en este caso que se invierte es el acto del cliente que obtiene el servicio.

Millett, C (2010). Patrones de diseño profesional ASP.NET. Wiley Publishing. 7-8.


0

// ICO, DI, hace 10 años, de esta manera:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

Ahora con Spring 3,4 o más reciente es como abajo

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

En general, el control se invierte del antiguo concepto de código acoplado a los marcos como Spring, que hace que el objeto esté disponible. Así que eso es IOC hasta donde yo sé e inyección de dependencia como sabes cuando inyectamos el objeto dependiente en otro objeto usando Constructor o setters. Inyectar básicamente significa pasarlo como argumento. En primavera tenemos una configuración basada en XML y anotaciones donde definimos el objeto bean y pasamos el objeto dependiente con el estilo de inyección de Constructor o setter.


0

Encontré el mejor ejemplo en Dzone.com, que es realmente útil para comprender la diferencia real entre COI y DI

"IoC es cuando alguien más crea objetos para ti". Entonces, en lugar de escribir una palabra clave "nueva" (por ejemplo, MyCode c = new MyCode ()) en su código, el objeto es creado por otra persona. Este 'alguien más' normalmente se conoce como un contenedor de IoC. Significa que entregamos la responsabilidad (control) al contenedor para obtener la instancia del objeto se llama Inversión de control. En lugar de que esté creando un objeto con un nuevo operador, deje que el contenedor lo haga por usted.

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

Leer artículo completo COI y Leer artículo completo DI


0

1) DI es Child-> obj depende de parent-obj. El verbo depende es importante. 2) IOC es Child-> obj realizar bajo una plataforma. donde la plataforma podría ser la escuela, la universidad, la clase de baile. Aquí realizar es una actividad con implicación diferente bajo cualquier proveedor de plataforma.

ejemplo práctico: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

``

-AB


0

En cuanto a esta pregunta, diría que el wiki ya ha proporcionado explicaciones detalladas y fáciles de entender. Citaré lo más significativo aquí.

Implementación de IoC

En la programación orientada a objetos, existen varias técnicas básicas para implementar la inversión de control. Estos son:

  1. Uso de un patrón de localización de servicio Uso de inyección de dependencia, por ejemplo, inyección de constructor Inyección de parámetros Inyección de setter Inyección de interfaz;
  2. Usando una búsqueda contextualizada;
  3. Usando el patrón de diseño de método de plantilla;
  4. Usando el patrón de diseño de estrategia

En cuanto a la inyección de dependencia

La inyección de dependencia es una técnica mediante la cual un objeto (o método estático) suministra las dependencias de otro objeto. Una dependencia es un objeto que se puede usar (un servicio). Una inyección es el paso de una dependencia a un objeto dependiente (un cliente) que lo usaría.


0

El concepto de IoC se escuchó inicialmente durante la era de la programación de procedimientos. Por lo tanto, desde un contexto histórico, IoC habló sobre la inversión de la propiedad del control de flujo es decir, quién es el responsable de invocar las funciones en el orden deseado, ya sean las funciones mismas o si debe invertirlas en alguna entidad externa.

Sin embargo, una vez que surgió la OOP, la gente comenzó a hablar sobre la IoC en el contexto de la OOP, donde las aplicaciones también se ocupan de la creación de objetos y sus relaciones, aparte del flujo de control. Dichas aplicaciones querían invertir la propiedad de la creación de objetos (en lugar del flujo de control) y requerían un contenedor que sea responsable de la creación de objetos, el ciclo de vida del objeto y las dependencias de inyección de los objetos de la aplicación, eliminando así los objetos de la aplicación de la creación de otro objeto concreto.

En ese sentido, DI no es lo mismo que Io C , ya que no se trata de control de flujo, sin embargo, es una especie de Io * , es decir, Inversión de la propiedad de la creación de objetos.

¿Qué hay de malo en mi forma de explicar DI y IoC?


0

IoC, también conocido como Inversión de control, se refiere al control de creación de instancias que realiza el contenedor Spring. El control para crear y construir objetos se encarga del contenedor. El contenedor crea los objetos y los inyecta en nuestra aplicación.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.