Tech·Ed by raona

Wednesday, November 29, 2006

DEV302 - XNA & the future of game development

EEehhhh.... una sesión de XNA en el Tech·ed??? Pues sí.

Vale, vale fue muy introductoria, pero es que tampoco estábamos en la GDC o en el Gamefest, así que supongo que no se podía esperar otra cosa. En cualquier caso fue una sorpresa muy agradable... al menos para mí, y al juzgar por el lleno de la sala, por más gente.

La sesión estuvo muy bien aunque sólo fuera para cambiar un poco el chip y para los que desarrollamos juegos como hobby todavía mejor. En fin, si queréis un comentario más técnico de la sesión, pasaros por este post de mi blog dedicado al desarrollo de videojuegos en XNA.

Para los que quieran un resumen rápido: XNA es el nuevo framework de desarrollo de videojuegos usando .NET (C# por el momento). La versión actual (beta 2) trabaja sobre DirectX9 y .NET Framework 2.0. Sustituye a la API de Managed DirectX y facilita enormemente la creación de videojuegos.
Evidentemente hay un impacto de rendimiento que no hace muy factible desarrollar un videojuego comercial 100% en XNA hoy dia, pero es posible que en un futuro a medio plazo eso deje de ser así. Y además XNA tiene un as en la manga: es cross-platform entre PC y XBOX 360.
En la sesión se desarrolló un juego partiendo desde cero. Era un juego simple, en 2D, pero contenía los elementos básicos de cualquier juego (gráficos, animaciones y audio).

En fin... una sesión distinta, sin duda.

ARC309 - Security is a feature

Vale... no debería decir esto pero.... vaya tostón de sesión que fue esa.

Seguramente la culpa no fue del ponente, quizá fue que mis expectativas al respecto de la sesión no se correspondieron a la realidad.
Antes que nada, los que sepáis catalán pasaros por el blog que hicimos en raona cuando asistimos al Enterprise Architect Summit 2005. Una vez estéis allí le dais a Ctrl+F y buscais "Workshop: Developing and Enforcing Security Policies" y iréis a parar un post mío sobre una sesión de seguridad que se dio en el EAS2005. Pues bien, el 80% de la sesión del EAS2005 se repitió en esta del tech·ed. La verdad es que salí con una sensación de deja-vu (y buscando paredes que no existían), hasta que recordé donde había oído antes lo mismo (o algo muy parecido).

La sesión versaba sobre 10 consejos para mejorar la seguridad, siempre teniendo el principio que daba título a la sesión: como la seguridad no es un añadido si no una funcionalidad debe pensarse sobre ella en el tiempo de análisis.

Consejo 1. Analizar los posibles ataques
Basarse en el modelo STRIDE de ataques. Este modelo determina los siguientes tipos de ataques:
  • Spoofing identity
    • El atacante quiere ser alguien que no es (puede ser client spoofing para acceder a recursos de un servidor o server spoofing para obtener datos de clientes).
    • Mitigación: Mecanismos de autenticación fuertes. Alternativas a login/pwd
  • Tampering with data
    • El atacante modifica los datos de la aplicación
    • Mitigación: Usar firmas digitales, hash codes y canales seguros de comunicación
  • Repudiation
    • El atacante puede negar acciones que haya hecho
    • Mitigación: Logs de auditoría, firmas digitales y timestamps
  • Information disclosure
    • El atacante puede acceder a datos confidenciales
    • Mitigación: Obscuración, encriptación, control de acceso, autenticación fuerte
  • Denial of Service
    • El atacante puede generar DoS debido a males diseños
    • Mitigación: Aumentar disponibilidad y fiabilidad. Diseñar medidas preventivas.
  • Escalation of Privilege
    • El atacante obtiene privilegios que no le corresponden (generalmente por inyección de código).
    • Mitigación: Validar todas las entradas.
Consejo 2: Protección, detección y reacción
Protección al 100% para todos los problemas es imposible. Por ello no sólo es importante la detección de todos los problemas sinó también la reacción tomada cuando son detectados.

Consejo 3: All input is evil
Una de las máximas de seguridad: Toda entrada provenga de donde provenga es susceptible de generar problemas de seguridad (generalmente por ataques de inyección). Debe validarse toda entrada de datos.

Consejo 4: No reinventar la rueda
Basarse en tecnologías conocidas y probadas antes que en tecnologías propias. P.ej. no desarrollar nuestros protocolos de seguridad o encriptación.

Consejo 5: Usar siempre el mínimo privilegio necesario
Ejecutar las aplicaciones siempre con el privilegio mínimo. La mayoría de aplicaciones no requieren privilegios de administrador.
Bueno, aquí tengo una nota personal: muchas aplicaciones de windows están mal diseñadas y requieren privilegios administrativos cuando no deberían. Ello, junto con que windows mismo exige privilegios administrativos para ejecutar muchas acciones han hecho que la mayoría de usuarios sean (seamos) administradores locales. La tecnología UAC de Vista va precisamente en este camino: ejecutar las aplicaciones sin privilegios administrativos y sólo darlos bajo determinadas circunstancias de forma controlada.
Por otro lado en .NET existe la posibilidad de que una aplicación se reduzca a si misma los privilegios de seguridad, aunque el usuario y la configuración de la máquina le den más privilegios. Este camino es muy interesante.

Consejo 6: Criptografía NO garantiza seguridad
Pues eso. De nada sirve encriptar todos nuestros mensajes si las claves generadas son débiles, o no están bien guardadas o son intercambiadas por canales no seguros.
Además debe tenerse presente de que la criptografía no garantiza la integridad de los datos.

Consejo 7: Firewalls NO garantizan seguridad
Un firewall protege la red, pero las aplicaciones requieren ser accedidas (por lo que el firewall no las protege)... y más del 70% de las vulnerabilidades de seguridad están a nivel de aplicación.

Consejo 8: Secure defaults & failure modes
No habilitar nada por defecto que pueda suponer un problema de seguridad. P.ej. la instalación por defecto de IIS7 no instala ningún módulo susceptible de ser atacable (comparar eso con versiones de hace algunos años...)

Consejo 9: Usar herramientas
No solucionan todo, pero ayudan.
Realizar tests de penetración y revisión de código. Si es necesario, externalizarlos.

Consejo 10: Sentido común
Seguramente el primero en importancia ;-)

En fin, eso fue lo que dio de si esta sesión... que seguramente no fue mala, pero para mis expectativas demasiado básica (lo reconozco: yo esperaba una sesión sobre lo que ofrece .NET 3.0 y Vista a nivel de seguridad).

DEV212 - .NET vs J2EE

MMmm... asistí a esta sesión para saciar mi morbosidad: qué podian decir de una comparación entre .NET y J2EE en un tech·ed?
Bueno, antes que nada aclarar que el ponente era David Chapell, que es una de esas personas que tiene la virtud de no decir casi nada pero divertir al personal (por algo es consultor). David Chapell es un consultor externo a Microsoft, así que al menos la sesión podía tener algo de objetividad.
Todo lo que se contó fue muuuuuy introductorio pero al menos pasamos un buen rato :)

Primero hizo una história de las dos plataformas enfrentadas (Microsoft vs Java), remontándose al 1996. Los principales hitos de esa historia serian:
  1. 1996: Microsoft lanza DNA, que no es mas que un paraguas que agrupa numerosas de las tecnologías existentes en aquel momento (ASP, ADO, MTS). Por aquel entonces Java era un lenguage orientado al cliente. Pasada ya la excitación de los applets, el focus de Java eran las aplicaciones de escritorio.
  2. 1999: Sun lanza la especificación J2EE, que recoge varias APIs y tecnologías para Java para el desarrollo de aplicaciones de escritorio. En este punto la batalla es entre COM+ y EJBs, entre ASP y JSP/Servlets y entre ADO y JDBC.
  3. 2002: Microsoft lanza .NET 1.0, con un conjunto de tecnologías nuevas (ASP.NET, ADO.NET, Enterprise services y ASMX).
  4. 2003: Sun lanza la revisión 1.4 de J2EE. La gran incorporación es JAX-RPC que compite directamente con ASMX.
  5. 2005: Sale el .NET Framework 2.0 que no aporta ninguna novedad destacable.
Y el futuro (bueno, en el caso de .NET ya es el presente)?
Por parte de .NET se trata de .NET Framework 3.0, que presenta WF, WCF y WPF como principales novedades.
Por parte de Java??? pues depende a que actor Java sigamos.

Por parte de Sun, a través de la JCP, saldrá Java EE 5 (nueva denominación de J2EE), cuyas principales novedades son EJB3 y Jax-ws (que reemplaza al obsoleto jax-rpc).
Por parte de OpenSoA el futuro de Java se encamina a SCA (Service Components Architecture) y SDO (Service Data Objects).

Comparación .NET 3 vs Java EE 5
Java EE 5 es una evolución de las APIs contenidas en J2EE 1.4. Una de las principales novedades es que en EJB3 los entity bean desaparecen y son sustituídos por JPA (Java Persistence Api). JPA no solo deja obsoletos a los entity beans sino también a JDO.
No tiene equivalente a Workflow Foundation
No tiene equivalente a Windows Communication Foundation. En Java EE 5, siguen habiendo varias APIs de comunicación (RMI, EJB3, jax-ws y JMS) en función del tipo aplicación que se esté construyendo.

Comparación .NET 3 vs OpenSoA
OpenSoA mapea mucho mejor a .NET Framework 3
El equivalente de Workflow Foundation en OpenSoA es BPEL
BPEL es un lenguage XML (mantenido por OASIS), del cual dijo que era poco productivo pero que existían numerosas herramientas gráficas que lo generaban. El principal problema de BPEL es que aunque es estándard le hacen falta extensiones no estándares para dar soporte a actividades que quedan fuera de su definición, pero que son necesarias (p.ej. interacción humana, acceso a datos). El problema es el de siempre: cada motor de BPEL ha terminando desarrollando sus propias extensiones.

El equivalente a WCF en OpenSoA es SCA, que ofrece una API de comunicaciones unificada.

Chapell se posicionó a favor de Workflow Foundation en contra de BPEL, y al respecto de WCF vs SCA dijo que a su parecer son muy parecidas aunque en algunos aspectos SCA le parece ligeramente mejor enfocada que WCF (pero no dijo cuales).

Ni en Java EE 5 ni en OpenSoA hay equivalente para WPF, pero seguramente este seria un componente más de cliente que de servidor. En el mundo Java actual hay tres grandes APIs para el desarrollo de interfaces gráficas: la obsoleta AWT (de Sun), SWING/JFC (de Sun) y SWT (IBM/Eclipse).

Conclusiones

Chapell planteó aquí que uno de los problemas de Java es que al no estar todo en manos de una misma compañía había ciertos desarrollos que eran casi imposibles. Por ejemplo algo parecido a LINQ (que requiere modificar Visual Studio, el lenguage C# y el CLR) es muy complicado en el mundo Java, porque el entorno de desarrollo está en unas manos (eclipse), el lenguaje en otras (sun) y los servidores en otras (Bea, Ibm,...). Evidentemente esa decentralización también puede verse como una ventaja, todo son puntos de vista ;-)

Mis conclusiones
Estoy bastante de acuerdo con muchas de las ideas de David Chappell. Que Sun no ha hecho las cosas bien con Java creo que hay una gran mayoría de gente que lo piensa. Lo cierto es que Chappell criticó con dureza a Sun y repartió elogios entre OpenSoA y Microsoft. Que OpenSoA se han posicionado como una muy buena alternativa a Sun para el futuro de Java es un hecho constatado, pero deberá verse la acogida que tenga SCA cuando salga y si es capaz de aglutinar a su alrededor a la comunidad de desarrolladores de Java.

Links finales
Este post ha sido prolífico en siglas y conceptos, así que voy a poner un conjunto de enlaces para más información.
  1. Los contendientes: Por un lado .NET y por otro Java.
  2. Los equipos: El Framework 3.0 por un lado. J2EE por otro y OpenSoA por otro.
  3. Las tecnologías
    1. .NET: WPF, WCF, WF
    2. Java EE: EJB3, JPA, JAX-WS, los obsoletos JDO y JAX-RPC
    3. OpenSoA: SCA, SDO
    4. OASIS: BPEL
  4. Otras tecnologías mencionadas: AWT, Swing, SWT
  5. No hay nostalgia en Microsoft... (www.microsoft.com/dna).

DEV232 - IIS 7.0: End to End Overview

Una nueva sesión del Tech·Ed... Esta iba sobre las novedades de IIS7.0 y ofrecía una visión general del mismo.

Primero vimos las principales novedades de IIS7 respecto IIS6
  • Seguridad: Muchos componentes que antes estaban en el "kernel" ahora son modulares (p.ej. CGI).
  • Extensibilidad: IIS7 aporta una API nueva (tanto nativa como managed) para temas de extensibilidad. Además ofrece soporte integrada para los módulos ASP.NET
  • Configuración: Basada en ficheros XML, con el mismo esquema que los ficheros de configuración de ASP.NET. Aparece además inetmgr una herramienta de configuración con interfaz gráfica (a l'estilo de lo que viene haciendo MS últimamente).
  • Managment: Aparece una herramienta de línea de comandos que permitee realizar cualquier operación con IIS.
Modularidad
Uno de los aspectos claves de IIS7 es su construcción modular. Casi todo es un módulo que se carga o no en función de lo que indique el fichero de configuración. Existen más de 40 módulos. Por ejemplo varios módulos de autenticación (Digest, Windows,...), varios de desarrollos de aplicaciones (ASP, ASP.NET,...) y así ir siguiendo.
El setup por defecto de IIS7 instala solamente los módulos necesarios para servir páginas estáticas con autenticación anónima (jejejee... problemas de seguridad mínimos).
Es posible incluso desactivar todos los módulos y IIS sólo carga la pipe-line (la pipe-line es quien genera los distintos eventos a los que los módulos se pueden suscribir).

Extensibilidad
IIS6 se extiende mediante filtros ISAPI y extensiones ISAPI. Muy potentes pero complejas de desarrollar y no hay soporte managed para ISAPI.
Con IIS6 se pueden crear módulos con código managed pero esos módulos deben ser procesados por la extensión ISAPI de ASP.NET antes de ser invocados. Es decir, la request debe pasar por toda la pipe-line de IIS6, hasta llegar a la extensión ISAPI de ASP.NET y entonces pasar por toda la pipe-line de ASP.NET.
En IIS7 se pueden combinar Handlers de ASP.NET (IHttpHandlers) con los nativos (filtros o extensiones ISAPI) y la pipe-line es compartida. Eso significa que una request ya no debe pasar por el pipe-line de ASP.NET antes de poder ser tratada por un IHttpHandler.
De igual forma podemos tener módulos ASP.NET (IHttpModules) que se pueden suscribir a esta pipe-line compartida. Esos IHttpModules también se cargan o no en función de lo que indique el fichero de configuración del servidor.

Aquí hizo una demo, donde creo un IHttpHandler, que capturaba todas las requests a imágenes y les añadía una marca de agua a modo de copyright. A diferencia de IIS6 este IHttpHandler era a nivel de servidor IIS.

Configuración
Muere la metabase de IIS y toda la configuración es ahora basada en fichero XML (basada en el esquema de ASP.NET). El fichero principal se llama ApplicationHost.config (jejeeee... se ve que IIS tiene pretensiones de servidor de aplicaciones).
La configuración de cada aplicación web se realiza mediante el web.config (por lo que es compartido automáticamente si la aplicación es asp.net), y los ficheros de configuración de cada aplicación pueden redefinir parámetros establecidos en el ApplicationHost.config siempre que éste último lo permita.

Aquí hizo una demo: habilito la cache (tag <cacge> de web.config) y comprobamos como el IHttpHandler de la demo anterior pasaba de soportar tasas de 8 req/s a más de 400 req/s.

Managment
IIS7 viene con un proveedor WMI completamente nuevo.
Nueva herramienta de configuración con interfaz gráfica (no basada en MMC, como todas las últimas).
La herramienta en línea de comandos AppCmd permite configurar cualquier cosa del servidor, ya no son necesarios los scripts vbs que vienen con IIS6 (de hecho para que funcionen los scripts de managment de IIS6 debe instalarse un módulo de compatibilidad que no se instala por defecto).
En este punto nos hizo una demo de AppCmd, creando 10 aplicaciones web desde un fichero bat.

Resolución de errores
IIS7 añade páginas renovadas para errores HTTP 500 con detalles adicionales del error y soporte mejorado para custom-errors. Al estilo de ASP.NET las páginas pueden ser distintas para localhost y para clientes externos.
Aparece también la herramienta FREB que permite realizar un seguimiento de lo ocurrido cuando una request falla. Genera un xml (con una xslt asociada para su visualización) donde hay información de la request en cada paso de la pipe-line. Se guarda un xml por cada request fallada, dentro del directorio de logs.

Y esto fue todo lo que nos contaron... Bastante interesante todo, no?

DEVWD30 - Developing for Windows Vista

Buenoooo... el título no era exactamente así, pero no me acuerdo del título exacto.
Esta sesión era una whiteboard discussion, es decir una sesión más íntima, en una sala más pequeña (a rebosar, eso sí) y donde la participación del público se convierte en el hilo conductor de la charla.
Esta charla iba sobre el desarrollo de aplicaciones Windows Vista. En concreto sobre que es lo que aporta de nuevo Vista y que no está en el .NET Framework 3.0. Así se comentaron temas de UAC, Restart Manager y Aero. La verdad es que teoricamente la sesión trataba 10 puntos fundamentales para la programación de aplicaciones Vista, pero apenas hubo tiempo de tratar estos tres, ya que la participación fue constante haciendo multitud de preguntas.

Fue una sesión muy, muy, muy interesante, y es que ahora que el .NET Framework 3.0 también está en XP, es un valor añadido saber aprovechar las capacidades adicionales de Vista para que las aplicaciones se integren en el nuevo sistema operativo.

DEV306 - LINQ to SQL

Buenooo... una nueva sesión sobre LINQ, continuación de la anterior DEV323 (C# 3.0). En este caso se trataba de explorar las capacidades de LINQ para el mapeo de entidades relacionales de la BBDD a objetos de negocio.

Antes que nada un repaso a los principales problemas de usar comandos SQL embebidos en cadenas para acceder a la BBDD:
  1. Queries son cadenas, por lo tanto el compilador no puede ayudar.
  2. Parámetros son loosely-bound y tipo de retorno es un loosely-typed resultset, por lo tanto no se pueden hacer chequeos en tiempo de compilación.
La idea de LINQ to SQL es la misma que la multitud de ORM mappers que existen hoy día: generar un conjunto de clases para representar la estructura de datos de la BBDD subyacente. En el caso de LINQ:
  1. La conexión a la BBDD és una clase derivada de DataContext
  2. Tablas y vistas son convertidas a clases
  3. Columnas y Relaciones son propiedades de las clases.
  4. Stored procedures son métodos.
Generación del mapping

Para crear el mapping entre la BBDD y las clases de LINQ:
  1. Decidir que tablas de la BBDD se quieren mapear a clases .NET
  2. Usar el atributo [Column] a las propiedades que se quieran mapear.
    1. Usar [Column(Id=true)] para la clave primaria.
  3. Usar el atributo [Table(Name="Foo")] para mapear tablas.
  4. Declarar la clase Db derivada de DataContext.
    1. Añadir miembros Table<T> siendo T las clases Table que hemos creado.
    2. Invocar al constructor de DataContext con la cadena de conexión correspondiente.
  5. Crear métodos en la clase Db para los stored procedures y usar el atributo [StoredProcedure] para mapearlos.
  6. Crear objeto Db y lanzar consultas usando query expressions.
    1. LINQ convierte la query expression en consultas SQL de forma automática.
Otra opción es usar un fichero XML que tenga información sobre el mapping, en lugar de tener que usar atributos: las clases deben crearse igualmente pero sin usar ningún atributo, y al crear la clase Db se crea pasando un parámetro XmlMappingSource(XmlMappingSource.FromUrl("..."));

La tercera opción para generar el mapeo es usar Visual Studio: Project -> Add -> LINQ to SQL Mappint y usar el server explorer de Visual Studio, para arrastrar tablas y generar el código (genera partial clases).

Así el mapping es flexible:
  • Podemos crear las clases primero y luego decidir cuales de ellas y como las mapeamos a la BBDD.
  • Podemos crear la BBDD primero y luego generar todas las clases de mapping.

Consultas de datos

Para consultar objetos se usan las query expressions.
P.ej. dada la siguiente clase:

public class Northwind : DataContext
{
public Table<Customer> Customers;
}

donde Customer es una clase con el atributo [Table] aplicado, entonces una vez creado un objeto Norhwind (llamésmole db) entonces para realizar consultas:

// Escojer los customers de NY amb 5 o mes ordres
from c in db.Customers
where c.City == "NY " and c.Orders.Count >= 5
select new {c.CompanyName, c.OrderID};

// Escoger los customers de NY con sus Orders del 1997
from c in db.Customers
where c.City == "NY"
from o in c.Orders
where o.OrderDate.Value.Year = 1997
select new {c.CompanyName, c.OrderID, o.OrderDate};

LINQ asegura que existe un sólo objeto en memoria para una misma PK de una tabla (identity mapping). Es decir, si mediante una query obtenemos un registro con una determinada PK, y luego mediante otra query obtenemos otra vez el mismo registro, el objeto devuelto por LINQ será el mismo.

var cust = db.Customers.Single (c => c.CustomerID == "CONSH");
var query = from c in db.Customers select c;
foreach (var c in query) { Console.WriteLine( c==cust);}


En la primera línea se guarda en la variable cust, el objeto Customer que representa al registro con la PK 'CONSH'.
En la segunda línea se obtiene un IEnumerable de Customers con todos los customers.
En la tercera línea se itera sobre el IEnumerable obtenido y por cada objeto Customer contenido en la lista se imprime si es el mismo que el objeto referenciado por cust.
Este código imprime tantos "false" como registros haya en la tabla de la BBDD, excepto una vez que imprime "true" (correspondiente al Customer 'CONSH').
Es decir, la variable cust y la colección query contienen referencias al mismo objeto Customer, por tanto una modificación realizada desde cualquier sitio será visible al resto (cosa lógica, puesto que es el mismo registro de la BBDD).

La navegación entre las propiedades equivale a las joins clásicas de BBDD:

var query =
from o in db.Orders
where o.OrderDetails.Any (d => d.Product.ProductName == "Tofu")
select new {o.Customer.Company.CompanyName, o.OrderID}

Escoje todas las Orders que tengan alguna OrderDetail que contenga un producto llamado "Tofu". Es decir equivale a una join entre Order, OrderDetail y Product.

En las query expressions se usa la palabra clave join, cuando se quieren unir resultados que no tienen relación de FK en la BBDD (si hay relación de FK en la BBDD entonces se usan las propiedades como en el ejemplo anterior).

from c in db.Customers
join s in db.Suppliers on c.Country equals s.Country
select new
{
CustomerName = c.CompanyName,
SupplierName = s.CompanyName
};

Devuelve el nombre de un Customer y de sus Suppliers que sean del mismo país. Es decir realiza una join entre el pais de un Consumer y de un Supplier. Esa relación no existe en la BBDD en forma de FK.

En LINQ cuando se declara una query:

var query = from c...

La query se prepara pero no se ejecuta hasta que se necesario acceder a los resultados. Eso hace posible usar una query dentro de otra query y que sólo se envie a la BBDD el SQL combinado más óptimo:

var query1 = from c in db.Customers where c.City == "NY" select c;
var query2 = from c in query1 select new { c.CompanyName;}


La primera query selecciona todos aquellos Customers de NY.
La segunda query selecciona el nombre de la empresa de todos los customers devueltos por la primera query.
Cuando se acceden a los resultados devueltos por query2 es cuando esta se ejecuta y lo que se hace es enviar a la BBDD el SQL combinado de las dos queries. Es decir el SQL que se enviaría a la BBDD sería algo como:

SELECT companyName FROM CUSTOMERS WHERE CITY = 'NY'

Modificación de datos

Para insertar datos se llama al método Add de la clase tabla correspondiente y luego el método SubmitChanges.

db.Customers.Add(myNewCustomer);
db.SubmitChanges();

Para modificar datos, se obtiene el objeto que deseamos modificar, modificamos sus propiedades y luego llamamos a SubmitChanges:

// Escogemos un customer
Customer cust = db.Customers.Single ( c => c.CustomerID == "EXISTINGID");
cust.ContactName = "A new Name";
db.SubmitChanges();

Los updates cuando se traducen a SQL sólo modifican las propiedades modificadas (no todas).
Para tratar los conflictos de concurrencia de modificaciones LINQ aplica una aproximación optimistica: Al realizar el UPDATE añade una cláusula WHERE con todos las propiedades tal y como estaban cuando se recuperó el registro. De esta manera si alguien ha modificado el registro antes el UPDATE no tiene efecto. Si tenemos en la BBDD alguna columna tipo rowid se puede indicar a LINQ que haga el WHERE contra esa columna en lugar de contra todas las propiedades.

Acceso a SQL

Bueno... todo eso de LINQ está muy bien, pero a veces nos puede interesar realizar consultas directamente usando SQL. Para ello LINQ proporciona el método ExecuteQuery en la clase DataContext. Es un método genérico, y el parámetro genérico sirve para indicar el tipo devuelto por la query, para de esa manera poder tener resultsets tipados:

var query = db.ExecuteQuery<Contact>("Select CompanyName as Name, Phone from Customers where city = 'NY'");

Bueno.... básicamente eso fue todo lo que dio de si esa charla... bastante información y ejemplos constantes. En mi opinión fue una muy buena charla (divertida, lo que se dice divertida, no... pero interesante sí).

Tuesday, November 28, 2006

ARC201 - Patterns & antipatterns for SOA

Esta era la segunda sesión del track de arquitectura a la asistía en este tech·ed. En la primera me aburrí bastante, pero en esta segunda me divertí un montón. No es que el ponente (Ron Jacobs) contase muchas cosas pero las que contó fueron interesantes... y divertidas.

Básicamente la sesión comentó tres cosillas básicas de la filosofía SoA y luego analizó un conjunto de patrones y antipatrones de SoA.

Lo que dijo primero sobre SoA fue que:
  1. Las aplicaciones fuertemente acopladas no son satanás: tienen su sentido cuando el rendimiento es vital.
  2. Debe preferirse siempre el comportamiento explícito al implícito.
  3. Los servicios son la puerta de entrada a procesos de negocio. Si algo no es un proceso de negocio, quizás no se trate de un servicio.
  4. Las barreras deben ser explícitas (sin llegar a suponer impedimentos).
  5. Los servicios deben ser autónomos. Los servicios comparten sólo su interfaz (y las políticas asociadas).
  6. La compatibilidad entre servicios viene dada por sus políticas asociadas (que define protocolos de transporte, temas de transaccionalidad, reliable messageing, ...).
Luego empezó a enumerar algunos antipatrones clásicos de SoA:
  1. CRUDy interface: Un servicio cuyo interfaz sea únicamente operaciones CRUD (Create, Read, Update, Delete) debe hacernos plantear si realmente estas operaciones son procesos de negocio (recordar el punto 3 anterior) o simples modificaciones de datos. Las interfaces CRUDy tienden a aparecer cuando se diseñan aplicaciones débilmente ligadas a partir de la experiencia del pasado (aplicaciones fuertemente ligadas).
  2. Enumeration: Un servicio cuya interfaz tenga los clásicos métodos Object current() y bool moveNext(). Debemos plantearnos dos preguntas: la primera es quien contiene la colección y los recursos necesarios (puede violar la regla de que los servicios deben ser autónomos). La segunda pregunta es que podemos hacer con un Object? Básicamente nada, sólo convertirlo a la clase real contenida en la colección, y eso implica un conocimiento que va más allá de la interfaz.
  3. Chatty Interface: Interface que contiene métodos del tipo UpdateAddress(), UpdateName() y CommitChanges(). Durante las llamadas a UpdateXXX y hasta que no se llama a CommitChanges, existen datos "incosistentes". Todas las operaciones que requieren más de un mensaje para realizarse son potencialmente peligrosas.
  4. Loosey Goosey: Dio una traducción al español de lo que significaba Loosey Goosey, pero sinceramente no me acuerdo. Se trata de evitar interfaces tan genéricas que no sirvan de nada. Por ejemplo una interfaz con un método XmlDocument Execute(XmlDocument request), es extremadamente flexible, adaptable (y reutilizable) pero es completamente inútil: necesitamos saber el formato del XML de entrada y de salida, que es información que no está en la propia interfaz. Resumiendo: interfaces flexibles y adaptables sí, pero todo tiene un límite.
Luego pasamos a ver un par de par de patrones válidos en arquitecuras SoA: Document processor y Reservation.

Document Processor

Este patrón se basa en las siguientes claves:
  • Operaciones asíncronas
  • Fronteras bien definidas
Decidir que proceso quiere implementarse.
Decomoponer el proceso en actividades realizables mediante un workflow.
Crear el contrato:
  1. Definir los mensajes
  2. Definir las operaciones
  3. Agrupar operaciones relacionadas dentro de servicios.
Como ejemplo de Document Processor puso el proceso de apuntarse a una universidad, pero no una de actual, si no una de hace unos 10 años. Cuando uno se apunta una universidad debe asignarsele aula, horario, profesor, ...
  1. Existen un conjunto de formularios a rellenar (mensajes)
  2. Cada persona implicada en la operación recibe el formulario (mensaje) correspondiente y realiza su tarea (operaciones asíncronas).
Reservation
Sistemas de transacciones distribuídas asumen un grado de confianza que en aplicaciones loosely coupled muchas veces no son deseables (no siempre se quiere dar el control final de una transaccion al transaction manager de otro sistema). Para evitar esto y al mismo tiempo seguir tenir transacciones se establece un estado intermedio llamado reserva. Es nuestra responsabilidad definir bien los estados por los que pasa una reserva hasta que es consolidada y que mensajes son intercambiados en cada caso.
Como ejemplo puso el de las compañías aéreas: Cuando el cliente llama para pedir un vuelo, como no confían en el cliente para cerrar la transacción, permiten hacer una reserva. Hasta que el cliente no pague (mensaje) la reserva no pasa al estado de confirmado.

Finalmente terminó la sesión con un par de consejos básicos: intentar usar tipos portables entre plataformas (p.ej. evitar DataSets que se mapean a "any" en WSDL) y evita el comportamiento implícito (p.ej. no asumir que los datos vienen en un orden determinado si el contrato no lo especifica de forma clara).

Eso es todo lo que dio de si la sesión, muy introductoria pero eso sí: muy divertida.

DEV311 - WCF: Managing WCF Services

Una nueva sesión de WCF a la que asistí... la tercera del tech·ed. Haber asistido a la primera era requisito casi obligatorio para entender algo de esta sesión.

Si las sesiones anteriores habían tratado del desarrollo de servicios bajo WCF, en esta se hablaría del tema del managment de esos servicios, esto es: como configurarlos, monitorizarlos y depurarlos.

Fue una sesión bastante light, que se puede resumir básicamente en los siguientes puntos:
  1. Modelo de configuración de WCF está basado en XML. El modelo XML es muy complejo, pero la herramienta visual WCF Config Editor ayuda mucho en este punto. Con esta herramienta se pueden configurar servicios, pero también activar temas realcionados con el diagnóstico (trazas, logs, perfcounters).
  2. WCF proporciona un proveedor de WMI integrado, por lo tanto cualquier herramienta de monitorización de WMI (Tivoli, MOM, ...) puede monitorizar servicios WCF.
  3. Los Diagnostical behaviours (activar/desactivar logs,...) se pueden modificar sin necesidad de reiniciar el servicio.
  4. WCF incorpora varios contadores de rendimiento (perfcounters) para las métricas más comunes. Existen contadores a nivel de servicio, endpoint y operación.
  5. Un servicio puede definir sus propios contadores de rendimiento. Esto permite crear contadores mixtos que correlen datos de negocio con datos de rendimiento.
  6. WCF incorpora hasta 5 niveles de trace. El trace de mensajes está disponible, sin que sea necesario instalar sniffers ni ninguna herramienta parecida.
  7. El trace de mensajes permite correlar llamadas entre servicios: se añade automáticamente un ActivityID a cada mensaje que es el mismo para llamadas encadenadas (es decir si un cliente envia un mensaje al servicio SA y este como consecuencia envía un mensaje a otro servicio SB, los dos mensajes tendrán el mismo ActivityID)
  8. Existe una herramienta visual para tratar con los logs.
  9. WCF al ser un framework no incorpora herramientas de Governabilidad (Governance), aunque da facilidades para que estas sean construídas (en este punto hizo una demo de un servicio que monitorizaba continuamente un fichero de configuración (no el suyo propio) y si este cambiaba, modificaba su fichero de configuración para que fuese igual al modificado y se reiniciaba. Eso permitiría tener n servicios que compartiesen un fichero (o parte de un fichero) de configuración).
Finalmente terminó con unos consejos, los más destacables para mi fueron:
  1. Usar contratos dúplex para que los servicios puedan informar de cambios en su estado de salud, a las aplicaciones sin que esas deban estar preguntando continuamente.
  2. Vigilar la seguridad de WMI. El proveedor WMI de WCF permite descubrir todos los servicios activos, lo que podría derivar en ataques de floodeo.
  3. Proteger los ficheros de logs generados. Contienen mucha información.

OFF306 - Understanding Workflow in Windows Sharepoint Services (WSS) and Microsoft Office SharePoint Server 2007

Toma cacho título para la sesión, eh?

Esa sesión versaba sobre Workflow Foundation y como MOSS 2007 lo extiende. Fue una sesión bastante interesante, aunque por algunos momentos un poco durilla de seguir.

Primero comentó los aspectos claves de Workflow Foundation (WF):
  1. Es un framework para generar workflows, no un servidor de aplicaciones ni nada parecido.
  2. Se trata básicamente de un motor de ejecución de workflows y de una API expuesta bajo .NET Framework 3.0 para dicho motor.
  3. Los workflows se dividen en actividades (piezas reutilizables entre workflows).
En este punto nos realizó una demo del workflow designer, que se integra en VS2005 cuando se instalan las extensiones para .NET Framework 3.0.
La demo consistió en crear un workflow con una CodeActivity y codificar el evento ExecuteCode y así generar el clásico Hello World.
Luego nos demostró como los Workflows pueden ser definidos usando código o bien en formato XML.

Luego nos comentó como MOSS extiende WF, proporcionando nuevas actividades y como MOSS soporta workflows en items y documentos y como los workflows de MOSS pueden ser iniciados (aunque no obligatoriamente) por acciones de usuario.
Vimos que los workflows de MOSS pueden tener definidos el init form y el association form, que son formularios (aspx) que se muestran cuando se inicializa un workflow y cuando se asocia el workflow a una document library o a un item. Esos dos formularios que forman parte del workflow permiten configurar el workflow con datos propios para cada caso concreto.

Finalmente hizo una demostración de creación, definición y ejecución de un workflow bajo MOSS:
  1. Creación de una document library y asociar en ella documentos de word.
  2. Creó una workflow association entre esta document library y uno de los workflows previamente instalados en el servidor.
  3. En este punto se muestra el association form.
  4. Ir a la document library e iniciar el workflow para un documento en concreto.
  5. En este punto se muestra el init form.
En los clientes Office 2007, tan buen punto se salva un documento en una document library que tenga algún workflow asociado, este workflow pasa a ser disponible (y puede ser iniciado desde los propios clientes de Office).

Finalmente vimos como con una extensión adicional se podían crear desde VS2005 workflows para MOSS (aparecen las actividades propias de los workflows de Sharepoint).

DEV323 - C# 3.0

Bueno... como es habitual el título no era tan escueto, pero vamos, la presentación iba sobre eso: las novedades que Orcas traerá al lenguaje C#.
Hace ya algún tiempo (más o menos un añito) probé una alfa de LINQ y venia con C# 3.0, así que pude probarlo. Mis impresiones de entonces están en mi blog personal, en concreto en este post.

Digamos que la gran novedad de C# 3.0 es LINQ y que el resto de novedades incorporadas al lenguage se han incorporado en mayor o en menor medida para poder dar un buen soporte a lo que es LINQ... pero vayamos por partes y enumeremos las diferentes novedades que se nos fueron presentando.

Local variable type inference
El compilador puede determinar el tipo de una variable en función del tipo del rvalue correspondiente (es decir en función de lo que se encuentre a la derecha del signo igual). Existe una nueva palabra clave "var" para declarar variables.
var foo = new Dictionary<bar,baz>();
En esta línea automáticamente la variable foo queda definido de tipo Dictionary<bar,baz>. Debe notarse que declarar variables con var no hace que C# sea débilmente tipado, el lenguaje continua siendo fuertemente tipado. Es simplemente para no tener que escribir de forma redundante.
Hay otra razón por la que "var" se ha introducido en el lenguaje (se comenta más abajo).

Extension methods
Permiten extender una clase sin necesidad de crear una clase derivada. Interesante cuando no queremos (o no podemos) derivar.
Para ello simplemente declaramos un método estático cuyo primer parámetro se declare con la palabra clave this:

static FooType foo (this BarType bar, Baz baz) { .... }
Este método funciona como un extension method a la clase BarType. Es decir sobre los objetos de la clase BarType se puede invocar el método foo() pasando como parámetro un objeto Baz.
Los extension methods se implementan a nivel de compilador, no hay implicación para el CLR en ellos.
Si se implementa un extension method sobre una interfaz sólo debe implementarse una vez, y queda implementado para todas las clases que implementen la interfaz.

Evidentemente extension methods, es un mecanismo muy potente a la vez que peligroso: mal usado hace que al final uno no tenga ni idea donde está definido un método determinado. Por lo tanto es un recurso que debe usarse en último lugar (mmm... veremos como evoluciona).

Lambda expressions
Jejejee... todos los que odiaban lamda-calculus en la carrera y creían que ya podían olvidarlo para siempre... pues no.
Lo más importante de als lambda expressions es que permiten pasar código como parámetros. Por lo tanto se usan en muchos puntos donde antes usábamos un delegate.

La definición de una lambda expression es:
param_list => código
donde param_list es una lista de parámetros.

Por ejemplo:
c => c.State == "WA";
Define una expresión lambda que recibe un parámetro (c) y cuyo resultado es la evaluación del código (c.State == "WA").

Lo más interesante de las lambda expressions es cuando sustituyen a delegates.
Por ejemplo este código seria C# 2.0 usando delegates:

public delgate bool Predicate<t>(T item);
Predicate<Customer> isFromWA = CustomerFromWA;

private static bool CustomerFromWA (Customer c)
{ return c.State == "WA"; }

Y el código equivalente usando expresiones lambda:

Predicate<Customer> isFromWA = c=> c.State == "WA";

Object initializers
Se pueden crear e iniciar objetos en una sola línea:

Point a = new Point {X=0, Y=1};
equivale a:
Point a=new Point();
a.X=0;
a.Y=1;

Collection initializers
Se pueden inicializar colecciones junto con su declaración:

List foo = new List{100,200,300};
Para que funcione la clase debe tener dos requisitos:
  1. Implementar IEnumerable
  2. Tener un método publico llamado Add()
El método Add() puede tener más de 1 parámetro:

var foo = new Dictionary<int,string> { { 0,"zero"},{1,"one"}};

Automatic properties
Bueno... esa es una pequeña modificación para evitar tener que crear código para crear propiedades get/set que únicamente devuelven/acceden a una variable miembro.

public class Product {
public String Name {get; set;}
}

equivale a:

public class Product {
private string _name;
public String Name { get { return _name;} set { _name = value; } }
}

La variable privada _name y el código de get/set lo crea el compilador para nosotros :)

Query expressions
Query expressions es la sintaxis propia de C# para LINQ.
Las nuevas palabras clave (p.ej. select o join) sólo lo son dentro del contexto de una query expression. El inicio del contexto de una query expression la marca la palabra clave from. Eso significa que el resto de palabras clave de LINQ no se comportan como tal fuera del contexto de una query expression.

var query = from c in customers
where c.State == "WA"
select new {c.Name, c.Phone};

LINQ está implementada como un conjunto de extension methods (p.ej. muchos de ellos sobre IEnumerable). El compilador traduce las query expressions a las llamadas a métodos LINQ equivalentes. La query expression anterior el compilador la traduciria a:

var query = customers.Where(c => c.State == "WA").Select( c=> new {c.Name, c.Phone});

Es aquí donde se pone de manifiesto que la mayoría de añadidos al lenguaje C# 3.0 lo son para poder dar soporte a LINQ (esa línea de "código convertido" usa anonymous types, lambda expressions, object initializers y local variable type inference).

Anonymous Types
Permite declarar objetos de clases anónimas, sin necesidad de declarar la clase.
Se usan mucho en LINQ:

IEnumerable<Contact> plq = from c in customers
where c.State == "WA"
select new Contact { Name = c.Name, Phone = c.Phone};

Esa consulta, tal y como está redactada nos obliga a implementar la clase Contact, que debe tener al menos, dos propiedades (Name y Phone).
Con anonymous types podemos usar el siguiente código:
var plq = from c in customers
where c.State == "WA"
select new {Name = c.Name, Phone = c.Phone};

La parte marcada en cursiva es la creación del objeto de un tipo anónimo (se pone new sin poner el nombre de la clase). Debe notarse que ahí estamos obligados a definir la variable plq usando "var" porque no hay manera de saber el tipo de un objeto anónimo (esa es la razón de peso por la cual "var" se ha introducido en el lenguaje).

Si queremos iterar sobre plq (que es un IEnumerable de un tipo anónimo) también estamos obligados a usar var:

foreach (var item in plq) {...}
La variable item es del tipo anónimo creado por el compilador, por lo que item.Name compila perfectamente.

Expressions Tree (Code as Data)
Expressions Tree es un nuevo modelo de clases y objetos que permite obtener el DOM de una expresión. De esta manera se pueden crear expresiones de forma dinámica.

Imaginemos que tenemos un delegate Func definido como:
public delegate T Func<a0, T> (A0 arg);
es decir representa a una función de un argumento de tipo A0 y que devuelve un valor de tipo T.
Usando lambda expressions podríamos definir el delegate apuntando a una función:
Func<double,double> f = x => x*2 + 1;
(para invocarlo: f(10.2);)

La classe Expression es el punto de entrada a la API de Expressions Tree:
Expression<Func<double, double>> e = x => x*2+1;

La variable e contiene el árbol DOM que usa el compilador para evaluar la expresión. Entre otras cosas lo que podemos hacer es compilar la expresión y obtener el código MSIL correspondiente (y por lo tanto asignarlo a un delegate):
Func<double,double> foo = e.Compile();

Evidentemente al ser un árbol DOM podemos añadir, quitar, mover, modificar nodos, lo que a la práctica siginifica que podemos crear expresiones de forma dinámica, y al final compilarlas y asignarlas a delegates!

Y eso fue todo lo que dio la sesión de si... como podeis ver bastante cosa, no????

DEV214 - Introducing WCF

Esta sesión era la primera de una serie de sesiones sobre WCF que se dieron en el tech·ed. La verdad es que fue una sesión bien explicada e interesante.
Antes que nada, nos comentó los principios de diseño de WCF:
  1. Unificar tecnologías existentes
  2. Aumentar la productividad
  3. Permitir la integración con otras tecnologías de mensajería (de otros fabricantes o de la propia MS).
Luego vino el dibujo general de lo que es WCF: Un cliente y un servicio que intercambian mensajes a través de un endpoint. Si el cliente puede crear un endpoint compatible con alguno de los endpoints expuestos por el servidor, entonces la comunicación es posible. Los servicios pueden estar hospedados en un IIS pero también en una aplicación CLR (p.ej. una aplicación WinForms).

Luego creó paso a paso el "Hello World" de WCF:
  1. Crear la clase servidor que tendrá el hosting del servicio. Clase estándard con el Main().
  2. Crear un interface para definir el contrato (què puede hacer) del servicio.
  3. Implementar el interface en una clase (la clase servicio).
  4. Usar la clase ServiceHost para hospedar el servicio en la clase Servidor.
  5. Activar el servicio (desde la clase servidor) usando ServiceHost.Open().
Al compilar y ejecutar la clase servidor... excepción al canto. La razón: faltaban definir los endpoints de acceso al servicio. Dicha definición puede hacerse por configuración (app.config) o bien por código. Definió el endpoint (en el app.config) y la aplicación se ejecutó correctamente.
Ahora el siguiente paso era crear el cliente. Aquí nos comentó que, dado que los clientes necesitaban crear un endpoint compatible con alguno de los endpoints del servicio para comunicarse, debía existir una manera de que el servicio expusiera todos sus endpoints a sus clientes. La manera en como los servicios WCF exponen sus endpoints a sus posibles clientes es usando WSDL, pero que no lo hacen automáticamente, si no que para ello debe configurarse un behaviour concreto llamado behaviour metadata. Lo configuró en el app.config del servidor (entre la información que introdujo fue en que URL estaría el WSDL del servicio). Entonces ya pudo crear el cliente: añadio una service reference desde Visual Studio, y automáticamente se creó la clase proxy para acceder al servicio usando un endpoint correcto.

Una vez hecha esa demo, entramos un poco más en profundidad en cada uno de los aspectos básicos de WCF, siempre teniendo presente el ABC de WCF: endpoint = Address + Binding + Contract.

Contracts
Los contratos definen que puede hacer un servicio. En WCF hay tres tipos de contratos, dos de ellos se usan constantemente y el tercero es más raro.
  1. Service Contract: Define los métodos que un servicio expone a sus clientes.
  2. Data Contract: Define la composición de los parámetros de los métodos definidos en el service contract. Es en definitiva el nuevo modelo de serialización que lleva WCF.
  3. Message Contract: Es el tipo de contrato que no suele usarse. Permite especificar a nivel de mensaje que datos van en la cabecera y en el cuerpo.
Luego vimos la definición de contratos.
Para Service Contracts: Definir una interface y aplicar el atributo [OperationContract] a cada método que se desea que el servicio exponga. Sólo los métodos que tengan ese atributo serán expuestos por el servicio a sus clientes.
Para Data Contracts: Definir una clase y aplicar el atributo [DataMember] a cada miembro de la clase que deba ser serializado. Sólo los miembros que tengan ese atributo serán serializados (y por lo tanto pasados/recibidos a/desde el servicio cuando se opere con datos de esa clase).

Luego vimos varios puntos interesantes sobre los contratos:
  1. Como mapear llamadas desconocidas a un método en concreto del servicio (p.ej. si un cliente envía un mensaje con un método que no existe se puede mapear esa llamada a un método inexistente a un método en concreto).
  2. Como declarar métodos asíncronos [OperationContract(AsyncPattern=true)]
  3. Como declarar métodos one-way (de los que no se espera respuesta) [OperationContract(IsOneWay=true)]
  4. Como definir contratos duplex: Un contrato duplex es aquel que permite que el servicio invoque una función de callback al cliente, para informar de que una operación ha terminado. Para ello el cliente debe implementar la interfaz de callback.
  5. Como declarar que un método de un servicio puede lanzar una excepción de tipo X. Se declaran en el contrato con [FaultContract(typeof(X))], se lanzan en el servicio con throw new FaultException(...) y se capturan en el cliente con catch (X ex).
Bindings
Si los contratos definen que hace un servicio, los bindings definen como acceder al servicio. Un binding se compone de tres partes:
  1. Un protocolo de transporte (p.ej http o tcp)
  2. Una codificación determinada (p.ej. binario o soap)
  3. Uno o más protocolos de funcionamiento (p.ej. Transacciones, reliable messaging, ...)
Los bindings se pueden configurar en el app.config.

Aquí hizo una demo curiosa: un servicio con dos endpoints. En uno de los endpoints el binding era con transporte http y en el otro era con transporte msmq (el resto era todo igual). Luego tenía dos clientes (eran el mismo programa que en función de un parámetro creaba un endpoint compatible con http o con msmq). Puso en marcha el servidor y los dos clientes y enseñó que todo funcionaba bien. Luego paró el servidor y mandó mensajes desde los dos clientes. El cliente http dio un error, mientras que el cliente msmq no dio ninguno. Luego puso en marcha el servidor de nuevo, y los mensajes enviados anteriormente por el cliente msmq fueron recibidos.

Behaviours
Los Behaviours son elementos locales al cliente o al servidor (no forman parte de los endpoints). Los behaviours permiten controlar aspectos relativos a la infraestructura de WCF, pudiendose controlar entre otros aspectos lo siguiente:
  1. Como el servicio expone su metadata (WSDL)
  2. Gestión de las instancias del servicio (singletons, un servicio por cliente, un servicio por mensaje).
  3. Máximo número de clientes admitidos.
  4. Información de enrutamiento
Aquí nos hizo una demo de un servicio que controlaba el número de mensajes recibidos, y jugando con el behaviour (definido en app.config) de gestión de instancias comprobamos que se trataba de un singlenton, o de un servicio por cliente o de un servicio que era creado y destruido para cada mensaje.

Eso fue todo lo que dio de si esa sesión (que no fue poco)... y era sólo la primera de una serie de tres o cuatro que hubieron en el tech·ed sobre WCF.

DEV351 - Expression and Ajax

Bueno... el título real era muchi más rimbomabante pero ese permite ver por donde fueron los tiros de esa sesión. No fue una sesión muy interesante la verdad (más bien al contrario).

Antes que nada nos comentó la importancia de una buena User Experience. Como ejemplo nos mostró el ipod: triunfa frente a reproductores más avanzados y más baratos porque proporciona una mejor experiencia de uso. Entonces comentó que uno de los principales problemas del desarrollo de aplicaciones web de hoy día es que los diseñadores van por un lado y los desarrolladores por otro. Que generalment el diseñador entrega al desarrollador un conjunto de maquetas y un conjunto de gráficos que se ven genial, y luego el desarrollador hace algo que se termina pareciendo a lo diseñado, pero que muchas veces no es igual. Este proceso redunda en una pérdida de user experience. La solución pasa por integrar a los desarrolladores dentro del proceso de creación de las aplicaciones web y que éstos no entreguen gráficos y cuatro HTML estáticos a los desarrolladores si no que les entreguen páginas aspx, y que los programadores básicamente tengan que añadir el code-behind.
Ahí es donde entraba Expression. Esta herramienta es un editor visual para ASP.NET. Viene a ser como un Dreamweaver pero especializado en ASP.NET y con soporte para algunas capacidades avanzadas como data-binding (de esta manera el diseñador puede ver como queda el diseño cuando muestra datos "reales" y modificarlo de forma acorde a las necesidades).
Entonces vinieron unos tediosos 45 minutos donde el ponente navegó por muchos de los menús y las opciones de Expression, ensalzando sus maravillas. Evidentemente Expression puede abrir un proyecto asp.net de Visual Studio existente o bien crear uno nuevo: desarrolladores y diseñadores pueden trabajar sobre el mismo repositorio de código fuente.
Finalizado este tour de force por las características de Expression le tocó el turno a la Microsoft Ajax Library. Evidentemente las aplicaciones web que usan Ajax tienen mucha mejor User experience que las que no. Lo que hizo fue abrir el proyecto generado con Expression y retocarlo con Visual Studio usando la Ajax Library para añadir funcionalidad. Debe reconocerse que tocó casi nada del diseño de la página generado en Expression. Las funcionalidades que añadió fueron: autocomplete en un text-box a partir de los datos devueltos por un web service y luego nos mostró varios de los controles web que la Microsoft Ajax Library contiene. Esa segunda parte de la demostración estaba demasiado compensada (por lo que el ponente cada dos por tres tenía que copiar-pegar páginas enteras de código sin poder comentar que hacían ni de donde salían).

En resumen: la parte dedicada a Expression no creo que aportase mucho la verdad, y la parte dedicada a la Ajax Library estaba tan condensada que era casi imposible entender nada.

Monday, November 27, 2006

DEV201 - Introduction to Windows FX

Bueno... con la barriga bien llena (es imposible no comer hasta rebentar en el Tech·Ed), me fuí a esta sesión que pintaba bastante interesante, pero que al final no lo fue tanto.

La sesión fue una introducción a las novedades del .NET Framework 3.0 (antes conocido como WinFX), es decir una introducción a WPF, WCF, WF y Cardspace.

Windows Presentation Foundation (WPF)
Fue la primera API que se nos presentó. Nos comentó que los objetivos básicos de WPF eran:
  1. Permitir que las aplicaciones tengan un estilo muy personalizado (poder dotar de estilo de "marca" a las aplicaciones.
  2. Ofrecer un aspecto gráfico innovador aprovechando las capacidades 3D de las actuales tarjetas gráficas.
  3. Permitir integrar a diseñadores dentro del proceso de creación del software (de ahí que esté basada en XAML).
Luego nos enseñó un par de demos de WPF: la primera era una demostración de varios controles WPF (desde los más básicos como botones, hasta los más elaborados como el reproductor de vídeo o gráficos en 3D). La segunda demo era una aplicación desarrollada por el New York Times, para leer las noticias del diario que aprovechaba WPF para dotar a la aplicación de un aspecto idéntico al del periódico en papel.

Windows Communication Foundation- WCF
La nueva API de comunicaciones de Microsoft fue la segunda que nos fue presentada. No comentó mucho sobre WCF, básicamente que viene a sustituir las diversas APIs de comunicaciones que actualmente existen en el mundo Microsoft (ASMX, WSE, .NET Remoting, System.Messaging y Enterpise Services) por un modelo unificado.
Luego nos dio un repaso rapidísimo a los fundamentos de WCF: es una API basada en el concepto de mensajes, que se intercambian los servicios, a través de los endpoints. Un endpoint está formado por lo que se conoce por el ABC de WCF: Address (donde está el servicio - URI de acceso), Binding (cómo acceder a él - protocolo y codificación), Contract (que puede hacer el servicio - métodos disponibles).

Windows Workflow Foundation - WF
Una de las novedades más interesantes del .NET Framework 3.0 és el framework para la creación de Workflows. No enseñó apenas nada de WF, sólo la extensión de Visual Studio para la creación de workflows de forma gráfica, y realizaó un workflow (que de "flow" tenía poco porque eran dos actividades ejecutándose una tras otra). Luego comentó que Sharepoint extendía WF añadiendo nuevas actividades.

Cardspace
Carspace es una API destinada a mejorar la seguridad en el proceso de autenticación y evitar problemas de phising o robo de credenciales. La idea es sustituir la autenticación por login/password por unas cards que las aplicaciones compatibles con Cardspace reconocen como válidas. Esas cards pueden ser emitidas por organizaciones de confianza o por uno mismo (algo parecido a lo que ocurre con los certificados para SSL). La posesión de la card garantiza el acceso a la aplicación en concreto.
El ejemplo que nos enseñó fue el siguiente: una aplicación web compatible con Cardspace (el acceso a Cardspace desde html se puede hacer a través de <object>), con dos botones "login" y "sign-up". Primero se dio de alta en la aplicación. Entonces apareció el asistente de Cardspace de Vista y él creó una card nueva para esa aplicación. De los varios campos que se pueden entrar algunos eran obligatorios y otros no, eso lo define la aplicación que solicita la card: la idea es que sólo se entren los datos realmente necesarios para la aplicación. Una vez creada la card en el sistema, accedió de nuevo a la aplicación y le dio a "login". Entonces, de nuevo apareció el asistente de Cardspace en Vista y le permitió seleccionar la card con la que entrar en la aplicación. Nos mostró que si escogía la que había creado podía entrar, si escogía cualquier otra que tuviese el acceso quedaba denegado.
Finalmente nos comentó que el asistente de Cardspace se ejecuta siempre en una sesión de escritorio nueva (Alt+Tab no sirve de nada) para evitar falsificaciones.
Personalmente me quedaron varias dudas sobre Cardspace, debido a que no conocía para nada esa API y que esa introducción era muy corta. Hubo un par de sesiones sobre Cardspace en el Tech·Ed pero no pude asistir a ninguna. Eso sí, la API parece muy interesante (supongo que la clave será en estandarizar las organizaciones de confianza que emitan las cards y como acceder a ellas desde cualquier ordenador).

KEY001 - Key note

La keynote dio el inicio al Tech·Ed: Developers 2006. Como es habitual en estos casos es la única presentación que no comparte horario con ninguna otra, y sirve de presentación a lo que veremos durante los próximos cuatro días. Se realizó en un escenario espectacular: el auditorium del CCIB.

En la keynote quedó patente que las grandes áreas de este Tech·Ed iban a ser Office 2007, .NET Framework 3.0, el desarrollo para Vista, y el desarrollo de aplicaciones web con tecnología Ajax (usando la Microsoft Ajax Library, antes conocida como Ajax, y Expression la nueva herramienta de MS destinada a diseñadores web).

Nos presentaron una demo, realmente espectacular, que unía esas tres tecnologías en una aplicación para el control de ventas de una empresa de ropa llamada Fabrikam (jejeje... de que me suena ese nombre?). La aplicación estaba compuesta de tres partes fundamentales: un portal web, desarrollado con Ajax, donde los clientes podían navegar por el catálogo y empezar procesos de compra, que eran procesados por workflows en un Sharepoint 2007. Finalmente una aplicación integrada en el task pane de Excel permetía todo tipo de consultas (de forma rápida y fácil), y obtener al instante gráficos y los valores en excel, para poder tratarlos...
... sólo faltó una aplicación cliente de WPF para poder navegar en el catálogo, ya que hubiera sido espectacular, debido a las capacidades gráficas de WPF. Pero no nos la enseñaron en la demo, porque nos mostraron un vídeo de un caso real, que era precisamente eso: una aplicación WPF, para poder navegar por el catálogo on-line de una tienda virtual. Las imágenes que se veían de la aplicación eran muy espectaculares.

Después de esa demo, nos mecionaron las novedades que traerá Orcas, a destacar: soporte completo para WPF y WCF, integración de LINQ, soporte para equipos distribuidos (en la versión equivalente a la actual Team System), VSTO 2007 y soporte para integrar Ribbon en aplicaciones propias.

Finalmente hubo una pequeña demo, muy introductoria, de LINQ, donde con un rápido ejemplo se nos enseñó como realizar consultas sobre objetos de negocio (basta implementar IEnumerable), tablas BBDD y generar XML. El resultado: un RSS con todos los procesos que se están ejecutando en la máquina en este momento.

En resumen, fue una keynote entretenida, sobretodo por lo espectacular de su demo.

Wednesday, November 08, 2006

Tech·Ed 2006 by raona









Hola a todos! :)

En este blog encontrareis mis opiniones y comentarios sobre el Tech·Ed 2006, al cual he asistido en nombre de raona.

Para hacer más amena la espera os invito a repasar experiencias anteriores de raona en distintas conferencias a las que hemos asistido:

  1. IT Forum 2005 by raona
  2. Enterpise Architect Summit 2005 by raona
  3. PASS European Conference 2006 by raona
  4. MEDC 2006 by raona

Y obviamente recomendaros que os paseis por la página web de raona, donde encontrareis los distintos blogs que estamos realizando.

Nos vemos en breve ;-)