En el vídeo que acompaña a este post explico con un sencillo ejemplo cómo utilizar el contenedor de dependencias Unity en un proyecto ASP.NET MVC (ya sabéis, la conocida implementación de Microsoft del patrón Modelo-Vista-Controlador). Pero antes, voy a tratar de explicar los conceptos que implementa Unity.

Qué es la inyección de dependencias

La inyección de dependencias es un patrón de diseño de software usado en la Programación Orientada a Objetos, que trata de solucionar las necesidades de creación de los objetos de una manera práctica.

Lo que dice es que los objetos nunca deben construir aquellos otros objetos que necesitan para funcionar. Esa parte de creación de los objetos se debe hacer en otro lugar diferente a la inicialización de un objeto. Tenemos, por tanto, una posible separación del código en dos partes, una en la que creamos los objetos y otra en la que los usamos.

En realidad es tan sencillo como apreciar que al constructor de los objetos se le están pasando aquellas dependencias que ellos tienen para poder realizar sus tareas. El hecho en sí, de enviar por parámetros los objetos que son necesarios para que otro objeto funcione, es la inyección de dependencias.

En escenarios de producción, hay muchos objetos que dependen de otros objetos. Dado el patrón de inyección de dependencias, necesito tener listos todos los objetos de los que depende el que voy a construir.

Contenedores de dependencias

Imaginad que una interfaz tiene una implementación de otras dos y éstas a su vez implementan otras interfaces. Obtendremos una jerarquía de dependencias cuyo manejo en tiempo de diseño es imposible de gestionar “manualmente”; es aquí donde entra en juego el término contenedor.

El principal cometido de un contenedor es el de gestionar el ciclo de vida de los objetos.

El contenedor registra una implementación específica para cada tipo de interfaz y retorna una instancia de objeto por muchas dependencias que tenga. ¿Dónde está la magia? el contenedor de dependencias simplemente tiene todos los objetos que puedas necesitar para crear cualquier objeto complejo y si no cuenta en ese instante con las dependencias necesarias, sabe cómo conseguirlas en el acto.

Las ventajas del uso de contenedores son, por un lado, que esta resolución de objetos tiene lugar en un único punto de las aplicaciones, por otro, que el contenedor puede resolver dependencias complejas de forma transparente y si quieres modificar una dependencia para cambiar el comportamiento, lo único que debes modificar es el contenedor.

El contenedor es implementado por un framework externo a la aplicación (Unity en mi caso).

El uso de este contenedor de dependencias ya depende del lenguaje que estés usando y el framework con el que trabajes. Además, habitualmente hay que hacer algunas configuraciones básicas para que funcione.

Inversión de control

Si hablamos de inyección de dependencias tenemos que mencionar la inversión de control. Aún hoy hay debate acerca de si es un principio, un patrón o ambas cosas a la vez.

La inversión de control invierte el flujo de control de un sistema en comparación con la programación estructurada y modular. En la inversión de control se especifican respuestas deseadas a sucesos o solicitudes de datos concretas, dejando que algún tipo de entidad o arquitectura externa lleve a cabo las acciones de control que se requieran en el orden necesario y para el conjunto de sucesos que tengan que ocurrir.

Es el principio subyacente a la técnica de inyección de dependencias.