Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 23 de julio de 2013
ASP.NET MVCLas novedades de Unity 3 no acaban en la inclusión del soporte directo para ASP.NET MVC, o en la introducción de convenciones para facilitarnos el registro de componentes, no. La extensión específica para MVC incluye otra característica muy demandada por los desarrolladores, que es la capacidad de realizar inyección de dependencias en filtros (action filters).

En este post vamos a ver cómo está construida, y cómo podemos usarla en nuestras aplicaciones.

imageLa “magia” que permite inyectar dependencias a los filtros la encontramos, en primer lugar, en el archivo UnityMvcActivator.cs que la instalación a través de Nuget habrá dejado en nuestra carpeta App_Start del proyecto.

Como sabemos, en este archivo encontramos la clase estática UnityWebActivator, cuyo método Start() es ejecutado automáticamente por obra y gracia de WebActivator durante el arranque de la aplicación sin necesidad de tocar el global.asax.

Pues bien, en ella podemos ver el siguiente código, que elimina el proveedor de filtros por defecto (FilterAttributeFilterProvider) y añade el nuevo proveedor incluido en el adaptador de Unity para MVC (UnityFilterAttributeFilterProvider):
FilterProviders.Providers.Remove(
    FilterProviders.Providers
        .OfType<FilterAttributeFilterProvider>()
        .First()
);

FilterProviders.Providers.Add(
    new UnityFilterAttributeFilterProvider(container)
);
Como hemos comentado en varias ocasiones por aquí, muchos mecanismos de ASP.NET MVC está construidos usando abstracciones que permiten tomar el control en muchos puntos del pipeline de ejecución de las peticiones. En el caso que nos ocupa, cada vez que ASP.NET MVC tiene que obtener los filtros asociados a una acción, en vez de ir a buscarlos directamente a los atributos del método, se los solicita a los proveedores de filtros; la implementación de proveedor por defecto (FilterAttributeFilterProvider), es la que acude a los metadatos de las clases para obtener los atributos.

El proveedor de filtros provisto por Unity.Mvc (UnityFilterAttributeFilterProvider) hereda del proveedor por defecto y lo usa para recuperar los filtros asociados a las acciones, pero antes de retornarlos insertará en ellos las dependencias que hayamos indicado que necesitan.

Sin embargo, en esta ocasión, el hecho de que los filtros sean atributos cambian un poco las reglas del juego, la forma en que se inyectarán las dependencias. En clases normales, casi siempre nos va a interesar inyección de dependencias en su constructor, por ser la técnica más limpia y explícita para conseguirlo (aunque hemos visto que existen otras formas); sin embargo, dado que los atributos son instanciados directamente por la plataforma .NET, la inyección de parámetros al constructor no es posible.

En este caso, usaremos otra técnica denominada inyección de propiedades. Básicamente, consiste en definir sobre nuestra clase las propiedades en las que introduciremos las dependencias, y marcarlas con el atributo [Dependency], que permitirá a Unity saber que es ahí donde tiene que resolver los tipos e inyectar instancias. Lo vemos en código:
public class MyFilterAttribute: ActionFilterAttribute
{
    [Dependency]
    public IProductServices ProductServices { get; set; }

    [Dependency]
    public ILogger Logger { get; set; }

    public override void OnActionExecuting(
                            ActionExecutingContext filterContext)
    {
        // TODO    
    }
}
Este filtro ya podemos usarlo en cualquier controlador o acción como la siguiente:
[MyFilter]
public ActionResult Action()
{
    // TODO
    return View();
}
Al realizar una petición contra esta acción, ASP.NET MVC acudirá a los proveedores para ver qué filtros tiene asociados. La clase UnityFilterAttributeFilterProvider ejecutará la lógica por defecto, heredada de su antecesor FilterAttributeFilterProvider, por lo que obtendrá los filtros a partir de los atributos registrados en los metadatos de la clase, pero antes de retornarlos los examinará para comprobar si tienen propiedades decoradas con [Dependency], en cuyo les insertará una instancia del tipo solicitado. Así, al llegar el momento de ejecutarse los distintos métodos disponibles en los filtros, tendremos ya las dependencias satisfechas.

¿Sencillo, eh? La verdad es que no es algo que no pudiéramos conseguir de forma manual, o utilizando otros contenedores de IoC, pero se agradece que lo hayan incluido en Unity y lo hayan puesto tan fácil de usar.

Publicado en Variable not found.

1 comentario:

Nicolas dijo...

Graciass era lo que estaba bucandoo