Blog de Fernando Machado Piriz

Artículos sobre transformación digital, arquitectura empresarial y temas relacionados

Archive for the ‘.NET Framework 4.0’ Category

Nueva versión de Visual Studio 2010 and .NET Framework 4 Training Kit

leave a comment »

imageDesde ayer está disponible para descarga desde el sitio de Microsoft la actualización de marzo de 2011 del Visual Studio 2010 and .NET Framework 4 Training Kit. Pueden descargar el kit desde aquí. Este training kit incluye presentaciones, hands-on labs y demos, que cubren las últimas novedades en las versiones de Visual Studio 2010 y .NET Framework 4 recientemente actualizadas . Que lo disfruten.

 

 

 

 

 

 

Written by fernandomachadopiriz

15/03/2011 at 19:03

Liberado Visual Studio 2010 Service Pack 1

leave a comment »

Está disponible desde ayer para descarga para los suscriptores de MSDN la versión final (RTM) del Service Pack 1 para Visual Studio 2010. Pueden ver la lista de novedades y correcciones completa aquí.

Dentro de las cosas que considero más interesantes en esta versión están:

  • Compatibilidad con Silverlight 4
  • Soporte para pruebas de unidad contra .NET Framework 3.5
  • IntelliTrace para aplicaciones de 64 bits y SharePoint
  • Albergar aplicaciones y proyectos web en Internet Information Services (IIS) 7.5 Express
  • Soporte para Microsoft Web Platform Installer

Written by fernandomachadopiriz

10/03/2011 at 07:01

Una introducción simple al patrón Model View ViewModel para construir aplicaciones Silverlight y Windows Presentation Foundation

with 12 comments

Hace algún tiempo estuve buscando una introducción simple al patrón Model View ViewModel (también conocido como MVVM) y todos los ejemplos que encontré eran un poco complicados para mi gusto. En este artículo trataré de presentarles el patrón MVVM usando el ejemplo más simple posible, enfocándome solo en los conceptos clave de MVVM. En otros artículos entraré en detalle de conceptos relacionados, pero vamos a comenzar con lo básico.

MVVM es un sucesor de otro patrón bien conocido y exitoso como es el Model View Controller (MVC). MVC nació (como tantos otros patrones bien conocidos y exitosos) en el mundo de Smalltalk hace más de treinta años. Al usar MVC la aplicación se compone de tres tipos de objetos, con responsabilidades bien claras y diferenciadas:

  • El modelo. Habitualmente hay un solo modelo por aplicación. El modelo es responsable de todos los datos de la aplicación y de la lógica de negocios relacionada.
  • La vista o vistas. Una o más representaciones para el usuario final del modelo de la aplicación. La vista es responsable de mostrar los datos al usuario y de permitir la manipulación de los datos de la aplicación.
  • El controlador o controladores. Habitualmente hay un controlador por vista, aunque no es raro ver un controlador por entidad de dominio controlando varias vistas. El controlador es responsable de transferir datos desde el modelo hacia la vista asociada y viceversa. También es responsable de implementar el comportamiento de la vista para responder a las acciones de los usuarios.

image

Con MVC cada tipo de objeto es responsable de solo una cosa, lo que simplifica el desarrollo, comprensión y prueba del código. Además, es fácil reemplazar las vistas, o tener más de una vista de los mismos datos.

En el caso de las aplicaciones Silverlight o Windows Presentation Foundation (WPF/SL), el .NET Framework provee la capacidad de usar bindings para transferir datos desde y hacia la vista, por lo que el controlador solo es responsable de implementar el comportamiento de la vista. En este caso, el controlador es llamado modelo-vista (view model), dando origen al patrón MVVM:

  • El modelo. Lo mismo que en MVC.
  • La vista o vistas. Igual que en MVC.
  • El modelo-vista. Uno o más por vista. El modelo-vista es responsable de implementar el comportamiento de la vista para responder a las acciones del usuario y de exponer los datos del modelo de forma tal que sea fácil usar bindings en la vista.

image

MVVM comparte todos los beneficios de MVC, pero tiene un beneficio adicional: la simplificación que resulta de usar binding declarativo para transferir los datos desde y hacia el modelo a la vista.

Voy a mostrar cómo funciona MVVM con un ejemplo. El código que voy a estar usando es de mi aplicación de ejemplo Giving a Presentation (aunque los animo a descargar el archivo de instalación y el código fuente de CodePlex, no hay necesidad de hacerlo para entender este artículo).

Giving a Presentation es una simple aplicación para cambiar ciertas configuraciones del equipo mientras damos una presentación, por ejemplo, ocultar los íconos del escritorio, remover o reemplazar el fondo del escritorio, etc. Los cambios son deshechos cuando la presentación termina.

La capacidad para cambiar estas configuraciones es provista por partes extensibles y no está implementada en la propia aplicación (más detalles en este artículo). Por lo tanto, siendo estrictos, los datos que maneja Giving a Presentation son solo un valor lógico que indica si el usuario está dando una presentación o no: el usuario asigna el valor en verdadero cuando comienza la presentación y lo vuelve a falso cuando la presentación termina.

El código del modelo aparece a continuación. Como prometí, es muy simple; sólo tiene una propiedad lógica:

public class Model
{
    public bool GivingAPresentation { get; set; }
}

He aquí el código del modelo-vista. También es muy simple. Como el modelo, sólo tiene una propiedad lógica, cuyo valor se obtiene de una instancia del modelo:

public class MainViewModel
{
    private Model model;
    public bool GivingAPresentation
    {
        get { return model.GivingAPresentation; }
        set
        {
            model.GivingAPresentation = value;
        }
    }

    public MainViewModel()
    {
        this.model = new Model();
    }
}

La vista (sin ninguna extensión) luce así:

clip_image006

El código XAML correspondiente es:

<Window x:Class="GivingAPresentation.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:GivingAPresentation "
        Title="Giving a Presentation" Height="350" Width="525" Icon="/MvvmDemo;component/Images/Presentation.ico">
    <Window.Resources>
        <vm:MainViewModel x:Key="mainViewModel"/>
    </Window.Resources>
    <Grid>
        <CheckBox Content="I'm currently giving a presentation"
                  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,12,0,0"
                  IsChecked="{Binding Source={StaticResource mainViewModel}, Mode=TwoWay, Path=GivingAPresentation}" />
    </Grid>
</Window>

Es interesante mencionar que no hay code-behind para esta vista [1] (es más, he borrado el archivo MainView.xml.cs del proyecto, y obviamente la solución compila y la aplicación ejecuta perfectamente). ¿Se preguntan por qué? Porque no hay necesidad de ningún código en el code-behind de la clase; el comportamiento de la vista está programado en el modelo-vista, no en la vista, ¿recuerdan?

La vista está conectada con el modelo en tres pasos. Primero, un atributo xmlns en el nodo Window es usado para crear un alias vm al espacio de nombres GivingAPresentation con xmlns:vm=”clr-namespace:GivingAPresentation. Luego, una instancia del modelo-vista es creada en el nodo Window.Resources; el nombre de esta instancia es declarado con x:Key=”mainViewModel”. Finalmente la propiedad IsChecked de la casilla de verificación de la vista es bindeada con la propiedad GivingAPresentation del modelo-vista con IsChecked=”{Binding Source={StaticResource mainViewModel}, Mode=TwoWay, Path=GivingAPresentation}”.

Y eso es todo. WPF/SL hacen la magia de obtener el estado de la casilla de verificación del valor de la propiedad del modelo-vista, quién a su vez lo obtiene de la propiedad correspondiente del modelo. A través de esta cadena, un cambio en la vista se refleja en el modelo y viceversa.

Este ejemplo es tal vez demasiado simple, pero tiene todos los componentes del patrón MVVM, y muestra claramente los fundamentos para implementar aplicaciones WPF/SL usando ese patrón.

¿Qué sigue? Hay varias cosas, muy comunes en escenarios de aplicaciones del mundo real, que no están resueltas en absoluto en este ejemplo tan simple; por ejemplo:

  1. No sólo la vista, sino probablemente otros objetos, necesiten estar al tanto de los cambios en las propiedades del modelo-vista. Aquí es donde entra en juego la interfaz INotifyPropertyChanged. Al disparar un evento PropertyChanged cada vez que cambia el valor de una propiedad, otros objetos pueden reaccionar a esos cambios. Vale la pena mencionar que estos otros objetos no son conocidos por el modelo-vista, pero son notificados de todas formas, gracias a la infraestructura de eventos del .NET Framework.
  2. Es muy común que la vista pida al modelo-vista que ejecute ciertas acciones. Esto se puede lograr si el modelo-vista expone comandos, y la vista usa bindings para ciertas acciones (como el clic de un botón) a esos comandos.
  3. También es muy común que las aplicaciones de la vida real tengan varias vistas interdependientes que necesitan comunicarse entre ellas. Para mantener estas vistas, y sus modelos-vista asociados, independientes unos de otros, los modelos-vista pueden usar mensajes para comunicarse entre ellos.
  4. ¿Quién crea a quién? En este ejemplo la vista crea declarativamente el modelo-vista (en el código XAML de la vista), y el modelo-vista crea el modelo. En aplicaciones más grandes, este enfoque no siempre es adecuado, y son necesarias otras clases para manejar la creación de objetos.

Estos aspectos no son realmente parte del patrón MVVM, pero son realmente necesarios para implementar aplicaciones del mundo real usando WPF/SL; es por es que pueden verlos junto con el patrón MVVM en la literatura. Planeo cubrir estos temas en futuros artículos y no en este, para mantener esta simple introducción, simple.

Espero hayan disfrutado de la explicación. Espero verlos pronto. Adiós.


[1] En este ejemplo. En el código real de Giving a Presentation, el vista es responsable de tareas relacionadas con la presentación, como mostrar el ícono de notificación cuando se minimiza por ejemplo, que require code-behind en la vista.

Written by fernandomachadopiriz

09/06/2010 at 23:03

Generación de Unit Tests con Visual Studio 2010 y C# 4.0

with 2 comments

Este es el segundo artículo de la serie sobre herramientas y técnicas de testing  con Visual Studio 2010, Team Foundation Server 2010, Microsoft Test Manager 2010, y C# 4.0.

En el primer artículo mostraba cómo Visual Studio permite hacer test driven development.

Visual Studio también genera automáticamente unit tests a partir del código a probar. En este vídeo verán cómo crear un unit test para un método Subtract de la clase Calculator.

También pueden descargar el video.

Publicaré más videos próximamente. ¡No se los pierdan!

Written by fernandomachadopiriz

15/05/2010 at 00:38

Charlas en Facultad de Ingeniería de la Udelar: .NET Framework & C# 4.0 y Azure

with 2 comments

Hace poco tiempo Pablo García me invitó a dar unas charlas a sus alumnos de Taller de Sistemas de Información (gracias Pablo por la invitación). Una fue sobre .NET Framework y C# 4.0 y la otra sobre Windows Azure. Aquí les dejo las transparencias.

 image image

Written by fernandomachadopiriz

29/04/2010 at 13:50

Simple Introducción al Managed Extensibility Framework

with 3 comments

Es muy común que los desarrolladores ocupemos más tiempo modificando aplicaciones existentes que construyendo aplicaciones nuevas desde cero. Nuevos requerimientos de negocio suelen precisar de nuevas funcionalidades en las aplicaciones. La forma como se agregan estas nuevas funcionalidades hoy en día termina cuando generamos, probamos y distribuimos nuevamente la aplicación. Estas actividades generalmente afectan la aplicación completa y no sólo la funcionalidad agregada.

Cuando los requerimientos cambian, los desarrolladores debemos cambiar las funcionalidades de la aplicación. Después de años de evolución, el código que implementa estas funcionalidades suelen tener dependencias indeseables y esas modificaciones pueden tonar la aplicación inestable, o requerir extensas pruebas de regresión que aseguren que no se han introducido errores. También en este caso la historia termina en generar y distribuir de nuevo toda la aplicación.

Cada vez más los negocios cambian más y más rápido, para sobrevivir en un mundo global y competitivo. Y el software que hace que esos negocios funcionen, también tiene que poder cambiar y tiene que poder cambiar rápido.

Supongamos por un instante que cada funcionalidad de la aplicación puede ser descompuesta en una “parte”. Lo que necesitamos es la capacidad de desarrollar partes débilmente acopladas, independientes no sólo en su estructura sino también en su prueba y en su distribución; y que esas partes pueden ser fácilmente compuestas en una aplicación.

Los principios de Ingeniería de software para resolver esta situación se conocen desde hace tiempo y muchas organizaciones los aplican con éxito. Pero las soluciones suelen ser caso a caso y no están disponibles al público en general como nosotros.

Recientemente han aparecido frameworks para desarrollo de aplicaciones en partes. MEF es uno de ellos.

En MEF existen los siguientes roles:

  • Partes exportadas. Declaran que pueden ser usadas para componer una aplicación y el contrato que implementan. Son unidades independientes de desarrollo, compilación y distribución. Estar débilmente acopladas, tanto como las demás partes como la aplicación que compondrán, es decir, una parte no necesariamente conoce a las demás, ni sabe necesariamente en qué aplicación será usada.
  • Puntos de importación. Variables que contienen partes o colecciones de partes importadas que deben implementar cierto contrato. Las partes son creadas automáticamente a partir de la información contenido en catálogos de partes.
  • Catálogos de partes. Contienen definiciones de partes: dónde están y qué contrato implementan.
  • Contenedores de partes. Contienen partes instanciadas y realizan la composición de las partes.

A continuación voy a mostrarles cómo desarrollar una aplicación con MEF paso a paso. Para entender MEF la aplicación debe ser simple, pero debe ofrecer varias funcionalidades que se puedan descomponer en partes.

La aplicación en este caso me permite escribir texto y luego puedo transformarlo aplicando diferentes algoritmos. Cada algoritmo ofrece una funcionalidad diferente y eso es lo que voy a transformar en partes. La aplicación luce así:

image

La lista desplegable muestra las transformaciones que puedo aplicar:

image

El objetivo es desarrollar la interfaz de usuario y cada transformación de forma independiente. Ahí vamos.

El contrato que deben implementar las partes lo declaro con una interfaz IFilter:

public interface IFilter
{
    string Filter(string input);
}

Luego creo una parte (la transformación ToUnicodeFilter) implementando esa interfaz IFilter y declarándola como exportable en MEF con el atributo Export:

[Export(typeof(IFilter))]
public class ToUnicodeFilter : IFilter
{
    public string Filter(string input)
    {
        StringBuilder output = new StringBuilder();
        foreach (char item in input)
        {
            output.AppendFormat(" U+{0:x4}", (int)item);
        }
        return output.ToString();
    }
}

La transformación en este caso es convertir cada letra del texto recibido en su correspondiente representación Unicode.

Puedo tener tantas partes como quiera, mientras también implementen la interfaz IFilter y estén decoradas con el atributo Export.

Ahora vamos a la aplicación a programar la composición de las partes en la aplicación. Necesito un catálogo que describa las partes. En este ejemplo voy a tener todos los ensamblados con las partes en una carpeta llamada Extensions, así que uso un catálogo DirectoryCatalog.

DirectoryCatalog catalog = new DirectoryCatalog("Extensions");

También necesito un contenedor para las instancias de las partes y para armar la composición. Al contenedor le paso el catálogo para que tenga la información de dónde encontrar las partes:

CompositionContainer container = new CompositionContainer(catalog);

Ya casi estamos. Lo que necesito ahora es un punto donde importar las partes. En este caso puede haber varias transformaciones, así que declaro una IList<IFilter> que decoro con el atributo Import:

[ImportMany(typeof(IFilter))]
private IList<IFilter> filters = new List<IFilter>();

Lo último que hago es componer las partes, indicándole al contenedor dónde están los puntos de importación:

container.ComposeParts(this);

Luego puedo recorrer la lista para poblar los filtros en la lista desplegable:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    foreach (IFilter filter in filters)
    {
        comboBoxFilters.Items.Add(filter.GetType());
    }
}

Cuando el usuario hace clic en el botón Apply, se busca el filtro a ejecutar en la lista de filtros a partir del elemento seleccionado en la lista desplegable:

private void buttonApply_Click(object sender, RoutedEventArgs e)
{
    if (comboBoxFilters.SelectedIndex != -1)
    {
        int index = comboBoxFilters.SelectedIndex;
        IFilter filter = filters.ElementAt(index);
        textBoxOutput.Text = filter.Filter(textBoxInput.Text);
    }
}

Tres ensamblados intervienen aquí. El primero es donde está declarado IFilter. El segundo es donde está implementada la clase ToUnicodeFilter. El tercero es el de la propia aplicación. Lo interesante aquí es que para agregar una nueva transformación o para modificar una existente, lo único que tengo que hacer es distribuir el ensamblado que la contiene en la carpeta Extensions. El resto de los ensamblados no se ven afectados, ni siquiera el de la aplicación.

¿Cómo se logra que esto funcione casi de forma máquina? Cuando invoco el método ComposeParts del contenedor pasando como parámetro la propia aplicación, el contenedor busca todas las variables decoradas con ImportMany (o con Import) en la aplicación. En cada caso aparece también la interfaz requerida por cada punto de importación.

El contenedor también conoce el catálogo, pues lo paso como parámetro en el constructor. Como el catálogo tiene la información de todas partes, incluyendo qué partes implementan qué interfaz, puede encontrar que parte o partes implementan la interfaz de cada punto de importación. Como el catálogo también conoce en qué ensamblados están las partes, puede crear instancias de las partes apropiadas y asignarlas a las variables correspondientes a los puntos de importación.

Al final, la composición “se arma sola”, el trabajo lo hace MEF y no el programador. El programador solo “decora” los tipos con Export, las variables con Import, crea uno o más catálogos y el contenedor, y finalmente compone las partes. Simple, ¿no?

Recuerden que el desafío era desarrollar partes débilmente acopladas, independientes no sólo en su estructura sino también en su distribución; y que esas partes pudieran ser fácilmente compuestas en una aplicación. ¿Objetivo cumplido? Yo creo que sí.

Pueden descargar el código de esta aplicación de aquí. El ejemplo contiene más partes todavía de las que estoy mostrando aquí.

Vean también MEF Home y MEF Overview (en inglés).

En un próximo post voy a hablar de cómo asociar metadata a las partes, por ejemplo, para que en lugar de poner el nombre del tipo en la lista desplegable, aparezca un nombre más adecuado. Nos vemos.

Written by fernandomachadopiriz

15/04/2010 at 10:46

La explicación fácil para entender covarianza y contravarianza

with 15 comments

Una de las novedades más importantes de C#4.0 y .NET Framework 4.0 es la introducción de covarianza y contravarianza. Varias veces he presentado covarianza y contravarianza en las charlas de novedades de C# y .NET Framework 4.0, y también en el blog, pero no siento que toda la audiencia termine entendiendo fácilmente estos conceptos. Hasta ahora he partido de las definiciones formales de covarianza y varianza, para luego mostrar cómo se implementan en C#. Probablemente no sea el mejor enfoque, así que ahora voy a intentar explicar estos conceptos de otra manera. Aquí vamos.

Vean las siguientes clases Animal y Cat que desciende de Animal:

class Animal { }
class Cat : Animal { }

Las siguientes declaraciones son correctas en cualquier versión de C#:

Cat kitty = new Cat();
Animal animal = kitty;

Todo Cat es un Animal (eso es lo que significa que Cat hereda de Animal), por lo tanto puedo asignar la variable kitty a la variable animal. Hasta ahora no hay nada nuevo.

Vean ahora lo que sucede cuando intento hacer algo análogo con enumerables de Animal y Cat:

IEnumerable<Cat> cats = new List<Cat>();
IEnumerable<Animal> animals = cats;

Todo Cat es un Animal, por lo que intuitivamente todo enumerable de Cat es un enumerable de Animal, ¿cierto? No, falso, al menos para los compiladores anteriores a C# 4.0, que dicen que no pueden convertir IEnumerable<Cat> en IEnumerable<Animal> y me preguntan si me estará faltando un cast.

clip_image001

Puedo agregar el cast, pero es un cast inseguro. Es decir, el programa compila, pero en tiempo de ejecución veo una excepción InvalidCastException en el momento de la asignación.

Ahora bien, coincidamos que a pesar que el compilador de C# no acepte que una todo enumerable de Cat es un enumerable de Animal, intuitivamente aceptamos la afirmación, en forma análoga a la afirmación todo Cat es un Animal.

C# 4.0 resuelve el conflicto. El fragmento de código anterior compila y no genera ninguna excepción en tiempo de ejecución, tal como nuestra intuición nos indica.

¿Por qué el mismo código que compila en C# 4.0 no compila en los anteriores?

Antes de C# 4.0 la interfaz IEnumerable estaba declarada como:

public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

Mientras que en C# 4.0 está declarada como:

public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

Noten la palabra clave out junto al tipo parámetro T: sirve para indicar que la interfaz IEnumerable es covariante con respecto de T. En general, dado S<T>, la covarianza de S respecto de T implica que si la asignación de Y ← X es válida cuando X hereda de Y, entonces la asignación S<Y> ← S<X> también es válida.

Veamos ahora otro fragmento de código que involucra acciones (las acciones son delegados a funciones de la forma void Action<T>(T)) sobre Animal y Cat:

Action<Animal> doToAnimal =
    target => { Console.WriteLine(target.GetType()); };
Action<Cat> doToCat = doToAnimal;
doToCat(new Cat());

De nuevo, como todo Cat es un Animal, una Action<Animal> que puedo hacer con un Animal debería ser también una Action<Cat> que pueda hacer con un Cat. Vean que aunque la afirmación resulta razonable al decirla, los tipos parámetro están al revés que en el caso anterior: allá estaba asignando un enumerable definido en función de un Cat a un enumerable definido en función de un Animal, mientras que aquí estoy asignando una acción definida en función de Animal a una acción definida en función de Cat.

A pesar que la afirmación es razonable, a los compiladores anteriores a C# 4.0 no les gusta la asignación y arrojan al compilar un mensaje similar al del caso anterior: no se puede convertir una Action<Animal> en una Action<Cat>; en esta oportunidad no me pregunta si me está faltando un cast.

clip_image002

Nuevamente C# 4.0 resuelve el problema, y el código anterior sí compila. Veamos cómo están declaradas las acciones.

Antes de C# 4.0 el delegado Action estaba declarado como

public delegate void Action<T>(T obj)

Mientras que ahora en C# 4.0 está declarado así:

public delegate void Action<in T>(T obj)

Noten ahora la palabra clave in junto al tipo parámetro T: sirve para indicar que el delegado Action es contravariante con respecto de T. En general, dados S<T>, la contravarianza implica que si la asignación de Y ← X es válida cuando X hereda de Y, entonces la asignación S<X> ← S<Y> también es correcta.

En resumen, la covarianza en C# 4.0 permite que un método tenga un resultado de un tipo derivado del tipo definido como parámetro de un tipo genérico. De esta forma, permite asignaciones de tipos genéricos que siendo intuitivas, no eran posibles antes, tales como IEnumerable<Animal> IEnumerable<Cat>, cuando Cat hereda de Animal. Noten que IEnumerable sólo puede retornar instancias de T como resultado, no recibe instancias de T como parámetro. Por ello la palabra clave para declarar que IEnumerable es covariante respecto de T es out.

En forma análoga, la contravarianza permite que un método tenga argumentos de un tipo ancestro del tipo especificado como parámetro del tipo genérico. Así, permite también asignaciones que siendo razonables, no eran posibles, como por ejemplo Action<Cat>Action<Animal>. Vean que en este caso Action sólo puede recibir instancias, no las retorna. Por eso la palabra clave para declarar Action contravariante respecto de T es in.

En este artículo estoy mostrando un ejemplo de covarianza con una interfaz genérica y de contravarianza con un delegado genérico (con tipos parámetro); en un próximo artículo les mostraré otros ejemplos diferentes y les contaré que interfaces y delegados del .NET Framwork 4.0 son covariantes o contravariantes.

De aquí pueden descargar el código de ejemplo.

Para probarlo en compiladores anteriores a C# 4.0 y ver la diferencia, cambien el framework para el cual generan en las propiedades del proyecto:

clip_image003

Nos vemos en la próxima.

Written by fernandomachadopiriz

13/04/2010 at 08:42