Páginas

jueves, 3 de septiembre de 2015

Creando un cronometro para medir tiempo de ejecución de nuestros metodos

Hubo muchas veces que por cuestiones de perfomance necesitaba saber el tiempo de respuesta de cada invocación a un método, por ejemplo muchas veces sobre consultas a bases de datos. 

Cansado de usar la clase StopWatch y repetir siempre la misma lógica , decidí crearme un cronometro para tomar el tiempo de cualquier método. El post lo voy a hacer breve, así que explico rápidamente algunas características y al final esta el ejemplo para descargar: 


  • Clase Cronometro con 3 métodos estáticos TomarTiempo, la respuesta a la toma del tiempo es una instancia de la clase CronometroResultado que contiene un TimeSpan (fraccion de tiempo) , resultado del método invocado y un flag que indica si el metodo fue encontrado.
  • Soporte para metodos con y sin parámetros.
  • TomarTiempo se encarga de buscar el metodo por nombre y coincidencia de cantidad y tipo de parametros.
  • Busquedas usando Reflection.
  • Aun no tiene soporte para métodos genéricos.
  • No importa el orden en que se envian los parametros, TomarTiempo se encarga de buscar el coincidente.

La verdad que me resulta mucho mas comodo ahora medir los ticks, milisegundos , segundos ,etc con esta forma , acá va la clase completa y como dije al final el fuente ..... lo demas para que lo investiguen ... 




Clase Cronometro ....


  public class Cronometro
    {

        /// 
        /// Usar esta carga para invocar metodos de instancia
        /// 
        /// Tipo de la clase que contiene el metodo. Ejemplo: typeof(MiClase)
        /// Nombre del metodo, no es case sensitive
        /// Array de object con los parametros que se le pasaran al metodo encontrado
        /// CronometroResultado
        public static CronometroResultado TomarTiempo(object instance, string nombreMetodo, object[] arguments)
        {
            return TomarTiempo(instance.GetType(), instance, nombreMetodo, arguments);
        }

        /// 
        /// Usar esta carga para invocar metodos estaticos
        /// 
        /// Tipo de la clase que contiene el metodo. Ejemplo: typeof(MiClase)
        /// Nombre del metodo, no es case sensitive
        /// Array de object con los parametros que se le pasaran al metodo encontrado
        /// CronometroResultado
        public static CronometroResultado TomarTiempo(Type type, string nombreMetodo, object[] arguments)
        {
            return TomarTiempo(type, null, nombreMetodo, arguments);
        }

        internal static CronometroResultado TomarTiempo(Type tipo, object instance, string nombreMetodo, object[] arguments)
        {

            MethodInfo ejecutar = null;


            bool searchStatics = instance == null;

            nombreMetodo = nombreMetodo.ToLower();

            //buscar dentro de los metodos encontrados si alguno coincide con los parametros enviados
            MethodInfo[] metodos =
                tipo.GetMethods().Where(m => m.Name.ToLower() == nombreMetodo & m.IsStatic == searchStatics).ToArray();

            //Soporte para metodos que no tienen parametros de entrada 
            if (arguments == null || arguments.Length == 0)
            {
                ejecutar = metodos.Where(m => m.GetParameters().Length == 0).FirstOrDefault();
            }
            else
            {
                //entre todos los metodos busco los parametros que coincidan
                foreach (var met in metodos)
                {
                    ParameterInfo[] pars = met.GetParameters();

                  
                    //coincide busco el orden de los parametos
                    if (pars.Length == arguments.Length )
                    {

                        Int16 coincidencias = 0;
                        for (int i = 0; i < pars.Length; i++)
                        {
                            if (pars[i].ParameterType.Name == arguments[i].GetType().Name)
                            {
                                ++coincidencias;
                            }
                        }

                        if (coincidencias == pars.Length)
                        {
                            ejecutar = met;
                            goto continuar;
                        }
                    }
                }

            }

            continuar:

            CronometroResultado resultado = new CronometroResultado();
            Stopwatch reloj = new Stopwatch();

            if (ejecutar != null && !ejecutar.IsGenericMethod)  //sin soporte para genericos
            {
                reloj.Start();
                resultado.Resultado = ejecutar.Invoke(instance, arguments);
                reloj.Stop();
                resultado.MetodoEncontrado = true;
            }

            resultado.Tiempo = reloj.Elapsed;
            return resultado;
        }


    }

Clase CronometroResultado ....


 public class CronometroResultado
    {

        private TimeSpan _span;

        public bool MetodoEncontrado { get; set; }

        public TimeSpan Tiempo
        {
            get { return _span; }
            set
            {
                _span = value;
            }
        }

        public object Resultado { get; set; }

    }


Una pruebita al metodo Vender de la clase Venta ... 



            Venta v = new Venta();
            var res = Cronometro.TomarTiempo(v, "vender", new object[] { 1, 2 });
            Console.WriteLine("Resultado ejecución");
            Console.WriteLine("--------------------");
            Console.WriteLine(res.MetodoEncontrado ? "Encontrado" : "No encontrado");
            Console.WriteLine("Ticks: " + res.Tiempo.Ticks.ToString());
            Console.WriteLine("Milisegundos: " + res.Tiempo.Milliseconds.ToString());
            Console.WriteLine("Segundos: " + res.Tiempo.Seconds.ToString());
            Console.WriteLine("Resultado: " + res.Resultado);
            Console.WriteLine("");
            Console.WriteLine("");

Espero que sirva ... aca el ejemplo Descargar 



domingo, 26 de julio de 2015

Specification Pattern en .NET - Busquedas en memoria

Hace rato que no publicaba nada la verdad que me resulta difícil hacerme un tiempo pero esta vez lo logre (espero muchas veces mas !!!). Ando con ganas de migrar todo esto a WordPress... así que bueno continuemos con el post. 

Hay veces en que necesitamos buscar dentro de un listado genérico de objetos los que cumplan con determinada condición. Como nos tiene acostumbrados (y por suerte) .NET usamos LINQ y como parámetros expresiones Lambda, la verdad que esta forma nos facilita y ahorra mucho trabajo pero por sobre todo el código queda super elegante. 


El problema: Que pasa cuando dejamos en una aplicacion que el usuario sea quien decide la forma de filtrar los datos o tenemos algun input de datos que da como resultado que nuestra busqueda sea dinamica y no estatica (por ejemplo la expresion lambda har codeada en el fuente (e => e.Id == num)) ? 


Ejemplo tenemos un formulario WinForm con los distintos filtros y vemos como quedaria el codigo todavia con el problema de no ser la consulta dinamica. Lo que vamos a buscar son atumoviles asi que tenemos la clase Automovil.





Como vemos ya estamos en un problema no podemos buscar por varios criterios de esa forma.  

Solución: vamos a utilizar el Patron Specification de Martin Fowler , pero usando las ventajas y utilizando C Sharp (en este caso , pero saben que es lo mismo para VB.NET) o sea que el patron esta modificado no es su version original (JAVA). Este patrón nos permitirá hacer búsquedas dinámicas según los criterios que se seleccionen de una forma muy elegante y código altamente reutilizable.


Para comenzar vamos a desarrollar el contrato de las especificaciones y una clase abstracta de la cual van a heredar las demas como Expresion , And , Or y Not.





Expression: esta clase tiene una variable de instancia del tipo Func<t, bool> (delegado) que sera el encargado de testear si el objeto por el que consultemos cumple con el criterio, la prueba se realiza dentro del metodo IsSatisfiedBy que sera sobrecargado por ser abstracto (implementacion obligatoria).


Entonces hasta aca tenemos una clase que tiene un metodo que invoca el delegado pasado por constructor y testeara si el objeto cumple con el criterio establecido. 

Para los que no conocen Func<t, bool> sifnifica que es una expresion o llamesmole un metodo que recibe un parametro del tipo t (generico) y retorna bool. 


Ahora crearemos las especificaciones And , Or y NOT. 




Ya tenemos las clases que representan las especificaciones condicionales , explico brevemente (siempre es mejor debuggear el coduigo y ver como funciona) por ejemplo And hereda de BaseSpecification , para crear una instancia se deben pasar por constructor dos especificaciones que representan el lado izquierdo y el lado derecho de toda condicion "Y" logica, esto se evalua en el metodo sobrecargado IsSatisfiedBy. Siguiendo con Or que es casi igual solo que IsSatisfiedBy pregunta  si se cumple una o la otra , y por ultimo tenemos a Not que seria una especificación negada. 

Medio quilombo al principio pero vamos a testear ahora antes de mostrar mas trucos (;-)).

Como habia mencionado tenemos la clase Automovil con algunas propiedades y un listado de automoviles , ahora le vamos a tirar unas consultas con linq y vemos los resultados. 



Ejecutamos el test. .... donde el Id del Automovil sea igual a 3. 



Por ahora mas que bien que bien , nuestra especificación cumplio su cometido y conseguimos el automóvil que necesitábamos dentro de la colección. 

Ahora vamos a combinar especificaciones, asi que usaremos And , Or y Not. Para combinar usaremos metodos de extension, estos metodos extienden a ISpecification y nos devuelven una And (metodo And) o una Or (metodo Or).


Vamos a verlo por que resulta confuso al pricipio. 





Excelente !!! Tenemos exactamente lo que buscamos combinando las expresiones , ahora volvamos al caso del win form para generar nuestra consulta dinamica y cargar la grilla con lo que buscamos (Ejemplo minimalista me paso de cargar el combo con las marcas).




Perfecto dio resultado , trajo justo lo que queremos, el listado de automoviles esta en la clase ExampleHerlper para comprobar que todo salio bien. 

Terminando ......... como se puede apreciar las consultas sobre LINQ quedan dianmicas por los criterios que necesitamos y un codigo totalmente elegante. Reconozco que el nombre de las clases es medio largo pero lo deje asi para que sea bien explicito el ejemplo. 


Dejo que lo prueben mas ustedes , y combinen todas las especificaciones que se les ocurra. 


Mas adelante voy a mostrar como hacer esto pero contra repositorios de Entity Framework. 



Dejame tu comentario !!!!!!!


Descargate el ejemplo de mi dropbox

Descargate el ejemplo por Mega


Christian DC.









sábado, 21 de marzo de 2015

ASP.NET Web Forms URLs Amigables

Como aún Web Forms no está muerto y siempre queda uno que otro proyecto que mantener, o por que todavía no migramos completamente a MVC .NET, etc., vamos a hacer un ejercicio para tener en nuestro sitio las urls mas amigables y fáciles de recordar por ejemplo: http://misitio.com/default.

Lo que tenemos que hacer primero es referenciar en nuestro proyecto el assembly System.Web.Routing.





Nuestras rutas personalizadas van a estar configuradas en un objeto del tipo RouteCollection y para esto vamos a hacer lo siguiente: 



  1. Agregar en la carpeta APP_Code una clase llamada RoutesConfig con un metodo estático que recibe un  RouteCollection. Recorda darle click derecho al archivo agregado para contruir la clase y en la propiedades setearle Acción de compilación: Compilación.
  2. Ahora abrimos el global.asax y en el evento Application_Start llamamos a esta clase con su metodo estatico y le pasamos la tabla de rutas contenida en: System.Web.Routing.RouteTable.Routes.

viernes, 13 de marzo de 2015

ASP.MVC - Alta de entidades con formulario modal usando JsonResult y AJAX

Al fin me pude hacer un rato libre para comenzar mi blog con los ejemplos que voy haciendo y posteo en algunos grupos. 
En esta ocasion les muestro en ASP.NET MVC como dar de alta entidades (en este caso Personas) usando un formulario en modal. Primero les cuento que para el ejemplo no se usan herramientas de terceros o sea html + js  + css y para el codigo de servidor C Sharp, para la manipulación del dom si usamos Jquery. 


Vamos con el paso a paso: 

1 - Primero que nada necesitamos preparar una ruta que vamos a necesitar en los proximos pasos: 




2 - En el modelo agregamos las clase Persona y la clase Respuesta, el uso de esta ultima sera contener información de la petición que le hagamos al controlador cuando demos de alta una persona. 



3 - Agregamos un controlador llamado PersonaController, este controlador contiene un listado de Persona cacheado en la Session para emular un repositorio y contiene los siguientes métodos (los nombres son para el ejemplo): 
  •   GetPersonasJson: Rertorna el listado de personas serializado en formato JSON.
  •   AddPersonaAjax: Se encarga de agregar una nueva persona al listado y retorna una instancia de la clase Respuesta serializada en JSON. 
  • Index: Devuelve la vista Index , solamente se ejecuta cada vez que entramos en la pagina , luego no tiene ningún uso adicional. 

Antes de seguir vamos a testear el metodo GetPersonasJson para que vean que es lo que se retorna (JsonResult), para eso navegamos a la ruta que esten usando para debuguear + controlador + accion, deberian ver lo siguiente: 



4 - Ahora falta la vista (me salteo la parte de como agregarla),  y aca vamos por partes, lo primero que debemos saber es que el listado de personas lo vamos a mostrar en una tabla y segundo que el alta de las nuevas personas lo hacemos en un formulario modal hecho con HTML + CSS. Para eso agregamos en el encabezado de nuestro HTML (vista .cshtml) las siguientes reglas de estilo: 


Para el formulario modal usamos un div con posición absoluta y un z-index de 1000 para dar la impresión que es un formulario aparte y las capas inferiores quedan inaccesibles hasta que lo cerremos (poner su propiedad display en none). 



Ahora, ¿ como se muestran las personas en la vista si nunca configuramos la propiedad model de la misma (@model List<Personas>) ? La repsuesta es que cuando se carga la vista una función en javascript hace la peticion de los datos a la acción que devuelve el listado de las personas en JSON (GetPersonasJson), luego iteramos ese array y por cada elemento agregamos una fila a la tabla. 



Ya casi lo tenemos, ahora solo falta cargar una persona nueva para ver que todo funciona. 
Abrimos el formulario modal y tratamos de cargar una persona con un documento ya existente en el listado, por ejemplo: 



Como ven dice que la persona existe, ¿ como lo valido ? El botón Aceptar ejecuta una función en javascript que envía los datos de la nueva persona al servidor , o sea son recibidos por el metodo AddPersonaAjax (por eso el mapeo de la ruta con los parametros al principio) como se detecta que ya hay una persona con ese DNI devolvemos una instacia de la clase Respuesta que contiene un codigo de error (en este caso elegido por mi) y una breve descripción de lo ocurrido, obviamente la respuesta va serializada en JSON que nos permite de forma muy fácil trabajar las validaciones del lado cliente. 
En el caso que el dni sea valido y todo este bien  se agrega la persona al listado (servidor), se envia la respuesta que todo esta ok (en este caso el codigo de la repuesta != 404)  y por ultimo se agrega la persona al listado de personas o sea la tabla con la funcion AddFila. 





Bueno espero que les sirva , como ven me salteo algunos pasos por que tomo por sabido que tienen los conocimientos basicos de MVC y de jquery. Les dejo el link de descarga del ejemplo completo. 

El ejercicio fue construido con Visual Studio 2013 y framework 4.5 .

Descargar el Ejemplo


{"Saludos", "!!!!"}