Inyección de dependencias en ASP.NET MVC usando Unity

Unity es un Contenedor de Inyección de Dependencias o DI Container desarrollado por el equipo de Patterns & Practices de Microsoft, y sin duda es uno de los más populares y usados componentes hoy en día. Unity brinda todas las herramientas necesarias para poder desarrollar aplicaciones con bajo acoplamiento. Si quieres profundizar sobre los conceptos de inyección de dependencias y otros relacionados, te invito a visitar los artículos de mi blog al respecto. En este artículo, vamos a ver como podemos implementar Unity en nuestros proyectos ASP.NET MVC.

Antes de meternos con Unity, crearemos un proyecto de código ASP.NET MVC en Visual Studio con una estructura muy básica. Una vez creado, iniciaremos por agregar una clase «repositorio» con el siguiente código en el proyecto:

public class NumberRepository
{
    public List<int> GetNumbers()
    {
        return new List<int>() { 1, 2, 3, 4, 5 };
    }
}

Para efectos de este ejemplo, tenemos una lista de valores fijos en el código, pero una clase así perfectamente puede ser la que usemos para traer los datos a nuestra aplicación desde una fuente externa, ya sea base de datos, servicios web, etc.

Ahora, vamos a crear un controlador ASP.NET MVC, el cual va a consultar los datos del repositorio y los va a enviar a una vista para ser visualizados por el navegador.

public class NumberController : Controller
{
    // GET: Numbers
    public ActionResult Index()
    {
        NumberRepository repo = new NumberRepository();
        IEnumerable<int> numbers = repo.GetNumbers();
 
        return View(numbers);
    }
}

Finalmente, agregamos una vista para representar los datos en pantalla. El código de la vista es un poco extenso, así que no lo voy a incluir en este artículo, pero puedes verlo en el código fuente publicado al final del post.

Si ejecutamos nuestra aplicación, tendremos el siguiente resultado:

UnityDemo_01

Podriamos decir que nuestra aplicación funcionó, pero… ¿recuerdas el concepto sobre el Principio de Inversión de Dependencias en SOLID?… Si la idea es no depender directamente de componentes sino de abstracciones, ¿cómo podemos mejorar nuestro código?… Bien, si vamos a mirar el código del controlador que creamos, podemos encontrar que está creando directamente una instancia de la clase NumberRepository, es decir, está dependiendo directamente de ese componente.

Visto esto entonces, manos a la obra y vamos a cambiar eso. Lo primero, será crear una interface de código para el «repositorio» de números que usamos, la cual vendría quedando así:

public interface INumberRepository
{
    System.Collections.Generic.List<int> GetNumbers();
}

Y ahora, cambiamos la clase NumberRepository para que implemente la interface INumberRepository, quedando el código así:

public class NumberRepository : INumberRepository
{
    public List<int> GetNumbers()
    {
        return new List<int>() { 1, 2, 3, 4, 5 };
    }
}

El siguiente paso es modificar el código en el controlador, para que ahora se relacione con la interface INumberRepository y ya no tenga más la relación directa con la clase concreta NumberRepository. El código del controlador es el siguiente:

public class NumberController : Controller
{        
    private readonly INumberRepository _repo;
 
    public NumberController(INumberRepository repo)
    {
        this._repo = repo;
    }        
        
    public ActionResult Index()
    {            
        IEnumerable<int> numbers = _repo.GetNumbers();
 
        return View(numbers);
    }
}

Ahora ejecutamos de nuevo la aplicación web, y podremos ver que en este momento ya no funciona :O

UnityDemo_02

¿Y por qué es este error?… si analizamos el nuevo código del controlador, vemos algunas cosas y surgen las siguientes preguntas: ¿si ahora depende de una interface INumberRepository, cómo usamos la clase NumberRepository y su funcionalidad? ¿quién le inyecta al constructor del controlador el parámetro con la clase repositorio que quiero usar?… bien, aquí es donde entra en juego el Contenedor de Inyección de Dependencias, en nuestro ejemplo: Unity.

Vamos a instalar Unity en nuestro proyecto a través del Nuget Package Manager, allí buscamos los paquetes «Unity» y «Unity bootstrapper for ASP.NET MVC» y seleccionamos la opción Instalar para cada uno.

UnityDemo_03

Una vez instalados, podemos ver que se agregan unos archivos en la carpeta App_Start de nuestro sitio web. Ahora, vamos a modicar la clase UnityConfig que se encuentra dentro de esa carpeta, para que el código del método RegisterTypes se vea de la siguiente manera:

public static void RegisterTypes(IUnityContainer container)
{           
    // Usar la clase NumberRepository cuando se encuentre la interface INumberRepository
    container.RegisterType<INumberRepositoryNumberRepository>();
}

Ahora ejecutamos de nuevo el sitio web, y veremos que ya funciona de nuevo!

UnityDemo_01

Ahora el sitio web funciona de nuevo porque Unity está configurado, y se encargó de «inyectar» una instancia de la clase NumberRepository en nuestro controlador, de acuerdo a las instrucciones que configuramos en el archivo UnityConfig. Ese mismo procedimiento lo haremos con todas las clases/interfaces que necesitemos en nuestros proyectos.

Y bien, hasta acá esta introducción y explicación sobre como configurar Unity en un proyecto ASP.NET MVC. En futuros artículos exploraremos más características que tiene este Contenedor de Inyección de Dependencias.

Si tienes dudas o comentarios sobre el tema del artículo, no dudes en compartirlos!

Puedes descargar el código fuente de este ejemplo en mi cuenta de GitHub

ironcat

12 Responses to Inyección de dependencias en ASP.NET MVC usando Unity

  1. Pingback: Inyección de propiedades usando Unity | hgr.net

  2. Pingback: Resolviendo dependencias nombradas en Unity | hgr.net

  3. Pingback: Inyección de dependencias en ASP.NET con Ninject | hgr.net

  4. Luis F. says:

    Muy buen articulo, por fin lo entiendo de forma rápida y clara, muchas gracias. Saludos.

  5. Hey buenisimo muchas gracias, m e ayudo a implementarlo, mas sin embargo, aun no entiendo como funciona, es decir en que momento de la aplicación se llama al ioc para hag el DI?

  6. Pingback: Inyección de dependencias en ASP.NET con Ninject – Avanet

  7. Pingback: Inyección de propiedades usando Unity – Avanet

  8. Àngel says:

    Una explicación extraordinaria.
    Muchas gracias.

Replica a hgr Cancelar la respuesta