¿Qué es la inversión de control y cuándo debo usarla?

Respuestas:

62

IoC (ver Inversión de control en Wikipedia) es aplicable en los casos en que un componente no puede realizar una tarea por completo porque no tiene alguna información o funcionalidad necesaria.

El ejemplo más simple de un patrón IoC serían las funciones de devolución de llamada en C. Por ejemplo, puede declarar la función:

void Iterator(void *list, Func* f)

Que itera sobre la listaplicación de la ffunción a cada uno de sus elementos. La Iteratorfunción no sabe cómo se procesará cada elemento, solo proporciona una función como argumento y los procesa.

Como muestra el ejemplo anterior, IoC le permite desacoplar su programa en componentes separados que no se conocen entre sí. Una de las versiones más comunes de IoC es la inyección de dependencia .

En Inyección de dependencias, cada componente debe declarar una lista de dependencias necesarias para realizar su tarea. En tiempo de ejecución, un componente especial (generalmente) llamado IoC Container realiza el enlace entre estos componentes. Intenta proporcionar valores para las dependencias de componentes publicadas.

Aquí hay un ejemplo en pseudocódigo:

class Foo 
{ 
   <Require Boo>Constructor(Boo boo){ boo.DoSomething } 
}

En este ejemplo, la clase Footiene un constructor que requiere un argumento de tipo Boopara realizar alguna acción.

Puede crear una instancia de clase Foousando un código similar a este:

MyContainer.Create(typeof Foo)

MyContainer- es un IoC Container , que se encarga de obtener la instancia Booy pasarla al Fooconstructor.

En resumen, IoC le permite desacoplar su programa en partes separadas. Esto es bueno porque:

  • Los componentes se pueden probar fácilmente de forma independiente.
  • La complejidad del programa se puede reducir.
  • Puede cambiar componentes a otra implementación.

Sin embargo, en algunos casos, IoC puede hacer que el código sea más difícil de entender.

Si desea ver un buen ejemplo del uso de IoC en el mundo real , eche un vistazo a Mircosoft Composite UI Application Block y CompositeWPF

Espero que mi explicación te ayude.

Saludos,
aku


fuente
1
Cinco años después, pero aún así ... Esa fue una excelente descripción. Gracias.
Nick Hodges
44
No se menciona mucho en ninguna parte sobre IoC el hecho de que el código se vuelve más difícil de leer. La legibilidad es la prioridad número uno si desea escribir un excelente software. Incluso supera a la Testabilidad. Puede desacoplar el código más allá de su utilidad.
Arne Evertsson
Entonces, ¿un código que usa una solución basada en interfaz para todas sus dependencias también se basa en el diseño de IoC?
nikel
4

Hola JMS, básicamente IoC / DI te permitirá definir qué implementación estás usando una vez y mantener una copia estática de tu contenedor para referenciar cada vez que quieras hacer referencia a ella.

La Wikipedia probablemente lo ayudará, pero quería hacer referencia a su segunda parte: sí, la inyección de dependencia se puede hacer para las clases (es decir, cada vez que este tipo de clase deba pasarse a un método, use esta clase), pero es mejor use interfaces, porque de esa manera puede cambiar qué versión de un proveedor, repositorio, etc. está usando simplemente haciendo referencia a ella en su configuración.

IE, digamos que tenía una interfaz para leer una secuencia, y tenía una implementación XMLStreamReader y SQLStreamReader. Luego puede pasar la referencia a la interfaz a sus métodos y luego, en su contenedor IoC, indicarle cuál usar.

Por lo tanto, puede tener List ReadPeople público (lector IStreamReader) y, en su configuración para su contenedor IoC, dígalo, cada vez que espere que un IStreamReader use SQLStreamReader.

Luego, si cambia de opinión más tarde, solo necesita cambiarlo en un solo lugar (la configuración de su contenedor) y no importa cuántos métodos solicite un IStreamReader, siempre obtendrá el valor predeterminado que le dijo a su contenedor servir.


fuente
3

Supongamos que tiene un validador para verificar si una empresa es válida o no en su sistema. Su "BusinessValidator" puede tener un campo de tipo AddressValidator que valida la parte de dirección de la empresa. Si desea probar el BusinessValidator sin ejecutar un código externo (es decir, el código del AddressValidator), si ha utilizado algún tipo de IoC / DI en su marco, puede "inyectar" fácilmente un AddressValidator falso en su lugar y no tener que preocuparse por probar código fuera del alcance de la clase bajo prueba.

codeLes
fuente