Custom Collections

Durante los meses en que he estado con GMaps 3.0, he trabajado en mejorar el código de versiones previas. Siempre se puede mejorar en eficiencia, limpieza y mantenibilidad.

Durante este artículo os voy a hablar de un Helper que hice con el que se mejorar mucho la mantenibilidad y la limpieza de código.

Con las custom collections vamos a poder crear colecciones de "items" o de "nombre-valor" que se convertirán en un string según nuestras necesidades.

La necesidad viene de la propia naturaleza del control de googlemaps para ASP.NET, que en su esencia es un "conversor" ASP.NET --> Javascript/API de Google.

En muchas ocasiones deberemos devolver colecciones de nombre-valor, donde cada una de ellas es opcional. Por ejemplo, las opciones que se le pasan al contructor de un GMarker pueden ser...

{clickable:false,title:'Titulo del GMarker',draggable:true,dragCrossMove:false,bouncy:false,bounceGravity:1}

... o pueden no ser nada.

En este caso se trata de una variable JSON, que responde a la definición de "Colección de nombre-valor".

Algo también muy común en el javascript de la API de Google Maps que también es una colección de nombre-valor, es una cadena QueryString:

?nombre1=valor1&nombre2=valor2&nombre3=valor3

Por otra parte, tenemos una coleccion de items (o de sólo valor, sin nombre) como por ejemplo los parámetros de un método javascript:

(item1, item2, item3)

Visto así, no se aporta nada que no pueda solucionarse con un StringBuilder y varios "if", pero creedme que las CustomCollections son brutalmente útiles.

Por ejemplo, para crear una variable JSON, sabiendo que todos sus parámetros son opciones, nos vale con el siguiente código:

JSONCollection jsonCollection = new JSONCollection();
jsonCollection.Add("clickable", clickable, !clickable, typeof(bool));
jsonCollection.Add("title", title, !string.IsNullOrEmpty(title), typeof(string));
jsonCollection.Add("draggable", draggable, draggable, typeof(bool));
jsonCollection.Add("dragCrossMove", dragCrossMove, draggable, typeof(bool));
jsonCollection.Add("bouncy", bouncy, draggable, typeof(bool));
jsonCollection.Add("bounceGravity", bounceGravity, draggable);
string jsonString = jsonCollection.ToString();

El primer parámetro se corresponde al "nombre", el segundo al "valor", el tercero es un booleano que indica si se va a insertar o no en la colección, y el cuarto es el tipo de dato javascript (que no tiene por qué coincidir con el tipo de dato de ASP.NET).

Hacer lo mismo con el método tradicional puede ser un infierno de "if-else", StringBuilder y tratamientos diferenciados según si hay o no items que añadir, o si diferenciar si son de tipo booleano, string o entero.


Tanto de lo mismo tenmos con la cadena QueryString. Un ejemplo de uso real sería la llamada al servicio Web REST de GeoCoding de Google Maps:

QueryStringParameterCollection queryStringParameterCollection = new QueryStringParameterCollection();
queryStringParameterCollection.Add("q", query);
queryStringParameterCollection.Add("output", output.ToString());
queryStringParameterCollection.Add("key", Key);
queryStringParameterCollection.Add("oe", "ISO-8859-1");
...
string queryString = queryStringParameterCollection.ToString();


Entrando en una faceta más técnica, tanto el JSONCollection, como el QueryStringParameterCollection, como el MethodAttributesCollection, heredan de la clase AdvancedCollection.

El AdvancedCollection tiene como propiedades internas un NameValueCollection (para las colecciones nombre-valor) y un StringCollection (para las colecciones de items) a las que se les añadirán elementos con los métodos Add(nombre, valor) y/o Add(item).

Las colecciones se transformarán en strings, para lo cual deberemos definir algunos parámetros (pongo entre paréntesis el valor que asignan el JSONCollection, el QueryStringCollection y el MethodAttributesCollection:
  • StartOfCollection: inicio de la colección. JSONCollection= {  QueryStringCollection= ?  MethodAttributesCollection= ( 
  • StartOfNameValue: inicio del item o del par nombre-valor. JSONCollection= vacío  QueryStringCollection= vacío  MethodAttributesCollection= vacío 
  • NameValuesSeparator: separador de los diferentes nombre-valor y los items. Se distingue de StartOfNameValue y EndOfNameValue, porque el NameValuesSeparator no se inserta tras el último nombre-valor o item. JSONCollection= ,  QueryStringCollection= &  MethodAttributesCollection= , 
  • NameValueSeparator: separador entre el nombre y el valor. Cuando sólo tenemos items no tiene efecto. JSONCollection= QueryStringCollection= =  MethodAttributesCollection= Tiene items 
  • EndOfNameValue: fin del item o del par nombre-valor. JSONCollection= vacío  QueryStringCollection= vacío  MethodAttributesCollection= vacío 
  • EndOfCollection: fin de la colección. JSONCollection= }  QueryStringCollection= vacío  MethodAttributesCollection= )

Así pues, los tres tipos de colecciones son sólo ejemplos ampliables tanto como necesitemos.