Definiendo Inversion of Control and Dependency Injection

Después de algunos ejemplos de código, dentro del Proyecto Hogwarts:

Introducción a IoC y DI: Otro ejemplo web
Introducción a IoC y DI: Un ejemplo web
Introducción a IoC y DI: Hello, world flexible

veamos de definir los términos Inversion of Control (Inversión de Control) y Dependency Injection (Inyección de Dependencias).

Recordemos lo que vimos en los ejemplos: los objetos no funcionan solos, forman un grafo de objetos. Algunos objetos colaboran con otros. Se dice entonces que los objetos consumidores tienen dependencia de los objetos que consumen como ayudantes. En una aplicación real, el mantener las dependencias puede irse complicando, debido a la cantidad de clases y responsabilidades. También, puede que querramos modificar las implementaciones. Vimos que nos conviene ir definiendo interfaces, y referirse a ellas, para no ligar los objetos consumidores a implementaciones concretas.

Inversion of Control refiere, entonces, a que el objeto consumidor no crea los objectos ayudantes, de los que depende. No se le adosa esa responsabilidad. Como vimos en los ejemplos, en esos objetos desaparece el "new" de los objetos ayudantes.

Dependency Injection se refiere a una forma de implementar IoC: el objeto consumidor recibe sus dependencias en propiedades o en argumentos de constructor.

Recordemos el ejemplo de servicio consumiendo repositorio, gráficamente:

El código de nuestro servicio no tenía new (con lo que tiene Inversion of Control). Pero bien podría haber pedido expresamente a otro que le diera el objeto, como en:

public class CustomerService
{
    private ICustomerRepository repository;
    public CustomerService()
    {
        this.repository = Registry.GetInstance<ICustomerRepository>();
    }
    public IEnumerable<Customer> GetCustomers()
    {
        return repository.GetAll();
    }
}


En este caso, sería simplemente Inversion of Control: alguien, la clase Registry, tendría la responsabilidad de ubicar o crear la instancia a usar. Pero CustomerService pide esa resolución explícitamente.

En cambio, el código de nuestro ejemplo era:



public class CustomerService
{
    private ICustomerRepository repository;
    public CustomerService(ICustomerRepository repository)
    {
        this.repository = repository;
    }
    public IEnumerable<Customer> GetCustomers()
    {
        return repository.GetAll();
    }
}


Acá apareció Dependency Injection: CustomerService ni siquiera pide el repositorio, alguien de afuera se lo da. Tenemos que estudiar que podemos usar librerías llamadas contenedores de IoC que nos facilitan la inyección automática de esas dependencias.



No necesariamente se inyecta un solo objeto: otras clases más complejas podrán necesitar de más objetos inyectados. Tenemos que investigar formas de inyectarle esas dependencias. Por ahora, lo vimos “manualmente”: vamos a ver que hay librerías llamadas IoC Containers, contenedores de Inversion of Control, que nos pueden ayudar a armar el grafo que necesitamos en un contexto (en producción, en pruebas TDD, etc…)




Artículos en inglés para consultar con más detalles:




Inversion of Control Containers and the Dependency Injection pattern (Martin Fowler)
Inversion of Control and Dependency Injection: Working with Windsor Container



Mis enlaces sobre el tema:



http://delicious.com/ajlopez/ioc
http://delicious.com/ajlopez/di



Nos leemos!



Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

This entry was posted in 13620, 14126, 14127. Bookmark the permalink.

2 Responses to Definiendo Inversion of Control and Dependency Injection

  1. Mak says:

    No se quien sos xD pero parece que sos el unico quien entendio el tema, es laprimera vez que veo la explicacion tan clara.. Por fin!
    Gracias.

  2. Joe says:

    Muy buena la explicación. Mil gracias!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>