Qué es la Inyección de Dependencias?

El año no puede terminar sin que antes aprendamos de inyección de dependencia. En este articulo aprenderemos de forma clara y sencilla que son inyecciones de dependencia como patrón de diseño, por qué se usan, cuáles son sus ventajas, y por último, daremos una ojeada a sus dos variantes: inyección de dependencia por constructor e inyección de dependencia por propiedades.

En los comienzos de la programación, los programas eran lineales y monolíticos. El flujo de ejecución era simple y predecible, ejecutándose línea tras línea.

Aparecieron dos conceptos para estructurar el código: la modularidad y la reutilización de los componentes: se crean bibliotecas de componentes reutilizables. El flujo se complica, saltando de componente a componente, y aparece un nuevo problema: la dependencia (acoplamiento) entre los componentes.

El problema de la dependencia se empieza a considerar lo suficientemente importante como para definir nuevos conceptos en el diseño :

  • Inversión de control (IoC).
  • Inyección de Dependencias (DI), que es una forma de inversión de control.

A medida que nuestras aplicaciones crecen, algunas partes de ella necesitan comunicarse con otros módulos. Cuando un módulo A necesita a un módulo B para funcionar, decimos que B es una dependencia de A.

Una de las formas más comunes para acceder a las dependencias es importando el archivo. Instanciando hipotéticamente este módulo, hacemos lo siguiente:

  1. // in A.ts
  2. import {B} fromB‘; // una dependencia!
  3. .
  4. B.foo(); // using B

En muchos casos, importar el archivo, es suficiente, sin embargo, en otras no resulta tan sencillo pues necesitamos proveer las dependencias de una manera más sofisticada. Aquí es donde entran en juego la inyección de dependencias.

Lay down your shoes along the walls of your bag. This helps create more space for your other items. (2).png


light-bulb

Otra forma de entender al “inyector” es como un remplazo al operador new .  En lugar de utilizar el nuevo operador provisto por el lenguaje, la Inyección de Dependencia nos permite configurar cómo se crean los objetos.


airplaneAterricemos los conceptos con un ejemplo.

 

Imagínese que usted como piloto de avión comercial, cada vez que tenga pilotear tuviera que llenar el tanque de combustible, preparar la pista, verificar que todo esta listo para el despegue, sabemos que no es humanamente posible, por eso existen distintas personas trabajan en conjunto para que sea posible el despegue. Entonces si adaptamos esta situación a nuestro idioma. Tendríamos que:

report

El aeropuerto hace la función de Contenedor de dependencia, pues se encarga de gestionar todo el proceso para que los vuelos puedan tener lugarLos controladores aéreos,  hacen la función de Framework, pues se encargan de inyectar las dependencias  a los módulos dependientes y gestionar los recursos para que los módulos puedan funcionar correctamente, las interfaces son los lineamientos que se necesitan para que el avión pueda aterrizar. Todos elementos en conjunto conforman la inyección de dependencia y la inversión de control.

Cuando un piloto va aterrizar en una pista, necesita tener el espacio para poder descender y que el transito actual del aeropuerto no interfiera con su aterrizaje. Pero el no va a comunicarse directamente con  el controlador de Tierra o el controlador de Ruta o Área. En lugar de ello, se comunicara con la torre de control quien se encarga de gestionar todo el proceso y darle toda la información que necesita para el aterrizaje.

Ventajas de Utilizar Inyección de Dependencias

Flexible

– No hay necesidad de tener un código de búsqueda en la lógica de negocio.

–Elimina el acoplamiento entre módulos

Testeable

– No se necesita un espacio especifico de testeo

–Testeo automático como parte de las construcciones

Mantenible

– Permite la reutilización en diferentes entornos de aplicaciones modificando los archivos de configuración en lugar del código.

– Promueve un enfoque coherente en todos aplicaciones y equipos


magic-wand

Convirtiendo en Código

Como mencionamos anteriormente existen varios tipos de inyección de dependencia: Inyección por constructor,  inyección por propiedad.

Inyección por Constructor

public class LogicaNegocio
{
    IAccesoDataCliente _dataAccess;

    public LogicaNegocio(ICustomerDataAccess custDataAccess)
    {
        _dataAcceso = custDataAccess;
    }

    public LogicaNegocio()
    {
        _dataAcceso = new GetDataCliente();
    }

    public string ProcesoDataCliente(int id)
    {
        return _dataAcceso.GetNombreCliente(id);
    }
}

public interface IAccesoDataCliente
{
    string GetDataCliente(int id);
}

public class AccesoDataCliente: IAccesoDataCliente
{
    public AccesoDataCliente()
    {
    }

    public string GetNombreCliente(int id) 
    {
        //obtener el nombre del cliente desde una BD     
        return "Dummy Customer Name"; 
    }
}

En el ejemplo anterior, LogicaNegocio incluye constructor con un parámetro de tipo IAccesoDataCliente. Ahora, la clase de llamada debe inyectar un objeto de IAccesoDataCliente.

Ejemplo: Inyección de Dependencia

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}

Inyección por Propiedades

En la inyección de propiedad, la dependencia se proporciona a través de la propiedad pública. Considera el siguiente ejemplo.
Example: Property Injection

public class CustomerBusinessLogic
{
    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        return DataAccess.GetCustomerName(id);
    }

    public ICustomerDataAccess DataAccess { get; set; }
}

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic();
        _customerBL.DataAccess = new CustomerDataAccess();
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}

Como puede ver arriba, la clase CustomerBusinessLogic incluye propiedad pública llamada DataAccess donde establece una instancia de una clase que ha implantado ICustomerDataAccess. Entonces, la clase CustomerService crea y establece la clase CustomerDataAccess usando esta propiedad pública.


Conclusiones

La inyección de dependencia es un tema bastante amplio que requiere que aprendamos la teoría, para posteriormente aplicarlo en nuestro código, ya sea por medio del constructor o por medio de propiedades.


Qué sigue?

En este articulo abarcamos los aspectos más importantes de la inyección de dependencia, aprendimos como se usa, el porqué es útil, sin embargo, hemos dejado un cabo suelto muy importante, la inversión de control, la próxima vez analizaremos de forma detenida y detallada este tema.

Hasta la próxima, no olviden dejarme sus opiniones y compartir este articulo.

 

Anuncios