Objetos anónimos como diccionarios

¡Hola!

Cada vez más existen frameworks y librerías que permiten usar objetos anónimos como si de diccionarios se tratase. Esto es muy cómodo porque permite realizar llamadas tal y como:

Foo(new { x = 10, y = 20, Data = "Data" });

Por ejemplo, en ASP.NET MVC no se paran de hacer llamadas parecidas a esta…

Internamente el método Foo utilizará reflection para iterar sobre las propiedades del objeto anónimo que recibe y obtener los datos.

Si tenéis varios métodos que trabajan con IDictionary<string, T> y queréis que se puedan llamar fácilmente usando esta técnica podéis crear un método extensor de IDictionary<string, T> que rellene un diccionario a partir de las propiedades de un objeto… De acuerdo, vuestros métodos no serán invocables directamente pasándoles un objeto anónimo pero al menos los diccionarios se crearán mucho más fácilmente.

Si estáis vagos aquí tenéis un código que uso yo para esto:

public static class DictionaryStringStringExtensions
{
    public static IDictionary<string, T>  FillFromObject<T>(
        this IDictionary<string, T> dictionary,
        object values)
    {
        if (values == null) return dictionary;

        Type type = values.GetType();
        foreach (var property in type.GetProperties())
        {
            if (!dictionary.ContainsKey(property.Name))
            {
                object propValue = property.GetValue(values, null);
                T finalValue = default(T);
                if (property.PropertyType.Equals(typeof(T)))
                {
                    finalValue = (T)property.GetValue(values, null);
                }
                else
                {
                    finalValue = (T)Convert.ChangeType (propValue, 
                        typeof(T),  CultureInfo.CurrentCulture);
                }
                dictionary.Add(property.Name, finalValue);
            }
        }

        return dictionary;
    }
}

El método realiza conversiones básicas entre tipos de propiedades… Así podeis inicializar fácilmente vuestros diccionarios:

var d = new Dictionary<string, int>();
d.FillFromObject(new { col = "10", row = 20.2 });

Saludos!

ASP.NET MVC y Custom Http Handlers

Hola! ¿Como va todo?

Un post rapidito… Imaginad que creais un Custom Handler para procesar determinadas peticiones en vuestra aplicación ASP.NET MVC:

    public class CardImagesHandler : IHttpHandler
    {
        #region IHttpHandler Members
        public bool IsReusable
        {
            get { return false; }
        }
        public void ProcessRequest(HttpContext context)
        {
            // ...
        }
        #endregion
    }

Luego, lo añadís en el web.config, para que os procese todas las URLs con extensión .portrait:

<add verb="GET" path="*.portrait" 
type="WofWeb.Code.CardImagesHandler"/>

Finalmente probáis alguna URL con extensión portrait, tal y como http://localhost:8080/prueba.portrait i veis que vuestro Custom Http Handler es vilmente ignorado…

¿Por qué? Pues porque ASP.NET MVC toma control de todas las URLs, por lo que intentará procesar esta URL aunque hayamos definido un Custom Http Handler para ella. ¿La solución? En la tabla de enrutamiento indicar que queremos que se ignoren las URL con .potrait, de esta manera serán procesadas por nuestro Custom Http Handler…

… tan sencillo como añadir:

routes.IgnoreRoute("{resource}.portrait/{*pathInfo}");

en global.asax donde configuremos la tabla de enrutamiento!

Saludos!

Surface en raona…

Hola! En raona tenemos desde hace algún tiempecillo la Surface… Lo que os quiero mostrar no es nada más que un pequeño vídeo de una aplicación que hemos desarrollado para ella: el Surface Shooter.

¿Y que es? Pues como bien se encarga de explicar mi compañero Juan Carlos Viñas permite navegar por los documentos de un portal de sharepoint usando la Surface.

Os dejo el enlace al youtube donde está el video:

Video Raona Surface Shooter (youtube)

En raona pensamos que la Surface ofrece grandes oportunidades, tanto a clientes como a proveedores, aunque es cierto que es necesario que nos olvidemos de todos los conceptos que tenemos preconcebidos en cuanto a como debe ser presentada una interfaz gráfica (os recomiendo que os leais este enorme post del no menos grande Miguel: Microsoft Surface: Developing NUI Touch Experiences).

Un saludo a todos!!! 🙂

Pexcando errores en nuestro código…

Buenas… ¿Conoceis Pex? Es una herramienta que genera tests unitarios a partir de nuestro código. Su característica principal es que analiza el código e intenta generar tests unitarios que cubran todas las posibilidades de nuestro código.

Vamos a ver un pequeño ejemplo de como usarlo y como se integra con Microsoft Code Contracts. Antes que nada os recomiendo echar un vistazo al genial Post de Jorge Serrano Precondiciones y Microsoft Code Contracts v1.0.

Vamos a hacer un método muy simple (y conocido por aquellos que desarrollen en VB.NET):

 public static class StringExtensions
{
     public static string Right(this string value, int chars)
     {
         return value;
     }
}

El método Right debe devolver los últimos chars carácteres de la cadena value.

Simplemente con este código nos descargamos Pex y lo instalamos. Una vez hecho vereis que nos aparece una nueva opción el menú contextual del “Solution Explorer” llamada “Run Pex Explorations”. Con esta opción lo que hacemos es que Pex analice todo nuestro código buscando generar Tests unitarios para nuestros métodos públicos:

image

Si ejecutamos esta opción Pex analiza el código y nos genera tests unitarios para el método Right:

image

 

En este caso nos ha generado un solo test. Es importante saber como Pex genera los tests: no lo hace al azar, sinó que intenta cubrir el máximo de nuestro código. En nuestro caso como no nuestro código apenas hace nada, con un solo test, Pex obtiene una cobertura del 100% y se queda ahí. Evidentemente Pex nada sabe de cual debe ser el resultado de nuestro método, por lo que no puede generar tests unitarios funcionales.

Ahora antes de empezar a analizar código vamos a ver el uso de Code Contracts. Una vez instalada, añadís la referencia a “Microsoft Contracts Library” (Microsoft.Contracts.dll). En el framework 4.0 parece ser que se incluirá el código dentro de mscorlib, por lo que no será necesario usar referencia alguna.

Ya estamos listos para definir los contratos en nuestra clase. Para ello debemos especificar las precondiciones de nuestro método. Una precondición es algo que debe cumplirse sí o sí para asegurar que la llamada  anuestro método es “válida”.

Una precondición de nuestro método es que NO vamos a aceptar que la cadena de entrada sea nula. El método Contract.Requires sirve para especificar las precondiciones:

public static string Right(this string value, int chars)
{
    Contract.Requires(value !=null);
    return value;
}

Si lanzamos Pex ahora vemos que… no ocurre nada distinto. Esto es porque por defecto los contratos no se evalúan. Si queremos que se evalúen debemos irnos a la pestaña “Code Contracts” de las propiedades del proyecto y habilitar “Perform runtime contract checking”. Una vez hecho esto, volvemos a ejecutar Pex y obtenemos lo siguiente:

image

Vemos que ahora Pex nos ha generado dos tests: uno que pase el contrato (le manda una cadena con un ‘’ y otro que no (le manda null).

Otra pecondición que vamos a usar es que el segundo parámetro debe ser mayor que cero:

public static string Right(this string value, int chars)
{
    Contract.Requires(value !=null);
    Contract.Requires(chars > 0);
    return value;
}

 

Una vez establecidas las precondiciones nos interesa establecer las postcondiciones, es decir todo aquello que aseguramos que se cumple al finalizar el método. Para ello usamos Contract.Ensures. P.ej. para añadir una postcondición que asegure que nunca devolveremos null:

public static string Right(this string value, int chars)
{
    Contract.Requires(value !=null);
    Contract.Requires(chars > 0);
    Contract.Ensures(Contract.Result<string>() != null);
    return value;
}

Una cosa realmente importante: Contract.Ensures se evalúa SIEMPRE al final del método… aunque como en este caso lo hayamos colocada antes del return, se evaluará después del return. El secreto está en que Code Contracts viene con un MSIL rewriter que modifica el código MSIL desplazando las llamadas a Contract.Requires al principio del método y de Contract.Ensures al final. El método Contract.Result<T> sirve para acceder al valor retornado por el método.

Contract.Requires no deja obsoleto a Debug.Assert. Ambos son necesarios: Con Contract.Requires comprobaremos las precondiciones lógicas de nuestro método, mientras que Debug.Assert lo seguiremos usando para comprobaciones de depuración (comprobaciones internas).

Tenemos el contrato de nuestro método especificado, tenemos a Pex para que nos genere tests unitarios… podemos empezar a meter código!

 public static class StringExtensions
{
     public static string Right(this string value, int chars)
     {
         Contract.Requires(value !=null);
         Contract.Requires(chars > 0);
         Contract.Ensures(Contract.Result<string>() != null);
         if (chars >= value.Length) return value;
         else
         {
             int inicial = value.Length - chars;
             if (inicial < 0) inicial = 0;
             return value.Substring(inicial, chars);
         }
     }
}

Una vez tenemos el código ya listo (o eso creemos jejejeeee…) relanzamos Pex para que nos cree un nuevo conjunto de tests unitarios para nuestro método. Como ahora tenemos un código un poco más complejo, Pex nos creará varios tests unitarios:

image

Pex ha creado 4 tests unitarios con el objetivo de cubrir al máximo nuestro código. A partir de este punto si queremos podemos generar un proyecto de test con estos 4 tests unitarios. Los podemos seleccionar desde la ventana de Pex Exploration Results y le dais a “Save”:

image

Con ello Pex nos genera el proyecto de tests unitarios:

image

El proyecto tiene dos archivos especiales: El fichero StringExtensionsTest.cs y el fichero StringExtensionsTest.Right.g.cs.

El segundo (.g.cs) se regenera cada vez que ejecutamos Pex, por lo que NO debemos poner código en él. El primero por su parte se mantiene y contiene lo que Pex llama PUTs, o Parametrized Unit Tests. Un PUT es un test unitario pero que acepta parámetros. Pex los usa para poder “agrupar” clausulas Assert: En lugar de colocar un Assert para cada test unitario, coloca uno de solo en el PUT y los tests unitarios que genera Pex, son llamadas al PUT con los parámetros correspondientes.

P.ej. el código del PUT generado es:

[PexMethod]
public string Right(string value, int chars)
{
    // TODO: add assertions to method StringExtensionsTest.Right(String, Int32)
    string result = StringExtensions.Right(value, chars);
    return result;
}

Como se puede ver no hace nada salvo llamar al método real que estamos testeando pasándole los parámetros. Pero aquí nosotros podríamos poner Asserts adicionales, que se comprobarían para todos los unit tests de Pex. El código de un unit test de Pex es similar a:

[TestMethod]
[PexGeneratedBy(typeof(StringExtensionsTest))]
public void Right04()
{
    string s;
    s = this.Right("", 1);
    Assert.AreEqual<string>("", s);
}

La llamada a this.Right es la llamada al PUT que ha generado antes.

Os dejo un par de videos con más información sobre Code Contracts y Pex para que les echeis un vistazo, dado que es un tema que vale realmente la pena!

Saludos!