Siempre me había intrigado por AOP y es que la idea de programar basado en aspectos en lugar de funciones o metodos o código secuencial es bastante atractiva. Obviamente no es para todo código, pero hay muchos "aspectos" que quisieramos poder tener encapsuladas y no sólo en un objeto, sino, despreocuparnos y no tener que invocarlas nosotros mismos.
Ejemplo Simple - Logging.
Pensemos que queremos loggear excepciones.
Ok, ese el código feo de novato. Ahora refactoricemos un poco. Podría estar en una clase y para cuestiones de la prueba hagamosla estática.
Ahora apliquen eso a todos los metodos de la clase. ¿Qué? Bueno supongan que nos interese enterarnos en nuestro archivo de Log de todos los lugares donde lleguue a ocurrir una excepción. Vamos a convertir esto en un aspecto. Refactoricemos de nuevo.
Simplemente hicimos nuestra clase serializable (necesario por PostSharp), hereda de OnExceptionAspect, overrideamos el Metodo OnException y listo, Logueamos tal como antes.
Ahora simplemente decoramos nuesto metodo con nuestro nuevo atributo, corremos la app y listo. El atributo también podría ir en una clase y aplicarle algunos filtros. Estas son sólo algunas de las posibilidades.
Puedes descargar el código aquí
Por mantener breve el ejemplo, la clase loggin es muy simple, en una aplicación real sugeriría usar el Loggin Application Block que es parte del Enterprise Library o Log4Net, ambos son open source y podrían integrarse con PostSharp.
Para un ejemplo aún más simple que este, vean el Video de Intro de PostSharp. El ejemplo me parecio poco práctico, sin embargo, es muy ilustrativo respecto a como usar la herramienta y sólo dura 5 minutos. Pueden bajar el código del video aquí.
Otro Ejemplo Simple - HttpSimulator
Hace algún tiempo escribi respecto al HttpSimulator, desde entonces lo hemos tenido que usar muchas veces para simular el contexto de Http en clases que dependen de algun objeto de ASP.NET y queremos probarla sin necesidad de que tenga dependencias a los objetos reales del framework, es decir, no queremos tener que usar realmente sesión y pasar por todo el pipeline de un request web, sólo para probar un simple metodo.
En el código a descargar viene todo el HttpContext, ahorita nos enfocaremos a las pruebas unitarias, estilo TDD para el HttpContext y como usarlo con PostSharp, en la prueba usaremos un WebDependentClass
Eso esperamos que arroje una excepcion, ya que WebDependentClass se debería ejecutar en un contexto web para que pueda usar HttpContext.Current tal como se muestra.
Ahora veamos como se haría esto con el HttpSimulator para lo que creamos otra prueba.
Es simple, se obtiene el path, se crea la instancia, se empieza a simular el request, se hace lo que se tenga que hacer y al salir del using se ejecuta el dispose y termina la simulación. Nuestra prueba pasa y todos contentos. Sólo que es mucha talacha. Puede haber 126 pruebas más que usen el Simulator. Aunque se podría simplificar un poco la creación, terminaríamos aún así con código repetido y el using no tenemos manera de evitarlo.
Con AOP, tenemos algo como lo siguiente:
El atributo se encarga de todo, inclusive si todas las pruebas de nuestro TestClass o nuestro Assembly de pruebas necesitaran del simulador podríamos definir el atributo a nivel de clase o assembly para aplicarles el mismo aspecto.
La implementación del atributo es de lo más simple. Tal como hicimos con el Logging, tenemos la clase serializable y hereda de un atributo predefinido en PostSharp.
Parece un Surround with snippet no? Es similar sólo que para tiempo de compilación.
Si quieres usarlo en tus pruebas, simplemente agrega el Assembly HttpSimulator y el atributo a las que dependan de un contexto Http. Puedes bajar el código de aquí.
Links
Downloads
SuperSimpleSample
LoggingSample
Attribute para el HttpContextSimulator
Todos los samples de este post
PostSharp Installer
PostSharp
PostSharp en .NET Rocks
PostSharp
Video de Intro de PostSharp
Suscribete