Introducción a la Programación Orientada a Aspectos (AOP) con Postsharp (@postsharp).

miércoles, 23 de octubre de 2013


La programación orientada a aspectos (AOP  Aspect Oriented Programming) es un paradigma de programación cuyo objetivo es reducir el código duplicado que suele existir en relación a los aspectos trasversales de una aplicación como creación de logs, control de excepciones, gestión de cache, temas de seguridad.

A mi forma de entender la programación orientada aspectos comparado con la programación orientada a objetos, es que esta última con las clases base permite la reutilización de código entre componentes comunes y la programación orientada a aspectos con atributos permite la reutilización de código entre componentes no comunes.


Aquí dejo el enlace de wikipedia para ampliar información sobre AOP.

Para .Net tenemos varios frameworks pero uno que me gusta mucho es Postsharp.

Vamos a ver unos ejemplos de utilización de este framework.

Creamos un proyecto de consola y mediante NuGet añadimos Postsharp


Después aparece un asistente donde indicas si quieres la versión libre express, una de pago o una de prueba de 45 días. Yo he seleccionado una libre express y te lleva a la web de Postsharp para que solicites una clave que te envían por correo. Después de insertar la clave en el asistente ya podemos empezar nuestros ejemplos.

En los proyectos una práctica habitual suele ser la toma de tiempos, un bloque de código que tenemos que repetir donde queremos tomar tiempos en nuestra aplicación de consola sería este.

//codigo al principio del método
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();       

    watch.Start();
    Console.WriteLine("Inicio Metodo x. Tiempo {0}");

    //lo que sea que hace el metodo
    //lo que sea que hace el metodo
    //lo que sea que hace el metodo

    //codigo al final del método
    watch.Stop();
    Console.WriteLine(string.Format("Fin Metodo x. Tiempo {0}",watch.ElapsedMilliseconds));


Pata el código del principio del método y para el código del final podemos crear un aspecto (Apect), en AOP un aspecto es un trozo de código transversal reutilizable. Un aspecto no deja de ser un atributo de .Net al que postsharp le añade funcionalidad muy interesante.

En la forma tradicional de .Net nos creariamos un atributo de esta forma.
public sealed class TimeTraceAspect: Attribute
    {
        private readonly string _name;

        public TraceTimeAspect(string name)
        {
            _name = name;
        }

        public TraceTimeAspect()
        {
        }
    } 

En postsharp hay un tipo de aspecto (atributo) que se llama OnMethodBoundaryAspect donde podemos añadir código a ejecutar al inicio y al final del método que decoremos con este atributo. Esta nueva funcionalidad que se añade, en AOP se llama consejo (Advice). Para ello modificamos nuestro atributo de esta forma:
[Serializable] 
    public sealed class TimeTraceAspect: OnMethodBoundaryAspect
    {
        private readonly string _name;

        [NonSerialized]
        System.Diagnostics.Stopwatch watch;

        public TraceTimeAspect(string name)
        {
            _name = name;
        }

        public TraceTimeAspect()
        {
        }

        public override void OnEntry(MethodExecutionArgs args)
        {
            watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            Console.WriteLine(string.Format("Inicio Metodo {0}", _name ?? args.Method.Name));
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            watch.Stop();
            Console.WriteLine(string.Format("Fin Metodo {0}. Tiempo {1}", _name ?? args.Method.Name, watch.ElapsedMilliseconds));
        } 
    } 

Sobreescribimos los metodos OnEntry y OnExit para añadir nuestro código a ejecutar al inicio y al final del método. Los attributos de Postsharp tienen que ser serializables y los campos que contengan, como en nuestro caso watch, deben ser marcados para que no se serializen.

Entonces ahora ya podemos decorar con el atributo TimeTraceAspect métodos en nuestra clase program del proyecto de consola.
class Program
    {
        static void Main(string[] args)
        {
            Method1();
            Method2();
            Console.Read();
        }

        [TimeTraceAspect("Metodo uno")]
        private static void Method1()
        {
            System.Threading.Thread.Sleep(1000);
        }

        [TimeTraceAspect]
        private static void Method2()
        {
            System.Threading.Thread.Sleep(2000);
        }
    }


Y nuestro resultado en la consola será este



Con esta introducción hemos visto un ejemplo sencillo con el tipo de aspecto OnMethodBoundaryAspect de postsharp, en futuros post veremos más ejemplos de Postsharp con otros tipos de aspectos.

Código fuente

No hay comentarios:

Publicar un comentario