RSS 2.0 Atom 1.0 CDF  
JASoft.org - Visual Studio
El blog de José Manuel Alarcón Aguín. Programación .NET y mucho más...
 

.NET 4.0 dispone de soporte para tiempo de ejecución de lenguajes dinámicos, el DLR (Dynamic Language Runtime). El propósito del DLR es permitir que los lenguajes de tipo dinámico -como PHP, JavaScript, Ruby, Python, Lisp o Groovy, por citar unos cuantos- puedan ejecutarse en la plataforma y además interactuar con código escrito en un lenguaje .NET -como C# o VB.

El DLR introduce en el framework una serie de clases dinámicas de comportamiento dinámico que ayudan mucho a la hora de interactuar con estos lenguajes o acceder a COM, pero que abren la puerta a crear monstruos de código si son mal utilizados. De hecho gurús de la plataforma como mi buen amigo Octavio Hernández, reniegan de esta característica ;-)

Lo cierto es que en general yo no recomendaría el uso de las clases dinámicas, pero sí que pueden llegar a ser útiles en algunas ocasiones. Por ello en este artículo voy a presentar la más útil y fácil de usar de todas, la clase ExpandoObject.

Añadiendo miembros dinámicamente

Este objeto es, en realidad, una colección genérica bien disfrazada con "azucar sintáctico" de manera que en lugar de andar escribiendo .Add y .Remove con el nombre de los miembros, se pueden escribir directamente en el código y el compilador hace caso omiso de ellos, posponiendo la comprobación de su existencia al tiempo de ejecución. Lo entenderemos mejor con un ejemplo:

//Creo el objeto
dynamic Persona1 = new System.Dynamic.ExpandoObject();
//le añado algunas propiedades
Persona1.Nombre = "JM";
Persona1.Apellidos = "Alarcón aguín";
Persona1.Edad = 37;

Fijémonos en lo que hemos hecho aquí: primero hemos declarado una nueva clase de tipo ExpandoObject, la cual está en el espacio de nombres System.Dynamic. Si hubiésemos escrito simplemente el nombre de la clase VS2010 nos da ya la opción de añadir el "using" correspondiente en la parte de arriba del código:

Hay que fijarse también en una cosa importante: en C# debemos declarar el tipo de la variable que va a contener el objeto como dynamic. Fíjate en que lo lleva delante. Este nuevo tipo de C# se puede considerar que es casi idéntico al tipo Object, pero su principal diferencia es que cuando declaramos una variable con dynamic, el compilador se salta la comprobación estática de tipos durante la compilación. De esta forma el compilador no "rompe" cuando compilamos si intentamos utilizar una propiedad o método de la clase dinámica aunque éstos no existan. En VB no es necesario un tipo especial porque este lenguaje soporta el enlazado de tipos postergado.

Bien, una vez creado el objeto dinámico podemos empezar a añadirle propiedades con sólo escribirlas, como se ve en las líneas anteriores, tras la declaración. Así, al nuevo objeto le añadimos una propiedad Nombre, otra Apellidos y otra Edad simplemente poniendo un punto y escribiéndola. Es decir, como si ya existiera de antemano, cosa que no es así. En la práctica lo que conseguimos es que si la propiedad existe que se asigne, pero si no existe se crea dinnámicamente y se asigna, es decir se van creando propiedades sobre la marcha.

Si ahora escribo:

Console.WriteLine("Persona: {0} {1}, Edad: {2}", Persona1.Nombre, Persona1.Apellidos, Persona1.Edad);

Obtendré por pantalla sin problemas el nombre y apellidos, seguidos de la edad anotadas en este nuevo objeto dinámico.

Los tipos apropiados para las propiedades se infieren del valor que se le pasa al asignarla. Así en el ejemplo, para el nombre y apellidos tendremos tipos string, y un int para le Edad. Además el tipo cambia también dinámicamente. Por ejemplo si asigno el valor 37 a la propiedad Edad su tipo será un Int. Sin embargo si acto seguido le asigno, por ejemplo, 10E10 (un número muy grande), automáticamente la propiedad cambia y ahora es de tipo double. Exactamente igual que pasaría en JavaScript u otro lenguaje dinámico tradicional.

Podemos crear propiedades de objetos dinámicos que a su vez son también objetos dinámicos. Por ejemplo:

Persona1.Domicilio = new ExpandoObject();
Persona1.Domicilio.Ciudad = "Vigo";

De este modo acabo de crear una propiedad Domicilio que es dinámica y le he creado a su vez una propiedad Ciudad. Así puede escribir Persona1.Domicilio.Ciudad para obtener el valor "Vigo".

Estos tipos dinámicos, aunque están soportados por el entorno de Visual Studio 2010, no nos ofrecen (al menos en la Beta2) soporte para Intellisense, en el sentido de que una vez definida la propiedad, esta no aparece en la ayuda contextual cuando volvemos a usar el objeto y ponemos un punto:

Como vemos, nos indica que lo que escribamos a continuación del punto será interpretado en tiempo de ejecución, no al compilar, y por tanto no nos muestra ayuda al respecto.

Con esto es muy facil, por ejemplo, crear un nuevo objeto dinámico dinámicamente (valga la redundancia) a partir de datos contenidos en algún lado. El ejemplo típico es cargar un archivo XML e ir recorriendo sus nodos e ir asignando a su vez propiedades alobjeto dinámico. Así podremos acceder más fácilmente a los datos desde el código pudiendo escribir notaciónn común de objetos (nombres y puntos) para acceder a ellas en lugar de estar escribiendo sintaxisd más complejas para leer valores de nodos o atributos XML. También nos valdría de modo similar para interpretar JSON.

Una aplicación especialmente interesante es a la hora de definir vistas de ASP.NET MVC 2.0 de manera dinámica, como explica Phil Haack en este post (inglés).

Además de propiedades es posible definir también métodos dinámicamente, si bien éstos son de menor utilidad ya que deberán ser estáticos y por lo tanto no pueden acceder al resto de propiedades del objeto.

Por ejemplo:

Persona1.Saludar = new Func<STRING, bool>((sSaludo) =>
{
    Console.WriteLine(sSaludo);
    return true;
});

Con esto creamos un nuevo método Saludar, y podemos escribir: Persona1.Saludar("Hola") para obtener ese mensaje por pantalla en este caso simple. El método se crea con una expresión Lambda por lo que siempre deve devolver algo. En este caso como no nos interesa para nada el valor devuelto he optado por devolver un booleano sin más. Ya digo que no tienen demasiada utilidad.

Si llamamos a la función sin pasarle el número de parámetros apropiado no se nos quejará el compilador y podremos generar el ejecutale. Sin embargo a la hora de ejecutar la aplicación romperá miserablemente:

Enumeración y eliminación de miembros

Hasta ahora hemos visto lo fácil que es crear un miembro, pero claro, nos será útil solamente si sabemos de antemano qué miembros están disponibles. ¿Cómo podemos averiguarlo?. Esto puede ser útil para, en el caso de crearlo a partir de un origen de datos arbitrario, poder enumerarlos y comprobar que existen un mínimo determinado de ellos, o simplemente para poder hacer introspección de los objetos. Siempre podríamos usar reflexión pero sin embargo no habríamos ganado demasiado ¿verdad?.

Fijémonos en la definición de la clase ExpandoObject (en C#):

public sealed class ExpandoObject : IDynamicMetaObjectProvider, 
    IDictionary<string, Object>, 
    ICollection<KeyValuePair<string, Object>>, 
    IEnumerable<KeyValuePair<string, Object>>, 
    IEnumerable, INotifyPropertyChanged

Como vemos implementa una interfaz IDictionary genérica y también una ICollection e IEnumerable. Es decir, en el fondo se trata ni más ni menos de una colección genérica capaz de albergar cualquier cosa. Los miembros que vamos añadiendo se incorporan a una colección interna. Por lo tanto para poder enumerarlos sólo hay que hacer uso del objeto como una colección o un diccionario:

IDictionary<String, Object> miembros = (IDictionary<string, Object>)Persona1;
foreach (System.Collections.Generic.KeyValuePair<String, Object> miembro in miembros)
{
    Console.WriteLine("{0}: {1}", miembro.Key, miembro.Value);
}

O de manera más directa y entendible:

foreach(var miembro in (IDictionary<string, Object>)Persona1)
{
    Console.WriteLine("{0}: {1}", miembro.Key, miembro.Value);
}

Como vemos simplemente hacemos un "cast" a la interfaz IDictionary y a partir de ese momento lo manejamos como cualquier otra colección de objetos cuya clave es de tipo texto. Gracias ello podemos añadir nuevos miembros usando el método Add del diccionario, pero, lo más importante, podemos eliminarlos usando el método Remove, por ejemplo:

((IDictionary)Persona1).Remove("Nombre");

En la que me he cargado la propiedad Nombre.

Detectando cambios en propiedades

Si nos fijamos en la definición de la clase vemos que implementa una interfaz INotifyPropertyChanged. Ésta define un evento llamado PropertyChanged que nos sirve para detectar el momento en que cambia una propiedad o se asigna por primera vez. Así, podemosdefinir una función como esta:

private static void DetectarCambios(object sender, PropertyChangedEventArgs e)
{
    Console.WriteLine("Se ha asignado la propiedad '{0}'", e.PropertyName);
}

y detectar los cambios en miembros simplemente estableciendo esa propiedad de la interfaz, así:

((INotifyPropertyChanged)Persona1).PropertyChanged += new PropertyChangedEventHandler(DetectarCambios);

No acaba de ser del todo útil porque no nos deja averiguar qué valor se ha asignado (aunque es fácil de determinar usando la colección interna como acabamos de ver hace un momento, pero puede ayudarnos en algunos casos. No obstante si queremos crear objetos dinámicos y tener control absoluto sobre cómo se crean sus miembros en lugar de ExpandoObject deberíamos usar la clase DynamicObject.

Colecciones de objetos dinámicos

Para terminar con este interesante tema me gustaría comentar cómo se crean colecciones de objetos dinámicos. Consideremos el siguiente código:

dynamic vecinitos = new List<dynamic>();

vecinitos.Add(new ExpandoObject());
vecinitos[0].Nombre = "Homer";
vecinitos[0].Apellidos = "Simpson";
vecinitos[0].Ropa = "Camisa blanca, pantalones azules";

//No son objetos iguales
vecinitos.Add(new ExpandoObject());
vecinitos[1].Nombre = "Ned";
vecinitos[1].Apellidos = "Flanders";

foreach (var vecinito in vecinitos)
{
    Console.WriteLine("{0} {1}", vecinito.Nombre, vecinito.Apellidos);
}

Vemos que la lista genérica se crea del tipo dynamic, y no del tipo ExpandoObject. Esto es normal ya que de esta forma estamos acogiendo objetos dinámicos de cualquier tipo y no sólo de esta clase particular. Aunque en este ejemplo concreto funcionaría perfectamente haberla definido con ExpandoObject, en general usaremos dynamic (u Object en VB) porque así nos aseguramos que vengan de donde vengan los objetos de la lista ésta funcionará sin problema.

A continuación definimos cada elemento añadido la lista de forma que creamos dinámicamente sus propiedades. Finalmente los recorremos en un bucle para mostrar sus propiedades.

Si en el bucle hubiésemos usado esta línea de código en ugar de la anterior:

Console.WriteLine("{0} {1}", vecinito.Nombre, vecinito.Apellidos, vecinito.Ropa);

Lo que hubiera pasado es que la primera vuelta (la de Homer) hubiera funcionado bien, pero como en el segundo elemento (Flanders) no hemos definido la propiedad ropa hubiésemos obtenido un error en tiempo de ejecución. Con esto quiero dejar claro que aunque se defina una propiedad para uno de los objetos, ésta no queda definida en los demás, ya que son objetos absolutamente independientes, así que hay que tener cuidado y no dar por hecho que una determinada propiedad va a existir para un objeto dinámico concreto.

En resumen

Los objetos dinámicos creados a partir de la clase ExpandoObject están pensados para trabajar con lenguajes dinámicos desde C# y VB. Ello además nos proporciona una nueva herramienta que podemos usar en otro tipo de desarrollos aunque no estén relacionados con los lenguajes dinámicos. Eso sí: debemos usarlos con sumo cuidado y sólo en situaciones que estén muy justificadas, porque de otra manera correremos el riesgo cierto de cometer muchos errores difíciles de detectar. De hecho una de las ventanas de los lenguajes tipados frente a los dinámicos es que es mucho más difícil meter la pata porque debes tener claro todo el rato qué tipo de información estás manejando. Así que ¡cuidado!.

Los objetos ExpandoObject son en realidad una forma fácil de acceder colecciones genéricas, por lo que debemos tener con ellos el mismo cuidado que con las colecciones. Así que cuando escribamos una propiedad con la notación del punto debes recordar que por debajo lo único que estás haciendo es añadir un elemento a una colección. Tenlo en mente todo el rato.

He dejado todo el código de este artículo en un ZIP para que puedas descargarlo y haer tus propios experimentos con estos objetos dinámicos y ver cómo se comportan.

¡Espero que te resulte útil!

Por: José Manuel Alarcon | Saturday, February 06, 2010 8:57:14 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Programación | Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Hoy he sabido, directamente a través de la gente de producto de Microsoft, que han realizado unos cuantos cambios de cierto calado a la parte de soporte para dispositivos móviles en ASP.NET 4.0. Estos cambios se verán cuando salga la versión definitiva pero ahora no están disponibles en la Beta de Visual Studio 2010.

1.- Han convertido en obsoletas todas las clases de System.Web.Mobile, es decir, todo el soporte de controles móviles para WAP que existían en versiones anteriores de ASP.NET. Con obsoletas no quiero decir que dejen de funcionar o de soportarse, simplemente que han sido marcadas con el atributo Obsolete y que generarán una advertencia cuando compiles apliaciones que las usen. Así que ojo si usas el compilador con la opción de que las advertencias se traten como errores, porque no te compilarán. Simplemente ahora no se recomienda su uso.

2.- Han modificado sustancialmente los archivos de definición de navegadores (archivos .browser) tanto para HttpBrowserCapabilities como para MobileCapabilities. Ahora tendremos versiones actualizadas de todos los navegadores móviles (iPhone, Blackberry e IE mobile) que estaban muy desactualizadas. Si necesitas definiciones para otros móviles que no sean estos tres puedes usar definiciones Open Source como las que ha puesto el equipo de Live en CodePlex y usarlas desde hoy mismo. También se han actualizado las de los navegadores de sobremesa más actuales, como Google Chrome. También han quitado las de navegadores viejos como Netscape o versiones de Internet Explorer previas a la 6.0 (ojalá desapareciera de la tierra la versión 6.0 también).

3.- Han adaptado la definición de los navegadores al modelo de proveedores, como las principales características de la plataforma.

4.- Lanzarán documentación específica para hacer que tus aplicaciones Web funcionen bien en iPhone. Ya os iré contando por aquí también cosas por mi parte sobre esto, que a mi ese tema me interesa mucho y de hecho algo ya he estado haciendo :-)

Por: José Manuel Alarcon | Monday, August 10, 2009 10:08:49 PM (Hora de verano romance, UTC+02:00)  #    Comments [1] - Trackback
Tags: ASP.NET | Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Hoy me he estado volviendo loco con Visual Studio 2008 SP1. Resulta que necesitaba hacer capturas de pantalla de la barra de propiedades, para lo cual la desacoplaba dellateral, donde la suelo tener, y hacía la captura. Luego la volvía a poner la barra en su sitio.

Bien, nada más hacer eso, si se me ocurría ejecutar la aplicación con F5: ¡crassss! cuelgue miserable de Visual Studio y el ordenador medio colgado (casi no me dejaba sacar ni el administrador de tareas para matarlo) :-((

Al principio no lo asocié a lo de desacoplar la ventana pero luego me di cuenta de que era claramente por eso. Así qeu buscando, buscando llegué a este artículo de la Knowledge Base de Microsoft.

Resulta que hay un bug en el Service Pack 1 de Visual Studio que puede hacer que cuando desacoplas ventanas y las vuelves a coplar algo vaya mal y se te cuelgue el entorno (y de paso casi el sistema).

Desde el enlace anterior te puedes bajar el parche que te proporcionan "por el buen rollito" pero del cual no se responsabilizan, es decir, no es un fix soportado oficialmente pero dicen que lo soluciona.

Tarda alrededor de media vida en instalarse... :-(

...pero parece que arregla el problema :-)

Yo tengo en mi equipo todo instalado en inglés, así que no puedo decirte si funcionará también con la versión en Español del entorno. Si alguien lo prueba en otro idioma y es tan amable, que deje un comentario aquí para los demás. Gracias.

Espero que a alguien le pueda resultar útil.

Por: José Manuel Alarcon | Monday, July 27, 2009 9:04:43 PM (Hora de verano romance, UTC+02:00)  #    Comments [1] - Trackback
Tags: Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Soy fan de esos pequeños detalles de calidad que muchas veces pasan inadvertidos pero que, una vez descubiertos, no puedes vivir sin ellos.

En este caso me gustaría hablar de una nueva característica del depurador de Visual Studio 2010 que me resulta muy útil y que echo de menos cuando tengo que volver a versiones anteriores: las inspecciones/watches flotantes.

Quizá no lo hayas notado, pero cuando te colocas encima de una variable o de una expresión cualquiera en el código mientras estás depurando, en la habitual ventanita flotante que te permite inspeccionar las variables y los objetos verás una especie de cuadrito amarillo a la derecha,como en la figura siguiente (por cierto, depurando JavaScript, o sea que funciona con todos los lenguajes):

Si lo pulsas verás que la ventana flotante se convierte en el típico Post-it que se queda visible de forma permanente, y puedes arrastrar a donde queiras. De este modo puedes tener tus objetos de interés siempre visibles, de manera mucho más cómoda que añadiendo una simple inspección a la lista de inspecciones (watch list).

Además tenemos otras ventas ya que nos permite añadir notas debajo para no olvidarnos de cosas importantes relacioandas con cada inspección, así como modificar los valores de las variables y propiedades, cambio que se ve reflejado de inmediato  en el programa que estamos depurando:

Ya sabes, si no los habías visto no pierdas tiempo y empieza a sacarles partido :-)

Por: José Manuel Alarcon | Saturday, July 25, 2009 10:40:41 AM (Hora de verano romance, UTC+02:00)  #    Comments [0] - Trackback
Tags: Programación | Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

ADO.NET Entity Framework

Last week, we at Krasis Press launched what we believe is the first book fully dedicated to ADO.NET Entity Framework published worldwide, in any language: "ADO.NET Entity Framework: Data centric applications and services" (in Spanish).

And what a book! Honestly, I firmly believe we have produced an excellent resource, created by three experts that have been working with this technology since the very first betas, and using it in real life projects for many months: Unai Zorrilla, Octavio Hernandez and Eduardo Quintas.

Unai and Octavio (Microsoft MVPs) are already well known to audiences for their frequent articles in publications, and for being the authors of the books "Modeling business processes with Workflow Foundation" and "C# 3.0 and LINQ", both published by Krasis in October, 2007 (in Spanish).

The book consists of six chapters plus five appendixes, which cover in depth most of the features of the Entity Framework:

  • The book begins with a chapter introducing the technology, and continues with a second chapter fully devoted to show all the resources that Entity Framework puts in our hands for the development of conceptual entity data models, using clear and practical examples.
  • After that, the next two chapters describe in detail the possibilities that the main programmatic layers of the Entity Framework (Entity Client, Object Services and LINQ to Entities) offer us in order to query and update the conceptual models.
  • The fifth chapter, "Entity Framework in the real world" is dedicated to several more advanced topics, such as the relation between EF and WCF and its application to N-tier application development, or the techniques that are at our disposal for doing data binding against EF-produced results in WinForms, WPF and ASP.NET applications.
  • At last, the sixth chapter offers a broad introduction to ADO.NET Data Services, a practical framework built by Microsoft on top of the Entity Framework in order to expose entity data models through REST-based services.
  • The five appendixes cover, respectively, the fundamentals of LINQ, an Entity SQL reference, EDMGen.exe and DataSvcUtil.exe command line options and JSON serialization basics.

You can download the table of contents and part of the first chapter following this link. You can buy the book in the same webpage. The price includes courier delivery expenses to any part of Spain, although delivery to other countries may have extra charges.

Other books in English on the subject are expected to appear in bookstores at the end of 2008/beginning of 2009.

Read this post in Spanish / Lee este post en Español

Por: José Manuel Alarcon | Tuesday, October 07, 2008 6:58:35 PM (Hora de verano romance, UTC+02:00)  #    Comments [0] - Trackback
Tags: Noticias Programación | Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner
Page 1 of 4 in the Visual Studio category Next Page
Copyright © 2010 José Manuel Alarcón Aguín. All rights reserved.