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

63

Estoy diseñando un nuevo sistema y quiero saber qué inversión de control (IOC) es, y lo que es más importante, cuándo usarlo.

¿Debe implementarse con interfaces o puede hacerse con clases?

    
pregunta Jedi Master Spooky 05.09.2008 - 05:32

4 respuestas

61

IoC (consulte 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 list aplicando la función f a cada uno de sus elementos. La función Iterator 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 Inyección de Dependecy .

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

Aquí hay un ejemplo en pseudocódigo:

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

En este ejemplo, la clase Foo tiene un constructor que requiere un argumento de tipo Boo para realizar alguna acción.

Puedes crear una instancia de la clase Foo usando un código similar a este:

MyContainer.Create(typeof Foo)

MyContainer - es un Contenedor IoC , que se encarga de obtener la instancia de Boo y pasarla al constructor Foo .

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.
  • Se puede reducir la complejidad del programa.
  • Puede cambiar los 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 en el mundo real de IoC , eche un vistazo a Mircosoft Bloque de aplicaciones compuestas de UI y CompositeWPF

Espero que mi explicación te ayude.

Saludos,
aku

    
respondido por el aku 05.09.2008 - 05:44
18

Desde que comencé a investigar en esto recientemente y conservé todos los marcadores, a continuación, encontré un valor incalculable para aprender sobre IOC / DI.

Artículo original de Martin Fowlers sobre IOC / DI

Algunos conceptos para saber primero

Una excelente colección de tutoriales IOC / DI

Libro sobre IOC / DI de Manning Press

Fuente y explicación de cómo crear su propio IOC : la lectura del código fuente es siempre la mejor forma de entender un concepto.

    
respondido por el Kris Erickson 05.09.2008 - 06:08
4

Oye JMS, básicamente IoC / DI te permitirá definir qué implementación usarás una vez, y mantendrás una copia estática de tu contenedor como referencia cada vez que quieras hacer referencia a ella.

La Wikipedia probablemente te ayude, pero quería hacer referencia a tu segunda parte, sí, la inyección de dependencia se puede hacer para las clases (es decir, cada vez que este tipo de clase deba pasar a un método, usa esta clase), pero es mejor usar interfaces, ya que de esa manera puede cambiar la versión de un proveedor, repositorio, etc. que está usando simplemente volviendo a hacer referencia a ella en su configuración.

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

Por lo tanto, podría tener Listas de Lectura (Listas de IStreamReader) públicas y en su configuración para su contenedor IoC dígaselo, cada vez que espere que un IStreamReader use SQLStreamReader.

Luego, si cambias de opinión más adelante, solo necesitas cambiarlo en un solo lugar (la configuración de tu contenedor) y no importará cuántos métodos solicites un IStreamReader, siempre obtendrá el valor predeterminado que dijiste su contenedor para servir.

    
respondido por el crucible 05.09.2008 - 06:00
3

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

    
respondido por el codeLes 05.09.2008 - 06:48

Lea otras preguntas en las etiquetas