Ontuts: Introducción a Silverlight: Parte I

En colaboración con ontuts.com, acabo de publicar el primer artículo de una serie introducctoria a Silverlight, totalmente desde cero. En este primer artículo contesto preguntas como qué y para qué es, entre otras muchas cosas.

Las aplicaciónes Web de última generación son una combinación entre
aplicaciones Web y aplicaciones de escritorio que ofrecen al usuario
una buena experiencia de usuario. Y alrededor de ellas, es donde nace
Silverlight. Una tecnología que se puede… ver… oír… !tocar! ¡sentir!

El artículo puede ser leído en:

http://web.ontuts.com/tutoriales/introduccion-a-microsoft-silverlight-parte-i/

Sígueme en:http://twitter.com/eugenioestrada

Despliegue distribuido de clientes en .NET problemas y futuro

Desde la beta 1 de Visual Studio 2010 llevo testeándolo, pero aun no me había atrevido a escribir nada. Pero esta mañana leí una cosa que me pareció bastante interesante.

Para aquellos que tenemos aplicaciones distribuidas usando .NET 3.5 SP1 tenemos bastantes problemas a la hora de la distribución o inclusión de nuevos clientes.

Estos problemas derivan de que .NET 3.5 SP1 es una recopilación de bastantes actualizaciones partiendo de .NET 2.0 como base:

image

Lo que supone instalar 6 actualizaciones acumulativas, esto sobre una instalación base de XP sin .NET. Sobre todo la última actualización .NET 3.5 SP1 se hizo más pesada de lo habitual. Ya que incluía parches para el .NET 2.0, para el .NET 3.0 y para .NET 3.5. Ya que aun que en el gráfico yo lo puse en ese orden, no fue ese el orden real de publicación, ya que el .NET 2.0 SP2 y el .NET 3.0 SP2 fueron publicados junto al .NET 3.5 SP1 y durante un tiempo solo se podían instalar con el .NET 3.5 SP1 (el gráfico de publicación lo podéis ver a continuación).

image

Esto supuso un gran problema. Si nosotros nuestro proyecto de .NET 2.0 (con Visual Studio 2005) lo migrábamos a Visual Studio 2008 SP1 (liberado junto a .NET 3.5 SP1) y compilábamos con .NET 2.0, realmente estaría compilando con .NET 2.0 SP2 y en nuestros clientes no funcionaría. El problema se vio agravado ya que el paquete de .NET 2.0 SP2 no estuvo disponible hasta 6 meses después de la liberación de .NET 3.5 SP1. Cosa que obligaba instalar en todos los clientes el monumental .NET 3.5 SP1 (que ocupaba 3 veces más que su original 2.0). No solo eso, la instalación de dicho paquete se hacía eterna (aproximadamente entre 45 min y 1 hora dependiendo de la máquina). Esto en una máquina, ni en diez, es problema. Pero si hablamos de un sistema distribuido con un número considerable de clientes, si que podría ser un problema, sobre todo garantizando el funcionamiento del sistema durante la implantación y su mantenimiento.

Otra solución posible sería el planteamiento del uso del Client Profile de .NET Framework, que es una versión reducida para clientes distribuidos. Pero, solo era posible la opción si partíamos de una instalación limpia (sin .NET) y solo disponible en XP (ya que Windows Vista trae consigo .NET 3.0 y Windows 7 tiene .NET 3.5 SP1).

Pero .NET 4.0 tiene grandes novedades en su .NET Framework 4 Client Profile. Como gran novedad, al contrario que su antecesor, se puede instalar en cualquier SO y plataforma donde .NET 4 Framework esté soportado. Siendo Client Profile un subset de .NET 4 completo y el .NET 4 completo es un superset del primero. No solo eso, además han conseguido reducir el Client Profile a un distribuible de apenas 30 MB, incluyendo las tecnologías más comunes de los clientes como Windows Forms o WPF. Por otra parte, Visual Studio 2010 Beta 2 en sus proyectos de escritorio tiene por defecto el Client Profile activado.

Siendo esta la tabla comparativa (extraída de un post de Scott Guthier):

 

 

.NET Framework 4 Client Profile (NEW)

.NET Framework 3.5 SP1 Client Profile

Supported OS

Supported on all platforms and  OSs that are supported by the .NET Framework (excluding IA64 and the Server Core role in W2K8)

Supported only on Windows XP 32-bit machines that did not have any .NET Framework version installed.

(Client Profile setup silently installs the full 3.5 SP1 Framework otherwise)

Redistributable

Supports redistributable as well as web download

Supports web download only

Add Remove Programs entries

The full Framework comprises the Client Profile and another part called “Extended”. Thus it has two entries in the Add/Remove Programs dialog (or Programs and Features window).

If you installed the Full Framework, you can switch to the Client Profile by simply removing “Extended” from Add/Remove Programs.

Single entry in Add Remove Programs

Visual Studio

Improved support for Client Profile targeting in Visual Studio 2010.

By default many Visual Studio 2010 Beta2 Client project target the NET4 Client Profile.

Single checkbox in Visual Studio 2008 Service Pack 1 “Application” Project properties for .NET Framework 3.5 projects. Client Profile support unavailable in out-of-the-box VS 2008.

Features

Includes new .NET 4  features (such as Managed Extensibility Framework (MEF), C# 4 Dynamic Keyword,etc) as well as features previously included in NET 3.5 SP1 Full (Speech, WPF Spell Check, etc)

Subset of features in .NET 3.5 SP1 Full

Espero que os sea útil e interesante 🙂

Follow me: http://twitter.com/eugenioestrada

Microsoft e Intel anuncian Silverlight para Moblin

Microsoft e Intel acaban de anunciar el desarrollo de una implementación especifica de Silverlight para el S.O. basado en Linux de Intel, Moblin. Dicho sistema operativo tiene un repositorio de aplicaciones similar al del iPhone, donde sería distribuída dicho paquete.

Ha llamado especialmente la atención este anuncio ya que ya existe una implementación de Silverlight para Linux, Moonlight, tras el amparo de Novell. Pero Microsoft e Intel han justificado una nueva implementación en que mientras que Novell, con Moonlight, su target son S.O. de escritorio. Microsoft seguirá desarrollando implementaciones especificas, como puede ser la de Moblin, la de Nokia, etc. Ya que está sería con la ayuda de Intel para conseguir una mejor experiencia en equipos basados en Atom.

Para más información:

Programa de desarrollo de Intel Atom: http://appdeveloper.intel.com/en-us/
Moblin: http://moblin.org/
Moonlight: http://www.mono-project.com/Moonlight
Noticia: http://www.theregister.co.uk/2009/09/24/silverlight_to_linux/

RIA Services, parámetros con colecciones

Para quien no conozca RIA Services, son un conjunto de servicios que mejoran mucho el desarrollo de aplicaciones con Silverlight. Desde el propio equipo la definen así:

Microsoft .NET RIA Services simplifies the traditional n-tier application pattern by bringing together the ASP.NET and Silverlight platforms. RIA Services provides a pattern to write application logic that runs on the mid-tier and controls access to data for queries, changes and custom operations.

image

Esta gráfica de Nikhil Kothari explica muy bien donde se encuentra los RIA Services.

Las principales ventajas de RIA Services contra otras tecnologías de Servicios presentadas por Microsoft, son su integración con ASP.NET (por temas de autenticación, roles, etc.) como su ligera serialización usando Json.

El principal problema es que está muy centrado en las entidades tanto de la base de datos (Linq to SQL, Entity Framework, etc.) como las que nosotros podamos crear a mano. Centrándose así en las operaciones Add, Update, Delete, Get, etc. de las propias entidades.

El problema nos lo encontramos cuando queremos enviar del cliente al servidor una colección de entidades del servicio (entendamos como entidades del servicio aquellas que se exponen con un método Get, Update, Delete Add, etc.).

Las limitaciones de RIA Services se extienden hasta el punto de que un método solo puede devolver una colección de entidades, una entidad o un tipo serializable “built-in” (como los tipos básicos, el guid y poco más). Y los parámetros del método solo soporta los tipos básicos serializables “built-in” y una entidad.

¡No colecciones!

Para solucionar eso, primero debemos crear un Custom Operation y donde queríamos poner una colección he puesto un objeto serializado en Json. Y así lo serializo antes de llamar al método y justo en el manejador del método en el servicio.

La extension method que he usado para serializar la he publicado en mi proyecto SilverBox, que liberé la semana pasada en CodePlex:

http://silverbox.codeplex.com

Debéis obtener el último commit subido al Source Control y compilar la librería. Luego solo debéis referenciar la librería SilverBox.dll y en el archivo de código añadir la directiva “using SilverBox.Extensions”.

Y los tipos string y object tendrá un método SerializeToJson y Deserialize.

MonoTouch, C# para tu iPhone

Miguel de Icaza, lider del proyecto Mono, acaba de anunciar de que en septiembre van a publicar la primera versión de MonoTouch. Una implementación de Mono en tu iPhone.

Tal cual nos los cuenta Miguel de Icaza es un “A C# API for building Cocoa applications”, vamos que no vamos a contar con todas las herramientas de .NET, ni su sandbox, ni su JIT, ni nada. Pero para aquellos que usamos C# y .NET, es un acercamiento que de otra forma no sería posible.

Para la segunda versión están pensando en preparar un cliente de Silverlight y una implementación de LinQ, pero el propio Miguel reconoce que puede ser complicado debido a las limitaciones que Apple pone.

De todas formas, creo que es muy interesante.

Miguel de Icaza está intentando reunir una serie de programadores que estén interesados en probar la plataforma. Así que ya sabéis sumaros a la nueva iniciativa en:

Formulario de inscripción

Y para más información:

Proyecto MonoTouch: http://www.mono-project.com/MonoTouch
Anuncio de Miguel de Icaza: http://tirania.org/blog/archive/2009/Aug-03-3.html

Doble Click en Silverlight usando Behaviors

Silverlight no tiene soporte en los UIElement para el evento Doble Click. Pero con Silverlight 3 y Blend 3 es sencillo desarrollar una solución genérica para todos los UIElement y extenderlos con el evento Doble Click.

Para ello usaremos la librería System.Windows.Interactivity que se encuentra en el SDK de Expression Blend 3 (%programfiles%Microsoft SDKsExpressionblend InteractivityLibrariesSilverlight”). Una vez que ya tengamos esa librería referenciada en nuestro proyecto, debemos crear un Behavior:

using System.Windows;
using System.Windows.Interactivity;

public class MouseDoubleClickBehavior : Behavior<UIElement>
{
    
}

Como veis lo hacemos genérico para cualquier UIElement, ya que es la clase base de todos los elementos que tienen los eventos del ratón. Para trabajar con los Behavoirs debemos sobrescribir varios métodos de la clase base:

private AutomationPeer Peer { get; set; }

protected override void OnAttached()
{
    Peer = FrameworkElementAutomationPeer.FromElement(AssociatedObject) ??
           FrameworkElementAutomationPeer.CreatePeerForElement(AssociatedObject);

    AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
    base.OnAttached();
}

protected override void OnDetaching()
{
    AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
    base.OnDetaching();
}

Con estos métodos podemos controlar cuando el Behavior se asociada y se desasocia, debemos usar la clase AutimationPeer para darle funcionalidad al objeto AssociatedObject. Y ese mismo objeto de tipo UIElement es con el que nos subscribiremos al evento MouseLeftButton. Como veis tenemos ahí el controlador AssociatedObject_MouseLeftButtonUp, que el que dará la lógica a nuestro behavior:

private bool _waiting;
private DateTime _waitingSince;

private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (_waiting)
    {
        if (DateTime.Now.Subtract(_waitingSince).Milliseconds < Interval)
            OnMouseDoubleClick(e);
        _waiting = false;
    }
    else
    {
        _waiting = true;
        _waitingSince = DateTime.Now;
    }
}

private void OnMouseDoubleClick(MouseButtonEventArgs args)
{
    if (MouseDoubleClick != null)
        MouseDoubleClick(AssociatedObject, args);
}

public event MouseButtonEventHandler MouseDoubleClick;
private int _interval = 500;
public int Interval
{
    get { return _interval; }
    set { _interval = value; }
}

La lógica como veis es sencilla, hemos creado el evento MouseDoubleClick y en caso de que ya hayamos hecho un Click y el tiempo sea menor al que le establecemos en la propiedad Interval (Por defecto le pongo 500), el evento será lanzado.

Con esto ya podríamos en el XAML hacer algo parecido a los siguiente:

<Image>
	<i:Interaction.Behaviors>
		<my:MouseDoubleClickBehavior
            MouseDoubleClick="MouseDoubleClick" 
            Interval="500" />
	</i:Interaction.Behaviors>
</Image>

Y así ya podríamos añadirlo a todos los controles que deriven de UIElement que tengamos.

En otro artículo os comentaré como solucionar el Scroll con el Mouse Wheel usando otro Behavior 😉

Gestalt Beta, azúcar para la web

Desde los MIX Online Labs, nos traen un nuevo producto beta que tiene muy buena pinta. La descripción oficial es:

“Gestalt es una librería liberada por MIX Online Labs que te permite escribir código Ruby, Python y XAML en tus páginas (X)HTML. Te permite construir aplicaciones ricas y más poderosas casando los beneficios de lenguajes expresivos, modernos compiladores, AJAX y RIAs con el modelo de desarrollo escribe>guarda>refresca de la Web”

Sus características nos las venden así:

Haz hueco para Ruby y Python, Javascript

XAML para gráficos avanzados

Compilación transparente y flamante velocidad

Mira mamá, ¡sin herramientas!

Llevando el SEO (Optimización de Motores de Búsqueda) al siguiente nivel

Yo soy un Mac, yo soy un PC

Para ver que dicen de ellos, pasaros por la página del proyecto.

Un primer ejemplo que nos enseñan es el siguiente:

<html>
<head>
  <script src="js/jquery.js" type="text/javascript"></script>
  <script src="js/gestalt.js" type="text/javascript"></script> 
</head>
<body>

<input id="say_hello" type="button" value="Say, Hello!" />

<script language="ruby">
document.say_hello.onclick do |s,e|
  window.alert "Hello, World!"
end
</script>
</body>
</html>

Y esa es la forma de crear un botón que dice “Hello, World!” usando Ruby.

Sinceramente es una pasada, se pueden crear animaciones con XAML y todo.

Proyecto Gestalt: http://www.visitmix.com/Labs/gestalt/

.NUGG: Speed of Light: Optimización de SQL Server

Esta sesión está dedicada a detallar las técnicas y herramientas que nos permitirán exprimir el rendimiento de nuestro SQL Server al máximo, haciendo un repaso por la teoría implicada, y pasando directamente a ejemplos del Mundo Real™. Se abordarán buenas prácticas de indizado, las consideraciones de almacenamiento más relevantes, el análisis de planes de ejecución, así como la utilización de nuevas características de SQL Server 2008 para optimizar cargas de trabajo.

1.- Arquitectura general de SQL Server

2.- Metodología Waits & Queues: Monitorización de Esperas en SQL Server

3.- Optimización de Almacenamiento

4.- Optimización del Uso de Memoria

5.- Aislamiento Transaccional

6.- Optimización de Consultas

Fecha y hora:

17 de julio de 2009 : 17:00 a 19:00

Dirección:

Edificio Xoana Capdevielle
Campus de Elviña s/n
A Coruña – 15071

Registro:

http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032421168&Culture=es-ES

Cómo llegar:

http://maps.google.es/maps/ms?ie=UTF8&hl=es&msa=0&msid=112446040967221334224.00044475947d03a539b25&t=h&z=15

MCTS .NET 3.5 WPF : Examen 70-502 aprobado!!!

Esta tarde he aprobado el examen 70-502 que corresponde al MCTS de .NET Framework 3.5: Windows Presentation Foundation.

El examen consta como el libro de preparación explica, de seis partes:

  • Creación de una aplicación WPF
  • Creación de interfaces de usuario
  • Agregar y administrar contenido
  • Enlace a origenes de datos
  • Personalización de la apariencia
  • Configuración e implementación de aplicaciones de WPF

Con esto he obtenido la ceritficación de MCTS. Las próxima será la de ASP.NET que haré el examen en los proximos días.

Problemas y soluciones: Entity Framework, vistas y claves

Uno de los grandes problemas que me he encontrado a la hora de trabajar con Entity Framework (EF) es la de mapear una vista.

¿Dónde está el problema?

El problema está que una entidad de EF debe tener una clave primaria y las vistas no tienen claves primarias.

image

En una vista como la anterior realmente no tenemos una clave definida en la base de datos ya que los datos filtrados por Entidad generaría una gráfica como la siguiente:

image

Por defecto EF infiere que Entidad es una clave, lo infiere a partir de aquellos campos que SQL Server dice que no pueden ser nulos. En principio no da ningún problema, pero tenemos dos casos en los que ya encontramos conflictos.

  1. Obtenemos más de un resultado con Entidad idéntica. Al rellenar los objetos EF, presupone que al tener la misma clave primaria son el mismo objeto por lo que siempre tendríamos el primer objeto creado.
  2. Si filtramos por Entidad exclusivamente, EF presupone que solo vendrá un resultado por lo tanto se produce una excepción.

Hasta aquí bien, la solución podría ser quitar esa clave, EF no nos deja:

“Toda entidad tiene que tener una clave primaria”

¿Solución?

Para ello debemos de crear una clave artificial, el rowcount de nuestra vista puede ser una opción, ya que todas las claves deben ser distintas. Pero como aun así nuestro Entity Framework no lo detecta como clave debemos emergernos en el EDMX y modificar el XML a mano.

Para ello cabe destacar que el fichero XML tiene un elemento llamado <edmx:Runtime> que es el que a nosotros nos interesa y que éste consta de tres partes:

  1. SSDL: StorageModels: El modelo importado de la base de datos
  2. CSDL: ConceptualModels: El modelo generado a partir del importado y el que representará cada una de las entidades que luego usaremos por código
  3. C-S: Mappings: Es la que une ambos modelos

Nosotros primero debemos modificar el SSDL, el siguiente es el :

<EntityType Name="vXXXX">
  <Key
    <PropertyRef Name="Entidad" /> 
  </Key
  <Property Name="IDPK" Type="bigint" /> 
  <Property Name="Entidad" Type="int" Nullable="false" /> 
  <Property Name="FechaPrevista" Type="datetime" /> 
  <Property Name="Sobres" Type="int" />
</EntityType>

Este sería el modelo importado tal cual lo importó el diseñador. Como veis hemos creado el campo IDPK con el rowcount para establecerlo como clave. Para poder hacerlo se debe de hacer lo siguiente:

 

<EntityType Name="vXXXX"
  <Key
    <PropertyRef Name="IDPK" /> 
  </Key
  <Property Name="IDPK" Type="bigint" Nullable="false" /> 
  <Property Name="Entidad" Type="int" /> 
  <Property Name="FechaPrevista" Type="datetime" />
  <Property Name="Sobres" Type="int" />
</EntityType>

Entonces en el modelo de la base de datos ya tenemos IDPK como clave. Ahora solo nos queda cambiarlo en el diseñador. Y para ello debemos hacer click derecho en el campo y establecerlo como clave:

image 

Y así ya podremos trabajar normalmente con nuestra entidad.

Problemas posteriores

Problemas tendremos después cuando actualicemos el modelo desde la base de datos, porque el SSDL se modificará y tendremos que hacer a mano los cambios que ahora hemos hecho. En cambio en el diseñador no tendremos que hacer nada.