dedicada a los profesionales de la plataforma .net ... · hablamos sobre lenguajes (y el inevitable...

60
dedicada a los profesionales de la plataforma .NET Laboratorio NDepend TodotNet@QA Más cosas extrañas: esta vez de ASP .NET Opinión El difícil problema de la estimación www.dotnetmania.com entrevista Ami Vora Product manager de .NET Framework 3.0 en Microsoft dotNetManía Entrando en la tercera dimensión nº 37 mayo 2007 6,50 Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System Gestión de un boletín electrónico con CRM • Data binding con WCF • Serialización práctica.El serializador que lo serialice...o es binario o sabe XML

Upload: lytuyen

Post on 26-Sep-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

dedicada a los profesionales de la plataforma .NET

LaboratorioNDepend

TodotNet@QAMás cosas extrañas: esta vez de ASP.NET

OpiniónEl difícil problema de la estimación

www.

dotne

tman

ia.co

m

entrevistaAmi Vora

Product manager de .NET Framework 3.0 en Microsoft

dotNetManíaEntrando en la

tercera dimensión

nº 37 mayo 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System

Gestión de un boletín electrónico con CRM • Databinding con WCF • Serialización práctica.El serializadorque lo serialice... o es binario o sabe XML

Bienvenido al número 37, de mayo de2007, de dotNetManía.

Durante los días 4 y 5 de junio se cele-brará en Madrid el ReMIX —evento per-teneciente a la gira mundial MIX, quecomienza ahora en mayo en Las Vegas—dirigido a desarrolladores y diseñadores,donde Microsoft pretende aclarar las fron-teras entre ambos mundos —desarrollo ydiseño de aplicaciones—. Aunque no creoque se consiga, el intento nos enriquece-rá a todos, por lo que le recomiendo queno se lo pierda. Pienso que es muy difícil“cortarle la mano” al desarrollador paraimpedir que diseñe, aunque sí veo muysencillo evitar que el diseñador se meta adesarrollar. Como si fuese un título deGuillermo Som, creo que el mensaje deeste MIX podría ser: “El desarrollador queno lo diseñe.. buen desarrollador será”,pero estoy seguro de que usted, como lamayoría, está deseando probar las nuevasherramientas de diseño y cómo se integrancon Visual Studio. Estaremos atentos paraver qué porcentaje de desarrolladores ydiseñadores asisten. Apuesto por unamayoría de desarrolladores deseosos deincluir estas nuevas posibilidades de dise-ño en sus aplicaciones.

Precisamente, el artículo de portadade este mes es el titulado “Entrando en latercera dimensión” de los miembros delgrupo Weboo de la Universidad de LaHabana, autores del libro “Windows Pre-sentation Foundation” que hace el núme-ro 7 de los cuadernos técnicos de dotNet-Manía. Con este artículo nos introducena las capacidades de WPF para lograr efec-tos tridimensionales en nuestras aplicacio-nes. No me dirá que no es atractivo...

Este mes publicamos la entrevista querealizamos a Ami Vora, product managerde .NET Framework 3.0 en MicrosoftCorporation, con la que hablamos acercade lenguajes, de las nuevas API de Vista y

de su adopción por parte de los desarro-lladores y de la influencia de éstas en lasfuturas aplicaciones.

Tenemos la suerte de contar por pri-mera vez con Jesús Villalobos, antiguoredactor de la versión española de la revis-ta Visual Basic Programmer’s Journal.Ya ha llovido, es verdad, pero ¡los viejosrockeros nunca mueren! Su artículo “Databinding con WCF” examina cómo usar eldata binding cuando el origen de datos esun servicio WCF.

En nuestra sección de iniciación, Gui-llermo Som nos habla de seriación binaria yXML (yo no pienso usar el término “seriali-zación”). Su artículo “Serialización práctica...El serializador que lo serialice... o es binarioo sabe XML” ha abierto un debate en estaredaccción sobre el uso del castellano y cier-tas acepciones. A partir de ahora, en esta revis-ta aceptaremos el término “serializar” tantocomo “seriar”, dada la implantación actualdel primero. Por suerte para todos, no ten-go espacio para explicarme, pero quiero quequede constancia de mi oposición al uso deesta palabra innecesariamente inventada. Bas-tante tiene el desarrollador con estar al díaen tecnología como para reflexionar o inves-tigar estos asuntos. El desarrollador usa lostérminos que lee de fuentes aparentementeconfiables. Por esto, editores de libros, revis-tas, sitios Web y, por supuesto, fabricantes desoftware, tenemos una responsabilidad en eluso de nuestro idioma; somos el ejemplo quelos demás seguirán.

Por último, quiero informarle de que apartir de este número daremos otro enfoquea la sección dnm.laboratorio.net, a la que dedi-caremos más recursos para profundizar másen algunas evaluaciones y estar más pendien-tes de las novedades más importantes de laindustria. Octavio Hernández se respon-sabiliza desde ahora de esta labor.

Espero que el contenido de este messea de su agrado.

dotN

etM

anía

<<

3

El desarrollador que no lo diseñe...

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 37 • Mayo 2007Precio: 6,50€

EditorPaco Marín ([email protected])

Redactor jefeMarino Posadas([email protected])

Editor técnicoOctavio Hernández([email protected])

RedacciónDino Esposito, Guillermo 'Guille' Som, JoséManuel Alarcón y Miguel Katrib (GrupoWeboo)

Empresas Colaboradoras

Alhambra-Eidos

Plain Concepts

Raona

Solid Quality Learning

Además colaboran en este númeroDaniel Sabater, Iskander Sierra, JesúsVillalobos, Mario del Valle, Rodrigo Corral yYamil Hernández.

Corresponsal para América LatinaPablo Tilotta

IlustracionesYamil Hernández

Atención al suscriptorPilar Pérez ([email protected])

Edición, suscripciones y publicidad.netalia

c/ Robledal, 13528529 Rivas-Vaciamadrid (Madrid)

www.dotnetmania.com

Tf. (34) 91 666 74 77Fax (34) 91 499 13 64

ImprimeGráficas MARTE

ISSN1698-5451

Depósito LegalM-3.075-2004

dotNetManíadotNetManía

Paco Marín

sumario 37El difícil problema de la estimación 12-13

Realizar estimaciones es uno de los más complejos problemas de los varios que losdesarrolladores de software enfrentamos día a día. Además, es uno en el que históricamentehemos fallado a la hora de resolverlo. Por eso precisamente es ésta la cuestión que he elegidopara mi primera participación en esta columna.

Entrevista a Ami Vora 14-16Entre las personas a las que tuvimos ocasión de entrevistar durante el pasado TechEd 2006 enBarcelona, se encontraba uno de los Program Managers de .NET Framework 3.0, Ami Vora.Hablamos sobre lenguajes (y el inevitable debate VB.NET vs. C#), sobre las nuevas API deWindows Vista, su adopción por parte del colectivo de programadores y la influencia quealgunas de esas API, especialmente WCF y WPF, pueden tener en las aplicaciones futuras.

Gestión de un boletín electrónico con CRM 18-20En este artículo haremos una introducción al desarrollo de extensiones para Dynamics CRM,tomando como excusa la gestión de suscripciones a un boletín electrónico de una Web comercial.

Data binding con WCF 22-30La arquitectura SOA que implementa Windows Communication Foundation busca lamáxima interoperabilidad entre sistemas, pero ello no significa que hayamos de perderprestaciones en el desarrollo de las capas de presentación. En este artículo examinamos cómopuede utilizarse data binding en aplicaciones Windows Forms y ASP.NET cuando el origen dedatos es un servicio WCF.

Entrando en la tercera dimensión 32-41En este artículo se hace una introducción práctica a las nuevas posibilidades que WPF(Windows Presentation Foundation) abre ante los desarrolladores para utilizar recursos 3D enlas aplicaciones.

Serialización práctica. El serializador que lo serialice... o es binario o sabe XML 42-48En algunas situaciones nos veremos en la necesidad de transferir ciertos datos de un lugar aotro, y para poder hacer esa transferencia tendremos que guardar los datos de forma tal, quesea fiable la recuperación. Aquí es donde entra en juego la serialización.

dnm.todotnet.qaMás cosas extrañas: esta vez de ASP.NET 49-51

A los lectores parecen gustarles las cosas extrañas, o quizás es que las cosas extrañas son tan comunes quesorprenden a muchos desarrolladores. Así que este mes volvemos sobre técnicas poco corrientes, pero quetienen un elemento común: la Web.

dnm.laboratorio.netNDepend 52-55

Este mes presentamos NDepend 2.1, una herramienta que permite analizar tanto el códigofuente como el código objeto (ensamblados) que componen una aplicación .NET y generardiversos informes que facilitan una mejor comprensión de la arquitectura y la evolución delcódigo, así como una evaluación objetiva de la calidad del mismo.

dnm.biblioteca.net 57Programación Web con Visual Studio y ASP.NET 2.0.Profesional Visual Studio Team System.

dnm.desvan 58

dotN

etM

anía

<<

6

Microsoft ha dado a conocer suadhesión a la OpenAjax Alliance, laorganización configurada por fabri-cantes líderes del mercado, proyectosde código abierto y empresas quehacen uso de la tecnología Ajax y quese encargan de su correcta adopción.Esta noticia pone de manifiesto elcompromiso de Microsoft de traba-jar conjuntamente con otros fabri-cantes del mercado y promover la sim-plificación e interoperabilidad de lasherramientas Ajax.

Esta información se hizo públi-ca en EclipseCon, el evento para lacomunidad de código abierto Eclip-se, cuyos proyectos están centradosen la creación de una plataforma dedesarrollo ampliable para la cons-trucción del software.

Fundada en febrero de 2006con el apoyo inicial de quincecompañías –incluyendo a BEA,Borland, Dojo Foundation, Eclip-se Foundation, Google, IBM,Mozila Corporation, Novell, Ora-

cle, Red Hat y Yahoo, entre otros–hoy son más de setenta las empre-sas que forman parte de esta ini-ciativa, que nace con el objetivo depromover la adopción de la tec-nología de desarrollo Web, fomen-tando la capacidad de los usuariospara combinar soluciones de dis-tintos proveedores y conducir elfuturo del ecosistema Ajax.

Más información en : http://www.openajax.org y www.msdn.microsoft.com/asp.net.

Microsoft se une a la OpenAjax Alliance

noticiasnnoottiic ci ia as s

n no ot ti ic ci ia as s

n no ot ti ic ci ia as s

n no ot ti ic ci ia as s

Varias empresas importantes,como Akamai Technologies, Bright-cove, Eyeblaster, Limelight Net-works, Netflix y la Liga Nacional deBéisbol de EE.UU. ya han comen-zado a utilizar la tecnología.

Microsoft Silverlight, antesconocido como Windows Presenta-tion Foundation Everywhere(WPF/E) , se integra con las tecno-logías Web ya existentes, al tiempoque ofrece una experiencia de altacalidad a bajo coste a los proveedo-

res de contenido multimedia. Dis-ponible para los usuarios finales através de una instalación rápida eintegral, Silverlight es compatiblecon las plataformas Mac y Windows;así como con una amplia variedadde navegadores incluyendo Inter-net Explorer, Firefox y Safari.

Silverlight utiliza WindowsMedia Video (WMV); además,Microsoft ha implementado elestándar de vídeo VC-1 de laSociedad de Ingenieros de Cáma-ra y Televisión (SMPTE), lo queha permitido su compatibilidadinmediata con los millones dehoras de contenidos ya disponiblesen la red, e incluir el soporte parala experiencia de vídeo interactivaque escala desde la alta definición delas pantallas hasta el nuevo modelode reproducción de contenidos de losdispositivos móviles.

Los clientes de Silverlight tambiéndisfrutarán de la compatibilidad de laplataforma gracias al amplio ecosiste-ma de herramientas y soluciones dis-

ponibles para Windows Media, asícomo de la escalabilidad y fiabilidadque esta tecnología de reproducciónofrece. De cara a los proveedores decontenido, Silverlight también ofre-

cerá soporte para la gestión de dere-chos digitales en torno a la tecnologíade acceso de contenido multimediaMicrosoft PlayReady, que funcionasobre equipos Windows y Mac.

Para más información y descargas,visite http://www.microsoft.com/silver-light/asp/default.aspx.

Microsoft presenta la plataforma online SilverlightDurante la conferencia de la National Association of Broadcasters (NAB2007) que tuvolugar recientemente en Las Vegas, Microsoft presentó Silverlight, un nuevo plug-inmultiplataforma y multibuscador que trasfiere archivos multimedia de próxima generacióny aplicaciones Web interactivas.

Microsoft ha liberado la Beta 1 deOrcas, tanto en forma de imagen ISO deCD como de máquina virtual para Vir-tual PC, en diferentes ediciones: EdiciónProfesional, Team Suite y Team Founda-tion Server, así como varias edicionesExpress más ligeras. Estas betas puedendescargarse desde aquí: http://msdn2.micro-soft.com/en-us/vstudio/aa700831.aspx.

Microsoft Visual Studio “Orcas” sebasa en la visión de Microsoft sobre lasaplicaciones cliente inteligentes, permi-tiendo a los desarrolladores crear rápida-mente aplicaciones conectadas que ofre-cen experiencias de usuario más ricas y demás alta calidad. Con Visual Studio“Orcas”, las organizaciones encontraránmás fácil que nunca antes capturar y ana-lizar información de una manera que lespermita tomar decisiones de negocio efec-tivas. Visual Studio “Orcas” permitirá auna organización de cualquier tamaño cre-ar rápidamente aplicaciones más seguras,administrables y fiables que aprovechentodas las ventajas de Windows Vista y2007 Office System.

Visual Studio “Orcas” ofrece avancesclave para los desarrolladores en tres áre-as principales:

• Aumentar la productividad deldesarrollador.

• Administrar el ciclo de vida de lasaplicaciones.

• Emplear las tecnologías másrecientes.

Las mejoras en estas tres áreas se refle-jan fundamentalmente a través de gruposde tecnologías diferentes:

Desarrollo para Windows Vista y .NETFramework 3.0

A los desarrolladores le será más fácilaprovechar las tecnologías presentes enla nueva plataforma y ofrecer a sus clien-tes aplicaciones más atractivas, incor-porando con un mínimo de esfuerzo lascaracterísticas de Windows Presenta-

tion Foundation tanto en las aplicacio-nes Windows Forms existentes comoen las nuevas aplicaciones.

Crear aplicaciones para MicrosoftOffice

Visual Studio Tools for Office(VSTO) estará integrado completamen-te en la Edición Profesional de Visual Stu-dio “Orcas”. VSTO permite a los desa-rrolladores personalizar varias aplicacio-nes de Office, como Outlook y Power-Point, para mejorar la productividad delusuario final y mejorar de manera signi-ficativa el despliegue.

Gestionar los datos más fácilmenteCon la introducción de las consultas

integradas en los lenguajes (Language Inte-grated Query - LINQ) y varias otras mejo-ras en el acceso a datos, los desarrollado-res podrán tratar los datos con un enfo-que programático más consistente, reali-zar el acceso a datos a través de nuevassuperficies de diseño y utilizar clases pre-construidas para el patrón de diseño “oca-sionalmente conectado”.

Permitir nuevas experiencias WebRespaldados por la infraestructura

segura, fiable y extensible de IIS, losdesarrolladores podrán crear fácilmen-te aplicaciones Web más interactivas,con una mejor respuesta y una ejecu-ción más eficiente del lado del cliente,utilizando la integración directa y elmodelo de programación familiar deASP.NET AJAX, así como otras exten-siones y mejoras.

Mejorar la administración del ciclo devida de las aplicaciones (ALM)

ALM es de una gran ayuda no solopara gestionar todo el ciclo de vida delproceso de desarrollo de software, sinotambién para mejorar la importanteinteracción con los usuarios finales ylos administradores de una aplicacióncorporativa.

dotN

etM

anía

<<

7

dnm.directo.noticias<<

Estudiantes de la Universidad deGranada,ganadores de la ediciónespañola de la Imagine Cup deMicrosoftRepresentarán a España en la final internacionalque tendrá lugar en agosto en Corea.

Microsoft ha dado a conocer el nombredel proyecto ganador en la final española deImagine Cup, el concurso internacional paraestudiantes universitarios que premia las pro-puestas tecnológicas más creativas y origina-les. En ésta, su cuarta edición en España, hanparticipado más de 1.440 alumnos pertene-cientes a 52 universidades, lo que ha supues-to un incremento del 67% en la participaciónestudiantil con respecto al pasado año.

El proyecto ganador ha sido Sc@ut, rea-lizado por José Luis González Sánchez,Cristobal Espinosa Morente y Óscar PinoMorillas, estudiantes de la Escuela TécnicaSuperior de Ingeniería Informática de la Uni-versidad de Granada.

Los problemas de comunicación en laspersonas autistas son el punto de partida deSc@ut, un software comunicativo aumentati-vo diseñado para favorecer el uso de sistemasde interacción sonoro-pictográficos entre quie-nes padecen este trastorno. Bajo una sencillae intuitiva interfaz de usuario, el paciente podráacceder a un amplio catálogo de opciones que,de forma visual, sonora y táctil, permiten sucomunicación. Además, y gracias al uso demúltiples dispositivos como PC, Pocket PC ysmartphones, el usuario podrá beneficiarse delas múltiples posibilidades de interacción quebrinda Internet.

FinalistasEl proyecto Volver a empezar, de los

estudiantes de la Escuela Politécnica Superiorde la Universidad de Castilla-La Mancha, haobtenido el segundo puesto. Cada uno de losintegrantes del equipo ha recibido por ellocomo premio una videoconsola Xbox 360.

Alumnos de las universidades de Alicantey Sevilla, autores del proyecto Open Lear-ning Environment, se han alzado con el ter-cer puesto en la competición. Como premio,cada uno de los integrantes de este grupo harecibido un dispositivo smartphone.

Más información en www.imaginecup.com.

Imagine Cup 2007Liberada Beta 1 de “Orcas”

El pasado día 29 de marzo se celebró en las instala-ciones de Kinépolis en Madrid el Microsoft Deve-loper Day 2007, principal evento anual que organi-za Microsoft para la comunidad española de desarro-lladores de software, y una de las citas de referenciade la compañía con los profesionales informáticos queutilizan sus tecnologías. El evento tuvo una excelen-te acogida, y más de setecientas personas abarrotaronliteralmente las instalaciones de Kinépolis duranteuna jornada completa, que estuvo dedicada a promo-ver las mejores prácticas en el desarrollo de aplica-ciones y servicios de todo tipo (Windows, Web y paradispositivos móviles), así como a dar a conocer lasnovedades que se presentarán oficialmente en los pró-ximos meses.

A lo largo de la jornada, los profesionales deMicrosoft presentaron, compartiendo escenariocon algunos de sus principales socios tecnológicos,las siguientes ponencias:

• Para comenzar, José Murillo (Microsoft) y Ale-jandro Mezcua (ByteAByte) presentaron la ponen-cia “Mejores prácticas en aplicaciones servidor”, dedi-cada al desarrollo de la parte del servidor.

• Durante la sesión “Metodologías con Visual Stu-dio Team System”, presentada por César de la Torre

(Microsoft) yJesús Villalo-bos (Certia), semostraron lasfacilidades queofrece VisualStudio TeamSystem para laaplicación demetodologías dedesarrollo enequipos comoCMMI, MSF-Agile y SCRUM.

• A continuación, María Isabel Gómez (Microsoft)y José Manuel Alarcón (Krasis) presentaron ideasde gran utilidad en relación con el desarrollo Web(incluyendo el uso de AJAX) en la sesión “Mejoresprácticas en el desarrollo Web ASP.NET 2.0”.

• De la mano de David Carmona (Microsoft) yPablo Peláez (Plain Concepts) transcurrió “Mejores

prácticas en la experiencia de usuario”, una ponenciamuy amena e instructiva sobre la creación de buenasinterfaces de usuario, algo que cobra mayor relevan-cia ahora que ha aparecido Windows Vista.

• La sesión “Mejores prácticas de desarrollo enSQL Server”, conducida por Fernando Guerre-ro y Miguel Egea (Solid Quality Learning) yMario Roa (Danysoft) aportó recomendacionesrelacionadas con el desarrollo para SQL Server. Adestacar, la presentación de las principales posibi-lidades que aporta el nuevo Visual Studio TeamEdition para Profesionales de Bases de Datos.

• Chema Alonso (Informática64) y SimónRoses (Microsoft) condujeron la sesión "Consejospara el desarrollo de código seguro”, dedicada atemas relacionados con la seguridad.

• David Salgado (Microsoft) y OctavioHernández (Plain Concepts) presentaron la ponen-cia “Orcas, la nueva generación de Visual Studio”,en la que comentaron, de manera muy resumida,algunas de las principales novedades que llegaránen los próximos meses de la mano de la nueva ver-sión de Visual Studio, incluyendo LINQ.

• Por último, Ethel García (Microsoft) yMiguel Jiménez (Ilitia) presentaron, como preám-bulo de la entrega de premios del concurso de gad-gets (ver pág. 9), la sesión “Desarrollo de gadgetspara Windows Vista”, una guía para el desarrollode estas pequeñas aplicaciones que se han conver-tido en uno de los atractivos del nuevo sistema ope-rativo de Microsoft.

Microsoft Developer Day 2007

eventoseve

ntos <<

Octavio Hernández

Contactar con desarrolladores de Portugal y ver el ambiente que se res-piraba por allí, en el evento más importante que tiene lugar en nues-tro país vecino, y que tuvo lugar del 20 al 22 de marzo en el Palacio deCongresos de Lisboa, era el objetivo principal de nuestra visita a Por-tugal, en la que estuvimos magníficamente acompañados por CristinaGonzález Herrero (MVP Lead para España y Portugal) y su homó-loga lusa, Cristina Carvalho.

Hubo un gran número de ponencias a lo largo de los 3 días, y la flor ynata del desarrollo en nuestro país vecino se dio cita allí, junto a ponentesinternacionales de la talla de Jeff Prosise, Chad Hower, Ingo Rammer,Beat Schwegler, Fred Baumhardt, Lee Elliot, Jon Harris o MauroSant’Anna, quien –siendo brasileño- se permitía departir con ambos ban-dos en sus lenguas nativas. Hubo un elevado nivel técnico en las sesionesy notable interés por los temas relacionados con la Web (sobre todo AJAX)y SharePoint, en el lado de los servidores, y muchas de las novedades apor-tadas por Windows Vista y las API de desarrollo, en el lado del cliente.Otro de los temas a destacar fue VSTS que va ganando adeptos en sus dis-tintas ediciones.

Además, tuvimos ocasión de contactar con muchos de los MVP por-tugueses, como Luis Silva, Paulo Morgado, Antonio Almeida, RuiSilva, Joao Livio, Alexandre Janeiro, Alberto Silva, Jorge Moura,y con representantes del mundo empresarial, como Pedro HonorioSilva y David Rodrígues, de Easytronic. En todo momento nos sen-timos como en casa, y desde aquí aprovecho la oportunidad para agra-decer a todos ellos su hospitalidad.

dotN

etM

anía

<<

9

dnm.directo.eventos<<

Tech-Days 2007 de Lisboa

Como colofón de la intensa jornadadel Developer Day, se entregaron lospremios a los trabajos ganadores delprimer concurso español de desarro-llo de gadgets para Windows Vista,que había sido presentado en febreropor Microsoft y el grupo de usuarios.NET de Madrid (Mad.NUG).

En total se premió a 13 desarrolla-dores, que presentaron gadgets rela-cionados con temas tan diferentes comolas cotizaciones en bolsa, la monitori-zación de tareas o los resultados fut-bolísticos. El premio principal (unainvitación para asistir al próximo MIXde Las Vegas, además de otros goodies)recayó sobre José María Villagra,autor del gadget Recuerda el Pan, unaatractiva aplicación que ayuda a losusuarios a recordar, a través del teléfo-no móvil, qué productos de los indica-dos en la lista de la compra se hanadquirido y cuáles no.

Primer concurso dedesarrollo de gadgets

Marino Posadas

Durante el Microsoft Manage-ment Summit 2007, Bob Muglia,vicepresidente senior de la divisiónde Servidores y Herramientas deMicrosoft, anunció ante unaaudiencia de 3.000 profesionalesde TI, responsables de la toma dedecisiones y partners, la disponibi-lidad de Microsoft System Cen-ter Operations Manager 2007,

que ha sido diseñado para ayudar a ampliar e integrar eventosde TI y monitorizar el rendimiento para mejorar los niveles deservicio a través de un entorno de TI.

Microsoft presentó la versión RTM de Systems Manage-ment Server service pack 3 con AssetMetrix; la disponibilidad dela segunda beta pública de Data Protection Manager v2 y laprimera beta pública de Microsoft System Center ServiceManager, anteriormente conocida como Service Desk; la dis-ponibilidad de la segunda beta pública de Microsoft SystemCenter Virtual Machine Manager; y el reciente lanzamientode la segunda beta pública de System Center ConfigurationManager 2007 este pasado mes de febrero.

También se anunciaron los planes para desarrollar y lanzar uncomponente adicional que soportará el procesador 2007 Intel vProcon tecnología Intel AMT después de que la versión RTM de Sys-tem Center Configuration Manager 2007 esté disponible.

Microsoft Management Summit 2007

eventos

dotN

etM

anía

<<

10

dnm.directo.eventos<<

Gira Web Day: ¿Eres desarrolladorWeb? Desde el mes de abril y hasta juniorecorrerá las ciudades de Sevilla, Bar-celona, Bilbao, Valencia, Vigo, Albace-te y Pamplona.

CodeCamp 2-3 de junio en El Rocío

La próxima cita de este aplaudido tallerpara emprendedores y apasionados de latecnología.

Re-MIX4-5 de junio en el Círculo de Bellas Artes deMadrid –Alcalá, 42–.

El primer evento en España para dar aconocer las tendencias del mercado quedemandan los diseñadores y desarrolla-dores Web. Como objetivo tendrá acla-rar las fronteras del entorno Web actualen el que se difuminan y confunden lasfunciones de varios de sus profesionalescomo son los diseñadores, desarrollado-res, publicistas, editores… Habrá un totalde veinte sesiones sobre las últimas ten-dencias del sector; además, contaremoscon la presencia de destacados ponentesnacionales e internacionales, que pre-sentarán lo último sobre Silverlight, lacreación de páginas Web interactivasAJAX, Windows Presentation Founda-tion, Media Center y Live Messenger,entre otros.

Más información:http://www.microsoft.com/spanish/msdn

Microsoft

eventos

Buenas prácticas para mejorar el rendimiento de SQLServer 20053 de mayo de 19:00 a 21:00 en Universidad de Deusto, EdificioESIDE, Aula de videoconferencia. Organiza Artalde.net.

Windows Communication Foundation4 de mayo de 19:00 a 20:30 en C/ Bonaire, 9A Entresuelo B (Pal-ma de Mallorca). Organiza Baleares on .NET.

Tests de intrusión8 de mayo de 18:00 a 20:30 en Universidad Pública de Navarra, Cam-pus de Arrosadia, Edificio El Sario. Organiza Navarra dotNET.

Introducción a BI con SQL Server 2005 Analysis Services10 de mayo de 18:00 a 20:00 en la Facultad de Telecomunica-ciones de Barcelona -sala de Teleensenyament- . Organiza BCN-Dev.

Primera reunión de CatDotNet10 de mayo a las 20:00 en el Centre de Serveis a les Empresesde l’Ajuntament d’Igualada. Organiza CatDotNet.

El nuevo desarrollo Web: Expression,AJAX,WSS 3.017 de mayo de de 16:00 a 20:00 en Hospital Juan Ramón Jime-nez, Huelva. Organiza OnobaNET.

Introducción a LINQ.Técnicas y aplicación práctica24 de mayo de 18:00 a 20:00 en Barcelona Activa del Parc Tec-nológic BCN Nord. Organiza BCNDev.

Potenciando la productividad con la EntLib 3.021 de junio de 18:00 a 20:00 en Barcelona Activa del Parc Tec-nológic BCN Nord. Organiza BCNDev.

Más información en:http://www.microsoft.com/spanish/msdn/spain/eventos/comunidad.mspx.

Una Web perfecta con Sharepoint 6 de junio en Madrid y 17 de Mayo en Barcelona

BizTalk, resolviendo la Torre de Babel de los SI23 de mayo en Madrid y 24 de Mayo en Barcelona

De la empresa a los proyectos: bajo una visión común30 de mayo en Madrid y 31 de Mayo en Barcelona

Más información en:http://www.raona.com/Formació/Seminaris/tabid/66.

Comunidad .NET

Raona

para comentar que no pretendo dar des-de estas páginas soluciones concretas, más que nada porque, enmi opinión, en el desarrollo de software no existen recetas uni-versales, sino mover a la gente a pensar de otra manera, de unamanera ágil, en los problemas que nos encontramos día a díacuando tratamos de desarrollar software.

Voy a hablar, en la presente entrega, sobre qué armas hemosutilizado tradicionalmente los desarrolladores a la hora de rea-lizar estimaciones; de cómo éste es un problema complejo, quizásirresoluble, y de cómo las metodologías ágiles asumen esta com-plejidad y conviven con ella. Pero antes que nada me gustaríadejar claro, una vez más, que en este tema, quizás más que enningún otro, la única verdad absoluta es que ha quedado total-mente demostrado que no existen balas de plata.

Hagamos un repaso de cómo se ha enfrentado el problemade la estimación hasta ahora y qué ventajas y problemas, a muygrandes rasgos, tiene cada aproximación.

Primero se utilizó el juicio del experto. Es un enfoque sim-ple y directo. Basta con buscar a un desarrollador que haya desa-rrollado un sistema lo más similar posible al que queremos esti-mar y que nos diga cuál es su estimación. Las pegas de esta apro-ximación son: primero, que es difícil encontrar a alguien que hayaconstruido un sistema lo suficientemente similar al nuestro comopara obtener una buena estimación; se suelen desarrollar sistemasque no existen –si lo que necesita nuestro cliente ya existe, es mejorque simplemente lo compre–. Segundo, cada proyecto es un mun-do. Cada proyecto evoluciona de un modo diferente, se desarro-lla en un entorno diferente, con un equipo diferente, en una tec-nología diferente. Luego está claro que el juicio del experto no esdemasiado fiable. Además, se trata de la voz de una única perso-na, lo que siempre introduce riesgos.

El siguiente paso fue abordar el problema desde un enfoquemás ingeniero, más matemático. De aquí surgieron toda una seriede técnicas basadas en utilizar las matemáticas para la estima-

El difícil problema de la estimación

<< Aprovecho también

RRooddrriiggoo CCoorrrraall es MVPy MCPD y uno de los

fundadores de PlainConcepts, donde cola-bora como arquitectode software.Ademástrabaja en Sisteplant

como líder técnico enun proyecto desarrolla-do sobre .NET 3.0 utili-

zando Scrum comometodología de desa-

rrollo.También adminis-tra Geeks.ms. Su blog es

http://geeks.ms/blog/rcorral.

Realizar estimaciones esuno de los más complejosproblemas de los varios quelos desarrolladores desoftware enfrentamos día adía.Además, es uno en elque históricamente hemosfallado a la hora deresolverlo. Por esoprecisamente es ésta lacuestión que he elegidopara mi primeraparticipación en estacolumna. Es la estimaciónun problema complejo, dedifícil solución, pero unproblema que preocupa, ymucho, a todos losimplicados en el desarrollode software. Sin duda, silográsemos obtenerestimaciones fiables,muchos de nuestrosproblemas comodesarrolladoresdesaparecerían, pero ¿esposible realmente lograrestimaciones fiables?

opinión

Rodrigo Corral

ción, como COCOMO, y surgieron bastantes herra-mientas que implementaban este modelo. El proble-ma es que descubrimos que alimentar de datos talesherramientas era demasiado costoso para obtener unosresultados que no eran mucho más ajustados que el quese obtenía usando el juicio del experto.

La siguiente aproximación fueron los puntos defunción. La idea es simple: utilizando datos históricos,podemos evaluar lo que en nuestra empresa cuesta hacerun formulario o un informe, basándonos en lo que infor-mes o formularios similares costaron anteriormente.Luego, a la hora de estimar un desarrollo, simplemen-te tendremos que multiplicar ese valor por el númerode informes o formularios que tenemos. Pero resultóque aunque el método es simple y sin dudas funciona,es muy difícil recopilar una cantidad significativa de datosfiables que soporten subsiguientes estimaciones. Reco-pilar estos datos es algo que exige tiempo, y en ese tiem-po se producen cambios (tecnológicos, humanos u orga-nizativos, por citar algunos) que invalidan los datos ante-riormente recogidos. Es evidente que antes de la apari-ción de las herramientas RAD era mucho más comple-jo hacer un formulario o un informe, por poner un ejem-plo fácilmente entendible.

Que estimar sea un problema difícil no quiere decirque no sea un problema importante. Los desarrollado-res tenemos una continua relación con las estimaciones:damos estimaciones, recibimos estimaciones y sufrimosestimaciones que gente equivocada, comerciales, geren-tes, departamentos de marketing, etc. sin suficiente cono-cimiento del problema, hace por nosotros comprome-tiéndonos. Muchos problemas y riesgos habituales queaparecen en la gestión de los proyectos tienen que vercon una estimación deficiente. Es un problema que mere-ce mucha de nuestra atención.

Pero no podemos obviar la relación que nuestraindustria ha tenido con las estimaciones, la cruda rea-lidad que todos vivimos: nunca se respetan y nunca sonsuficientemente ajustadas, da igual la técnica que use-mos. Por lo tanto, es muy importante a la hora de esti-mar no consumir demasiado tiempo. Al fin y al cabo,la fecha o el precio de proyecto probablemente ya sehayan fijado por motivos ajenos al desarrollo de soft-ware, mucho antes de que el equipo de desarrollo hayapodido siquiera construir su estimación. Incluso, enmuchos casos, antes de que exista un equipo de desa-rrollo. Además, las estimaciones se basan en los requi-sitos y los requisitos cambian constantemente, o por lomenos desde el planteamiento de las metodologías ági-les así lo asumimos.

Otro fenómeno claro que tendemos a olvidar es quelas estimaciones son muchísimo más fiables cuanto másinformación tenemos sobre las cuestiones que estamosestimando. En proyectos de desarrollo de software, gene-ralmente esto es equivalente a decir que solo podemos

tener estimaciones fiables sobre las partes del desarro-llo que vamos a abordar en un futuro cercano. Con estoy con el principio de economía en mente (estimar tieneun coste alto, para el que buscamos una rentabilidad),las metodologías ágiles proponen solo estimar el futurocercano y no poner demasiado esfuerzo en esa estima-ción. La idea subyacente es que realizar una estimaciónaporta mucho, pero que refinar mucho una estimacióno utilizar métodos muy formales, generalmente costo-sos en cuanto a tiempo dedicado, no aporta tanto y sobretodo, no es económico desde el punto de vista de la rela-ción entre esfuerzo y resultados. Resumiendo, estimarsí, pero lo justo y solo en referencia al futuro cercano.

La siguiente pregunta es evidente: si estimar es ine-vitable y los métodos formales tradicionales exigen unesfuerzo que no tiene suficiente recompensa, ¿qué nosqueda? Una aproximación a la estimación que está ganan-do partidarios día a día es Wideband Delphi, un pro-ceso de estimación muy ligero y que obtiene unos resul-tados muy similares a procesos de estimación más pesa-dos o complejos. El proceso es simple y no exige muchapreparación o formación previa.

• Se reúne a unas cuantas personas (de dos a cin-co). Idealmente, se contará con personas quehayan trabajado en aplicaciones similares y per-sonas que no; es interesante contar con diferen-tes perspectivas.

• Cada persona contará con una descripción gene-ral de la cuestión a estimar y quien mejor laconozca expondrá de viva voz sus conocimientossobre la misma.

• Cada persona presente en la reunión de estima-ción realizará y anotará su estimación sin cola-borar con los demás. No se mostrará aún estaestimación al resto de participantes.

• Un ayudante revela los cálculos de cada partici-pante de manera anónima, y seguidamente, tie-ne lugar un debate sobre las suposiciones en quese basan los cálculos. Quien lo desee puede reve-lar cuál fue su estimación.

• El paso 3 se repite hasta que los cálculos con-verjan. Lo que se pretende es que cada personaaprenda de los demás participantes, actualice susestimaciones y proporcione una nueva.

Existen varias variaciones sobre está técnica, porejemplo hacer públicas las estimaciones de manerasimultánea y que, para agilizar, solo los propietarios deestimaciones extremas, la más pesimista y la más opti-mista, debatan el por qué de sus estimaciones. Desdehace algún tiempo utilizo este método de estimaciónen un proyecto gestionado con SCRUM para estimary planificar cada uno de los sprints, y la verdad es quetras el necesario proceso inicial de ajuste, puedo decirque está funcionando excelentemente.

dotN

etM

anía

<<

13

dnm.opinión<<

Marino Posadas

Marino Posadases director de tec-nologías de desa-

rrollo para Españay Portugal de SSoolliidd

QQuuaalliittyy LLeeaarrnniinngg.Puedes leer su blog

en hhttttpp::////wwwwww..eellaavveeffeenniixx..nneett.

entrevista

entrevista a Ami VoraEntre las personas a las que tuvimos ocasión deentrevistar durante el pasado TechEd 2006 enBarcelona, se encontraba uno de los ProgramManagers de .NET Framework 3.0,Ami Vora.Hablamos sobre lenguajes (y el inevitabledebate VB.NET vs. C#), sobre las nuevas API deWindows Vista, su adopción por parte delcolectivo de programadores y la influencia quealgunas de esas API, especialmente WCF y WPF,pueden tener en las aplicaciones futuras.

Como es habitual, ¿podemos comen-zar por unos comentarios de auto-presentación por tu parte?

Por supuesto. Soy program mana-ger en el equipo de desarrollo de .NETFramework 3.0 en Redmond (Was-hington), y una de las labores principa-les que realizo consiste en garantizarque la retroalimentación que obtene-mos de nuestros clientes es considera-da e implementada en las nuevas ver-siones del producto. También suponeestar en contacto permanente con elequipo para garantizar que resolvemoslos problemas críticos, en primer lugar,

y que ninguna de las mejoras clave, oconsiderada como fundamental, se pasapor alto. También me preocupo de laintegración de todo ello dentro deVisual Studio.

¿Crees que empieza a existir loque podíamos llamar una conver-gencia de necesidades, esto es, losusuarios empiezan a pedir con másfrecuencia un paquete funcional mássimilar para cada tecnología?

Totalmente cierto. Nosotros, en estemomento, estamos muy centrados enconseguir, sobre todo, objetivos de

conectividad. La idea es que no importadónde te encuentres, la tecnología te per-mita estar conectado a otras personas, atus datos, tu empresa, tus servidores, tupropio equipo de sobremesa, etc. Es laconectividad en cualquier parte, y es unademanda creciente. En todo el mundo.

Siempre que hablamos de len-guajes se recuerda la polémica sobrecuál es mejor, y considerando que tuvienes de un background de C++, mepones la pregunta en bandeja… ¿Cuáles mejor o preferible, C++ o C#?

Mi respuesta en este momento, esque nuestro interés es producir un con-junto de herramientas lo mejor posiblepara ayudar al programador. Y el reto delprogramador es encontrar la mejorherramienta para cada tarea. Pero si estáshaciendo cosas de bajo nivel –como porejemplo trabajando con el kernel–, posi-

blemente el lenguaje a utilizar sea C++,como se ha hecho en una gran parte deWindows Vista, por ejemplo. Pero siestás construyendo una interfaz de usua-rio o necesitas interoperabilidad entrelenguajes, C# es más adecuado. Eso es loque pienso.

¿Y respecto a la construcción delsistema mismo? ¿Es Vista un híbri-do entre las API clásicas y el nuevoFramework?

Supongo que podría decirse así, si.En muchas partes se ha seguido utili-zando la API de Windows, pero hay

muchas otras con código administrado.Es un producto enorme en extensión yhan colaborado miles de personas en suconstrucción. Lo cierto es que uno delos objetivos es que esas API sobre lasque se construye el sistema sean cada vezmenos necesarias para el desarrollador,aunque las tenga ahí y pueda usarlas, porsupuesto. Es la jerarquía de clases la quedebe aportar la gran mayoría de la fun-cionalidad, con lo cual se obtiene,además, un nivel de abstracción muyadecuado en el desarrollo. Pero es inne-gable que Vista utiliza un elevado núme-ro de API, por supuesto. De cualquierforma, es la primera vez que un S.O. uti-liza una cantidad tan grande de códigoadministrado, lo que –por otro lado– leaporta características únicas.

Para no olvidarnos del otro granprotagonista en el tema de lenguajes,

se ha dicho mucho últimamente queVB.NET estaba paulatinamente sien-do abandonado a favor de C#, espe-cialmente porque el paso inicial quemuchos necesitaban para abordardesarrollos con jerarquías de clasesera el conocimiento de la OOP, y –aldejar de ser eso un problema– laimplementación de C# se adaptabamejor. ¿Eres también de esa opinión?

Realmente es un tema de conoci-miento previo. Nuestros datos tambiénindican una mayor aceptación paulatinade C# como lenguaje, pero no de una for-

ma significativa, de manera que nos hagaplantearnos ningún cambio estructural.Creo que ambas son posibilidades quetiene el programador. En cierta forma,por ejemplo, en las aplicaciones Web esopuede significar una inversión si las apli-caciones son migraciones, y el equipo dedesarrollo no puede reconvertir todo elcódigo de ASP/VB a ASP.NET/C#, deforma que puede resultar más fácil en lacurva de aprendizaje reconvertir ese códi-go a ASP.NET/VB.NET, debido a lasimilitud entre ambos lenguajes, inde-pendientemente de consideraciones acer-ca de la programación orientada a obje-tos. Como decía antes, lo bueno es quese tengan las herramientas adecuadas, yen este caso, Visual Studio 2005 ofreceinfinitas posibilidades para trabajar coneditores de código en todos los lenguajesnecesarios. do

tNet

Man

ía<<

15

dnm.directo.entrevista<<

pie

dotN

etM

anía

<<

16

dnm.directo.entrevista<<

Y, desde luego, hablando de VisualStudio como herramienta, se han teni-do en cuenta todas esas necesidades paraque el programador siempre se vea asis-tido en ese tipo de tareas. Tanto por laherramienta en sí, como por el sistemade ayudas.

Ahora que sale a colación la cur-va de aprendizaje, una de las cues-tiones que plantea la aparición deVista es precisamente eso. Se hancambiado un montón de cosas en elsistema, tenemos nuevas API, tene-mos WPF, WCF, WF… ¿Piensas queel cliente medio adoptará de inme-diato esos cambios?

Creo que al final será una cuestiónde necesidad lo que guiará a las empre-sas en las migraciones, como viene suce-diendo habitualmente. Uno de los pro-blemas comunes es el tiempo (la faltade tiempo), y la gente comenzará ahacer migraciones a medida que lasnecesite, y lo más adecuado –para noquedarse atrás– es ir incorporando loque ofrecen las nuevas tecnologías. Peroserá un proceso gradual.

Antes has comentado algo acer-ca de la conectividad y los servicios.Cada vez se habla más de las aplica-ciones como un tipo especial de ser-vicio, e incluso un gurú muy cono-cido que está por aquí definía el otrodía una aplicación Windows como“un servicio con interfaz de usua-rio”. WCF promete muchas cosas, ysobre todo, promete integración desistemas de comunicaciones en unaAPI común. Dinos algo sobre WCF.

Estoy fundamentalmente de acuer-do con esa afirmación. Creo que WCFes un API revolucionaria en muchossentidos. Y está pensada para facilitarla vida a los programadores, permi-tiéndoles mantener su foco en la lógi-ca de la aplicación y no en las carac-terísticas especiales que se pueden nece-sitar como consecuencia de que su apli-cación tenga que comunicarse con lasdemás. Los programadores podrán aña-dir valor a sus aplicaciones haciendoque estén conectadas en todo momen-to, de una forma sencilla, por una par-te, y muy poderosa en sus posibilida-

des, sin tener que aprender distintas tec-nologías en función del tipo de conec-tividad que se necesite en cada caso. Ytodo esto sin importar el protocolo decomunicación, el escenario en que ten-ga lugar esa comunicación o los meca-nismos seleccionados para la transfe-rencia. Sin duda, WCF es uno de lospilares fundamentales de las nuevas APIde Vista y de .NET Framework.

¿Dirías que lo mejor de estas 3nuevas API que presenta Vista des-de la perspectiva del programadores que su uso es uniforme y homogé-neo? ¿O sea, que se pueda trabajarindistintamente con WPF, WCF yWF siguiendo en muchos aspectosun conjunto común de patrones?

Absolutamente. Eso es parte inhe-rente a la propia jerarquía de clases, acómo se ha pensado esa jerarquía parafacilitar la vida del desarrollador, comote decía antes. El conjunto de controlesdisponibles en la barra de herramientases uno de los ejemplos típicos de estoque te comento. Es contextual, depen-de de lo que estés haciendo te ofreceaquellas cosas que son posibles en esecontexto. Eso facilita la vida. Y sirve, almismo tiempo, de recordatorio y por lotanto, de herramienta de aprendizaje,para suavizar la curva de aprendizaje dela que hablabas anteriormente.

¿Prevéis una desaceleración en laadopción de las tecnologías relacio-nadas con Internet? ¿O va a conti-nuar en su crecimiento exponencial,como está sucediendo hasta ahora?

Es difícil de decir, pero, de momen-to, no hay indicios para pensar en unadesaceleración. Lo que antes comentá-bamos sobre las tecnologías relaciona-das con WCF es un reflejo de esta situa-ción. Las API de WCF están construi-das no solo para soportar lo existenteen la actualidad, sino para permitir lapersonalización por parte del usuario,de forma que resulte sencillo incorpo-rar nuevas formas de comunicación. Sila evolución de Internet continúa, comoparece ser, las API seguirán estando pre-paradas para ofrecer los mecanismosnecesarios para la incorporación decualquier novedad.

Parece que nos hemos centradomucho en la funcionalidad y no tan-to en la presentación, ahora quetodo el mundo dice que es tanimportante. ¿Qué tienes que deciral respecto?

No cabe ninguna duda de que lapresentación es importante, pero –másque nada– en el sentido de que nospermita programar con facilidad algu-nos aspectos que antes resultabanindeseablemente complejos, como eltratamiento de los elementos multi-media. Con WPF todas esas cosasresultan triviales, y es un alivio que losprogramadores no tengan que pensár-selo dos veces a la hora de incorporarnuevos elementos multimedia, porejemplo, vídeo en sus aplicaciones.Además, una aplicación con un diseñoagradable e intuitivo es mucho másfácil de usar y tiene una curva deaprendizaje mucho más suave. Y tam-poco hay que olvidar la importanciade WPF/E para añadir valor a las apli-caciones en contextos multiplatafor-ma desde los navegadores.

Y, para concluir, ¿es ésta tu pri-mera visita en España?

No, estuve hace un par de años enMadrid, que es una ciudad que me gus-ta mucho, y además estudié algo de cas-tellano en la universidad, así que no meresulta del todo desconocido el entor-no. Me gusta mucho este país.

Pues muchas gracias por tusopiniones en nombre de nuestroslectores.

Nos imaginaremos una compañía que quiere utili-zar su CRM para almacenar información sobre laspersonas que visitan su Web comercial y quierenrecibir un envío periódico de la publicación electró-nica. ¿Por qué mantener una base de datos aparte,si CRM ya incluye gran parte de esta funcionalidad?,podrían preguntarse en el hipotético departamentode desarrollo. Pues porque Microsoft DynamicsCRM proporciona acceso a todas sus funcionalida-des a través de un SDK muy versátil basado en ser-vicios Web. Lo de versátil es porque –en principio–los servicios Web pueden ser llamados desde unespectro muy amplio de clientes; aunque en esteejemplo el cliente será también una aplicación .NET,no estamos atados a esta tecnología (por más quenos guste). Un cliente escrito cualquiera de los len-guajes que soportan servicios Web –digamos PHPo Java– también podría acceder al SDK de CRM conun mínimo esfuerzo.

Creación de la aplicación WebCrearemos nuestra aplicación como un nuevo pro-yecto Web desde Visual Studio 2005. En la capturade pantalla que se muestra en la figura 1 puede vercómo hemos cambiado los nombres por defecto deaplicación y formulario inicial a DotNetManiaWeb yaltaboletin.aspx, respectivamente. Aunque hemoselegido desarrollar sobre C#, no hace falta decir quepodríamos utilizar cualquier lenguaje .NET, porejemplo Visual Basic.

Diseño del formulario de entrada de datosSe trata de un formulario típico de entrada de datos.Agregamos una cabecera, tres campos de texto consus correspondientes etiquetas y un botón para enviarla información al servidor. Por último, añadimos unaetiqueta vacía para mostrar mensajes adicionales alusuario.

Gestión de un boletín electrónico

con CRM

CRM

DDaanniieell SSaabbaatteerr es consultor CRM,

MCAD, MBS Certi-fied Professional enCRM.Actualmente

trabaja para CCRRMM ii//oo.net (wwwwww..ccrrmmiioo..nneett).

Puecde contactarcon él en ddssaabbaa--

tteerr@@ccrrmmiioo..nneett.

En este artículo haremos una introducción al desarrollo de extensionespara Dynamics CRM, tomando como excusa la gestión de suscripcionesa un boletín electrónico de una Web comercial.

Daniel Sabater

Figura 1. Creación de la aplicación

Adición de la referencia WebEn el explorador de soluciones, seleccionamos el pro-yecto y de su menú de contexto elegimos la opción“Agregar referencia Web”. Aquí tendremos que espe-cificar la URL donde se encuentra el SDK de CRMbasado en servicios Web. Ésta tendrá la forma:

http://<maquina>:<puerto>/MSCRMServices/2006/crmservice.asmx

Debemos darle un nombre significativo a la refe-rencia Web recién creada. Una opción típica es CrmSdk;os recomiendo que no dejéis el valor por defecto, quesuele ser el de la máquina en la que se aloja el servi-cio Web. Una vez añadida la referencia, podréis obser-var cómo Visual Studio genera una clave en el fiche-

ro web.config que incluye la URL del servicio Webcuyo proxy acabamos de generar. Esto es de gran uti-lidad, pues nos permitirá cambiar el servidor CRM alque apunta nuestra aplicación sin tener que volver acompilarla. Pensad en un escenario de pruebas/pro-ducción, por ejemplo.

<add key=”CrmSdk.crmservice” value=”http://servi-dorcrm:5555/MSCRMServices/2006/crmservice.asmx” />

Para utilizar los métodos del SDK de CRM desdenuestro código, incluiremos como primera línea denuestro fichero de código altaboletin.aspx.cs la sen-tencia using CrmSdk; –donde digo CrmSdk, me refiero alnombre de la referencia Web que hayáis especificado–.

El código del botón “Enviar”El código del botón es la parte que más me gusta deeste artículo. Me gusta por lo simple e intuitivo queresulta. Tenemos a nuestra disposición la clase Crm-Service que cuenta con un método Create que recibeun parámetro de tipo lead. El objeto lead tiene tan-tas propiedades como campos tiene la entidad deCRM. Más sencillo, imposible:

Falta por aclarar la segunda línea, eso sí. Cual-quier cliente de un servicio Web tiene que especifi-car sus credenciales antes de realizar una petición. Eneste caso, con DefaultCredentials estamos pidiéndo-le que utilice las credenciales estándar de Windows.Estas credenciales, en el caso de una aplicación deescritorio, corresponderían al usuario que ha hechologin en la máquina. En una aplicación Web, equi-valdrían a la identidad del grupo (pool) de la aplica-ción. Hablaremos más sobre este punto en la seccióndedicada a la configuración de la seguridad. Tambiénexiste la opción de especificarlas “a piñón fijo” en elcódigo, aunque esto sólo es recomendable para la fasede pruebas, ya que implica escribir en claro una con-traseña en el código:

crm.Credentials = new NetworkCredential(“usuario”, “password”, “dominio”);

dotN

etM

anía

<<

19

dnm.dynamics.crm<<

Figura 2. El formulario de entrada de datos

Figura 3.Adición de la referencia Web

CrmService crm = new CrmService();crm.Credentials = CredentialCache.DefaultCredentials;

lead clientePotencial = new lead();clientePotencial.firstname = tbNombre.Text;clientePotencial.lastname = tbApellidos.Text;clientePotencial.emailaddress1 = tbCorreoElectronico.Text;clientePotencial.subject = “Boletín electrónico”;

crm.Create(clientePotencial);

dotN

etM

anía

<<

20

dnm.dynamics.crm<<

Una programación responsable implica compro-bar el resultado de las acciones de nuestro código, pre-feriblemente a través de excepciones. Cualquier excep-ción que tenga que ver con CRM será notificada conun objeto SoapException, cuya propiedad Detail nosaporta más información sobre el error en formatoXML. El siguiente cuadro muestra el aspecto quetendría un código básico de detección de errores:

La figura 4 presenta una imagen del resultado ennuestro navegador Web de la creación de un registroen el que no se ha dado ningún error.

Comprobación del resultado en CRMEn la figura 5 podemos observar cómo el visitante dela Web ha quedado registrado en CRM como un nue-vo cliente potencial. Además, el campo Tema ha sidorellenado por nuestra aplicación con el valor “Boletínelectrónico” para que más adelante podamos haceracciones sobre estos registros. Por ejemplo, el lanza-miento del boletín electrónico propiamente dicho,que podría implementarse en CRM como una plan-tilla de correo electrónico.

Configuración de la seguridadSólo falta un detalle: hacer compatible la seguridadde ambas aplicaciones Web. La Web comercial (orien-

tada a ofrecer un escaparate en Internet) y nuestroCRM (orientado a uso interno) requieren modos deautenticación diferentes. Mientras que la primera hade ser de acceso anónimo para permitir su utilizacióngeneral, la última tiene fuertes limitaciones de segu-ridad relacionadas con la identidad del usuario que lasejecuta, y se basa en una autenticación integrada conWindows.

Para estar completamente seguros de que nuestraaplicación Web no podrá ser utilizada como un pun-to débil para ataques externos, debemos reducir almínimo el nivel de permisos que tiene sobre CRM ysobre el sistema en general. Aunque por su longitudel tema excede el ámbito de este artículo, sí podemosapuntar cuáles serían los pasos a seguir:

1. En CRM, crear un rol específico para los accesosdesde Web, con los permisos mínimos necesarios(en este ejemplo, crear clientes potenciales)

2. En CRM, crear un nuevo usuario y asignarle elrol de acceso Web creado en el punto anterior.

3. En el administrador de IIS, crear un nuevo gru-po de aplicaciones y asignarle el usuario crea-do en el punto anterior.

4. En el administrador de IIS, asociar a la aplica-ción Web comercial el grupo creado en el pun-to anterior.

ConclusionesEn este artículo hemos visto una primera aproxima-ción a la programación basada en el SDK de CRMutilizando como plataforma cliente una aplicaciónWeb. Sólo es un primer paso, claro: habría que imple-mentar muchas más funcionalidades, como son ges-tión de las bajas y automatización del proceso de envío,por ejemplo. De todas formas, espero que se apreciela facilidad con la que el desarrollo en .NET sobreCRM puede ayudar a automatizar tareas como éstaen poco tiempo.

try{CrmService crm = new CrmService();....lbMensaje.ForeColor = Color.Blue;lbMensaje.Text = “Sus datos han sido guardados”;

}catch (SoapException ex){lbMensaje.ForeColor = Color.Red;lbMensaje.Text = ex.Detail.OuterXml;

}

Figura 4. Registro exitoso

Figura 5. El cliente registrado en CRM

Visual Studio 2005 ha proporcionado un granempujón a la técnica del enlace a datos (data bin-ding), otrora tan denostada. Con muy poco esfuer-zo, es posible conectar una aplicación WindowsForms o una página ASP.NET a un componenteque exponga un DataSet tipado y enlazar los con-troles de la aplicación a los DataTable contenidosen dicho DataSet para mostrar o actualizar los datosque nos envía el componente. Incluso si el origende datos es un servicio Web, la interfaz de VisualStudio nos proporciona una interpretación delWSDL en clave .NET, y de esa manera dispone-mos en la aplicación de una réplica de la estruc-tura del DataSet de origen que nos facilita el enla-ce a los controles.

Sin embargo, en aplicaciones que utilizanWCF el paso de objetos DataSet no es recomen-dable. En primer lugar, un DataSet es una estruc-tura no sujeta a un contrato, y recordemos que enWindows Communication Foundation lo quepublicamos es un contrato de datos, y no unaestructura ya definida como la de DataSet. Ensegundo lugar, las aplicaciones no .NET no sabennada acerca de los DataSet, y mucho menos si estántipados, por lo que su uso vulnera en cierto modola norma de interoperabilidad a la que un serviciodebe aspirar.

¿Significa eso que perdemos funcionalidad enla capa de presentación? ¿Deberemos volver aescribir un código pesado y sujeto a errores paratransportar los datos desde las estructuras defini-das por el contrato hasta los controles que han devisualizar y manejar esos datos? ¿Estamos dandoun paso atrás si utilizamos una arquitectura basa-da en WCF?

Nada de eso, afortunadamente. El modelo deenlace a datos de VS.NET es tan poderoso quenos permitirá enlazar cómodamente los controlesde la capa de presentación a las estructuras de datospublicadas por los servicios WCF, aún cuando esasestructuras no tengan nada que ver con un Data-Set. Obviamente, nada nos impediría crear unDataSet tipado en la aplicación local y traspasarlos datos de la estructura devuelta por el servicioa dicho DataSet; pero esa solución es poco menosque chapucera. En ese caso tendríamos que repli-car en local la estructura del contrato (¡duplicarcódigo, qué horror!) y pasar (también mediantecódigo) los datos a nuestro DataSet local.

Pero no será necesario hacer eso. A lo largodel artículo examinaremos cómo aparecen en elcliente (ya sea Windows Forms o ASP.NET) losdatos publicados por el servicio WCF y compro-baremos que el data binding es tan factible y cómo-

Data binding con WCF

plataforma.net

JJeessúúss VViillllaalloobbooss es MSCD y MCPD y consul-tor y responsable de desa-

rrollo de CCeerrttiiaa(http://www.certia.net). Lle-va trabajando con las dife-

rentes versiones de VB yVisual Studio .NET desde1994 y ha sido redactor

jefe de la versión españolade la revista Visual BasicProgrammer’s Journal.

La arquitectura SOA que implementa Windows Communication Foun-dation busca la máxima interoperabilidad entre sistemas,pero ello nosignifica que hayamos de perder prestaciones en el desarrollo de lascapas de presentación.En este artículo examinamos cómo puede uti-lizarse data binding en aplicaciones Windows Forms y ASP.NET cuan-do el origen de datos es un servicio WCF.

Jesús Villalobos

do como si estuviéramos referenciando directamen-te un DataSet. A beneficio de inventario, diremos quetodo el código del presente artículo ha sido realizadocon Visual Studio 2005, utilizando las extensiones parael Framework 3.0 que ya están disponibles (en inglésa la fecha de redacción de este artículo) enhttp://msdn.microsoft.com/windowsvista/downlo-

ads/products.

El servicio y sus contratosLa creación del servicio no será un problema. Colo-caremos el servicio en una librería de clases que serála que en definitiva accederá a la base de datos. Nadanos impide utilizar internamente un DataSet y variosTableAdapter bien configurados para acceder al ori-gen de datos, así que eso será lo primero que hare-mos. El código que mostramos en el artículo utilizaun DataSet tipado que accede localmente a la tablaCustomers de la bien conocida base de datos North-wind de SQL Server. Hemos utilizado el asistente paracrear el DataSet tipado, y en el TableAdapter corres-pondiente hemos colocado dos métodos que recupe-ran la misma estructura: un método que recupera unconjunto de clientes utilizando un WHERE con un LIKEsobre la columna CustomerID y un método que recu-pera un único cliente utilizando el CustomerID direc-tamente. También hemos creado métodos que reali-zan actualizaciones directas contra la base de datos.

A continuación definiremos los contratos de datosque publicará el servicio. Dispondremos de dos contra-tos de datos, uno para los datos propiamente dichos yotro que utilizaremos para las excepciones. Como lasexcepciones corrientes no se propagan por WCF, es unabuena idea definir un contrato de datos específico parapoder lanzar excepciones al cliente del servicio. El lista-do 1 muestra ambos contratos de datos. El contrato dedatos principal tiene los mismos campos que la tabla Cus-tomers que utiliza el DataSet, pero con los nombres tra-ducidos. Hemos colocado también el parámetro Orderen el atributo DataMember de las propiedades para esta-blecer en qué orden queremos que se serien los miem-bros de la estructura; aunque luego ese orden no lo vere-mos respetado desde el cliente, mala suerte.

El listado 2 muestra el contrato del servicio. Hemosdefinido una operación por cada método de actualiza-ción y lectura, aunque quizás no siempre haya de ser así.En este contrato de servicios destacaremos algunas cosas.En primer lugar, hemos añadido el atributo FaultCon-tract a cada operación para poder disparar la excepcióndefinida por nuestro servicio. En segundo lugar, los méto-dos de actualización utilizan como argumento de entra-da el contrato de datos definido con anterioridad, enlugar de un argumento por cada campo.

dotN

etM

anía

<<

23

dnm.plataforma.net<<

<System.Runtime.Serialization.DataContract()> _Public Class ClienteDotNetMania

Private _IDCliente As StringPrivate _NombreCompañia As StringPrivate _NombreContacto As String

‘[…]

<System.Runtime.Serialization.DataMember(Order:=1)> _Public Property IDCliente() As String

GetReturn _IDCliente

End GetSet(ByVal value As String)

_IDCliente = valueEnd Set

End Property

<System.Runtime.Serialization.DataMember(Order:=2)> _Public Property NombreCompañia() As String

GetReturn _NombreCompañia

End GetSet(ByVal value As String)

_NombreCompañia = valueEnd Set

End Property

<System.Runtime.Serialization.DataMember(Order:=3)> _Public Property NombreContacto() As String

GetReturn _NombreContacto

End GetSet(ByVal value As String)

_NombreContacto = valueEnd Set

End Property‘[…]End Class

<System.Runtime.Serialization.DataContract()> _Public Class FaultWCF

Private _Mensaje as String

<System.Runtime.Serialization.DataMember()> _Public Property Mensaje() As String

GetReturn _Mensaje

End GetSet(ByVal value As String)

_Mensaje = valueEnd Set

End Property

Public Sub New(ByVal Mensaje As String)_Mensaje =mensaje

End Sub

End class

Listado 1

dotN

etM

anía

<<

24

dnm.plataforma.net<<

Para recuperar un conjunto deregistros hemos creado una operaciónllamada ObtenerClientes (en plural) quedevuelve una matriz de objetos Clien-teDotNetMania. Esta matriz será la queluego VS interprete desde la capa clien-te para ofrecernos una interfaz más ade-cuada para el data binding. El métodoObtenerCliente, en singular, recuperauna única estructura ClienteDotNetMa-nia, lo cual no sólo nos será útil para lasactualizaciones, sino que también nosservirá para enlazar posteriormente unObjectDataSource de ASP.NET.

La implementación del servicio basa-do en este contrato se muestra en el lis-tado 3. Como puede observarse, hemosde pasar los datos del DataTable queobtiene el TableAdapter a la estructuraClienteDotNetMania correspondiente.Hemos incluido también el tratamien-to de excepciones, que se realiza median-te la creación de un objeto FaultExcep-tion de tipo FaultWCF. Para los métodosde actualización, las operaciones no sonmás que un simple mapeo a los métodosdel TableAdapter, utilizando los valoresde la estructura ClienteDotNetManiacomo argumentos.

Hemos excluido del servicio el obje-to ExtensionData que por defecto WCFincluye en el encauzamiento de estructu-ras. El objeto ExtensionData permite uti-lizar versionado de contratos de datos, deforma que WCF automáticamente inclu-ya en ese objeto cualquier dato adicionalque el cliente envíe y no esté incluido enel contrato. No hay duda que esta carac-terística resulta muy útil, pero en este casodeseamos que el contrato de datos sea fijo,así que excluiremos esta información adi-cional mediante un comportamiento delservicio, definido en el atributo Service-Behavior del mismo.

Por último, hay que mencionar queel traspaso de los valores desde las filasdel DataTable a la estructura ClienteDot-NetMania exige, en este caso, el trata-miento de los nulos, cosa siempre pesa-da e incómoda. Podríamos haberlo solu-cionado utilizando tipos genéricos anu-lables, pero en este caso hemos optadopor enviar cadenas vacías al cliente cuan-do el valor subyacente sea un nulo.

<System.ServiceModel.ServiceContract()> _Public Interface IServicioDotNetMania

<System.ServiceModel.OperationContract()> _<System.ServiceModel.FaultContract(GetType(ServicioWCFDotNetMania.FaultWCF))>_Function ObtenerClientes(ByVal Nombre As String) As ClienteDotNetMania()

<System.ServiceModel.OperationContract> _<System.ServiceModel.FaultContract(GetType(FaultWCF))> _Function ObtenerCliente(ByVal ID As String) As ClienteDotNetMania

<System.ServiceModel.OperationContract()> _<System.ServiceModel.FaultContract(GetType(FaultWCF))> _Sub InsertarCliente(ByVal Cliente As ClienteDotNetMania)

<System.ServiceModel.OperationContract()> _<System.ServiceModel.FaultContract(GetType(FaultWCF))> _Sub ActualizarCliente(ByVal Cliente As ClienteDotNetMania)

<System.ServiceModel.OperationContract()> _<System.ServiceModel.FaultContract(GetType(FaultWCF))> _Sub BorrarCliente(ByVal Cliente As ClienteDotNetMania)

End Interface

Listado 2

<System.ServiceModel.ServiceBehavior(IgnoreExtensionDataObject:=True)> _Public Class ServicioDotNetManiaImplements IServicioDotNetManiaPrivate ds as new DSNorthwind Private ta As New DSNorthwindTableAdapters.CustomersTableAdapterPublic Function ObtenerCliente(ByVal ID As String) As _

ClienteDotNetMania Implements _IServicioDotNetMania.ObtenerCliente

ds.Customers.Merge(ta.GetDataPorCustomerID(ID))If Not ds.Customers.Rows.Count = 0 Then

dim dr as DSNorthwind.CustomersRow=_ctype(ds.Customers.Rows(0),DSNorthwind.CustomersRow)

return CargarCliente(dr)else

throw new System.ServiceModel.FaultException(Of FaultWCF)(new _FaultWCF(“El cliente “ & ID & “ no existe”),_

”El cliente “ & ID & “ no existe”)End If

End Function

Public Function ObtenerClientes(ByVal Nombre As String) As _ClienteDotNetMania() Implements _

IServicioDotNetMania.ObtenerClientesds.Customers.Merge(ta.GetDataLIKECustomerID(Nombre))If Not ds.Customers.Rows.Count = 0 Then

dim clientes() as ClienteDotNetManiafor each dr as DSNorthwind.CustomersRow in ds.Customers

if clientes is nothing thenredim clientes(0)

elseredim preserve clientes(clientes.GetLength(0))

End Ifclientes(clientes.getupperbound(0))=CargarCliente(dr)

Next

dotN

etM

anía

<<

25

dnm.plataforma.net<<

return clienteselse

throw new System.ServiceModel.FaultException(Of FaultWCF)(new _FaultWCF(“No hay clientes con ese nombre”),”No hay clientes con ese nombre”)

End IfEnd Function

Private function CargarCliente(dr as DSNorthwind.CustomersRow ) as ClienteDotNetManiadim c as New ClienteDotNetMania with dr

c.IDCliente=.CustomerIDc.NombreCompañia=.CompanyNameif .IsCityNull then

c.Ciudad=””else

c.Ciudad=.CityEnd Ifif .IsPostalCodeNull then

c.CodigoPostal=””else

c.CodigoPostal=.PostalCodeEnd Ifif .IsAddressNull then

c.Direccion=””else

c.Direccion=.AddressEnd If

[…]end withreturn c

End Function

Public Sub ActualizarCliente(ByVal Cliente As ClienteDotNetMania) _Implements IServicioDotNetMania.ActualizarCliente

try_ta.Update(cliente.NombreCompañia,cliente.NombreContacto,cliente.TituloContacto,_

cliente.Direccion,cliente.Ciudad,cliente.Region,cliente.CodigoPostal,cliente.Pais,_cliente.Telf,cliente.FAX,cliente.IDCliente)

Catch ex As Exceptionthrow new System.ServiceModel.FaultException(Of FaultWCF)(new FaultWCF(“Error al actualizar: “ &_

ex.Message ),”Error al actualizar: “ & ex.Message)End Try

End Sub

Public Sub BorrarCliente(ByVal Cliente As ClienteDotNetMania) Implements IServicioDotNetMania.BorrarClientetry

ta.Delete(Cliente.IDCliente)Catch ex As Exception

throw new System.ServiceModel.FaultException(Of FaultWCF)(new FaultWCF(“Error al borrar: “ &_ex.Message ),”Error al borrar: “ & ex.Message)

End TryEnd Sub

Public Sub InsertarCliente(ByVal Cliente As ClienteDotNetMania) Implements IServicioDotNetMania.InsertarClientetry

ta.Insert(cliente.IDCliente,cliente.NombreCompañia,cliente.NombreContacto,cliente.TituloContacto,_cliente.Direccion,cliente.Ciudad,cliente.Region,cliente.CodigoPostal,cliente.Pais,_cliente.Telf,cliente.FAX)

Catch ex As Exceptionthrow new System.ServiceModel.FaultException(Of FaultWCF)(new FaultWCF(“Error al insertar: “ & _

ex.Message ),”Error al insertar: “ & ex.Message)End Try

End Sub

End Class

Listado 3

dotN

etM

anía

<<

26

dnm.plataforma.net<<

Solo nos queda poner en marcha elservicio. En nuestro ejemplo hemosalojado el servicio en una aplicación deconsola dentro de la misma solución.Creamos dicha aplicación, añadimosuna referencia a la DLL que constitu-

ye el servicio, y configuramos elapp.config de la aplicación de consolamediante la herramienta de configura-ción de servicios que incorpora el.NET Framework 3.0. Para no com-plicar el ejemplo con aspectos de segu-

ridad, hemos optado por utilizar unprotocolo HTTP básico y hemos situa-do dos extremos, uno para el servicioy otro para la información de metada-tos. El fichero de configuración semuestra en el listado 4 en lo referenteal servicio. Por último, escribiremos laspocas líneas de código necesarias paraponer en marcha el servicio dentro dela aplicación de consola. El códigocompleto del módulo podemos verloen el listado 5. ¡Y ya está! Podemosponer la aplicación en marcha, esperara que en la consola aparezca el mensa-je de que el servicio está abierto y nave-gar con el explorador a http://local-host:8081/ServiciosDotNetMania: en lapantalla aparecerá el mensaje que nosindica que el servicio está en marcha ylisto para recibir llamadas.

El cliente Windows Forms

Configurar un cliente que recupere lainformación de metadatos del servi-cio puede hacerse mediante el pro-grama svcutil que incorpora el Fra-mework, pero como ya somos algoviejos para estar trasteando en la líneade comandos vamos a ir con un pocode picardía para que Visual Studio nosresuelva la papeleta. El problema esque si añadimos a la solución un clien-te Windows Forms no podremos aña-dir una referencia al servicio, ya queéste se aloja en la aplicación de con-sola que está dentro de la propia solu-ción. Otro caso sería si hubiéramosalojado el servicio en IIS, ya que deesa forma podríamos haber hechoreferencia a la dirección del mismo yel propio IIS lo tendría activado. Alestar el servicio alojado en una apli-cación de consola, ésta ha de estar eje-cutándose para que el cliente puedaleer sus metadatos.

En primer lugar, añadiremos anuestro cliente un fichero de configu-ración, necesario para crear el clientedel servicio. Luego hay dos formas deañadir a nuestro cliente una referenciaal servicio. Una de ellas es crear elcliente en otra solución, poner en mar-cha el servicio y luego añadir en el pro-

<system.serviceModel><behaviors><serviceBehaviors><behavior name=”ServiceMetadata”>

<serviceMetadata httpGetEnabled=”true” httpsGetEnabled=”false” /><serviceDebug includeExceptionDetailInFaults=”true” />

</behavior></serviceBehaviors></behaviors><services><service behaviorConfiguration=”ServiceMetadata”

name=”ServicioWCFDotNetMania.ServicioDotNetMania”><endpoint address=”” binding=”basicHttpBinding” bindingConfiguration=””

contract=”ServicioWCFDotNetMania.IServicioDotNetMania” /><endpoint address=”mex” binding=”basicHttpBinding”

contract=”IMetadataExchange” /><host>

<baseAddresses><add baseAddress=”http://localhost:8081/ServiciosDotNetMania”/>

</baseAddresses></host></service></services></system.serviceModel>

Listado 4

Module Module1Private HostServicio as ServiceModel.ServiceHost

Sub Main()HostServicio = New ServiceModel.ServiceHost(_

GetType(ServicioWCFDotNetMania.ServicioDotNetMania))HostServicio.Open()console.ForegroundColor=ConsoleColor.Yellowconsole.WriteLine(“Servicio abierto”)console.ReadLine PararServicio

End Sub

Friend Sub PararServicio()If HostServicio.State<>system.ServiceModel.CommunicationState.Closed Then

HostServicio.Close()End If

End SubEnd Module

Listado 5

dotN

etM

anía

<<

27

dnm.plataforma.net<<

yecto cliente la referencia al servicio de forma nor-mal. Haciendo clic con el botón derecho sobre elproyecto cliente aparece la opción “Add ServiceReference…”, que abrirá un cuadro de diálogo en elque podremos escribir la dirección en la que nues-tro servicio está esperando llamadas. Como hemosincluido un extremo de metadatos, Visual Studiorecuperará el WSDL que genera el servicio y nosañadirá las referencias al mismo.

Otra opción, más picaresca, es utilizar el propioapp.config del servicio. En este caso podemos aña-dir tranquilamente el cliente en la misma soluciónque la aplicación de consola que aloja el servicio, yaque no será necesario que el servicio se esté ejecu-tando. Si hacemos clic con el botón de la derechasobre el fichero de configuración de la aplicacióncliente veremos la opción “Edit WCF configura-tion…”, que permite editar la sección de serviciosdel app.config. Si seleccionamos el nodo “Client”veremos una opción que nos permite añadir un nue-vo cliente, y al pulsarla una pantalla nos permitirácrear una configuración cliente a partir de un fiche-ro de configuración del servicio. La figura 1 mues-tra esta pantalla. Una vez creada la referencia, podre-mos poner en marcha el servicio, y una vez en mar-cha éste crear la referencia al mismo en la aplicacióncliente, lo cual generará la clase proxy que utilizare-mos en el programa cliente.

A partir de aquí, ya es coser y cantar. Añadimosun formulario si no lo tenemos aún y mostramos laventana de “Orígenes de Datos en Visual Studio” (pue-de abrirse desde el menú “Datos”). Seleccionamos laopción “Añadir nuevo origen de datos” y añadimosun origen de datos de objeto. En la pantalla que semuestre aparecerán los posibles objetos que puedenser origen de datos y, cómo no, también estará nues-tro servicio, ya referenciado. Desplegamos el árbol yseleccionamos el objeto ClienteDotNetMania, como seilustra en la figura 2. El resultado será que en la ven-tana de orígenes de datos tendremos un nuevo ori-gen de datos con la estructura del contrato publica-do por el servicio.

Ya sólo tenemos que arrastrar y soltar el objetoen modo GridView sobre el formulario. Visual Stu-dio creará un BindingSource y un BindingNavigator,y una rejilla enlazada al BindingSource con la estruc-tura del contrato; eso sí, con los campos desordena-dos. Ahora añadimos un botón y un cuadro de tex-to al formulario, y con tres líneas de código podre-mos cargar el BindingSource con el resultado de lallamada al método ObtenerClientes, como se apre-cia en el listado 6.

¿Cómo es posible esto? Bien, recordemos quehabíamos definido nuestro contrato de modo que lallamada a ObtenerClientes devolviera una matriz de

objetos ClienteDotNetMania. Sin embargo, VisualStudio nos lo pone más fácil, y en el proxy generadoel método ObtenerClientes devuelve un objeto detipo BindingList(Of ClienteDotNetMania). Precisa-mente el tipo BindingList(Of T) es idóneo para enla-zarlo a un BindingSource. El control GridView estáenlazado al BindingSource, así que para él es indife-rente el origen de los datos, que son gestionados porel BindingSource. Si introducimos una letra cual-quiera en el cuadro de texto y pulsamos el botón,veremos como la rejilla se llena con los registrossuministrados por el servicio.

Figura 1

Figura 2

dotN

etM

anía

<<

28

dnm.plataforma.net<<

El BindingSource actualizará elobjeto ClienteDotNetMania subyacen-te cuando realicemos cualquier cam-bio en la rejilla. Actualizar la base dedatos consistirá tan solo en recuperarel objeto subyacente y llamar al méto-do correspondiente del servicio. Ellistado 7 muestra la forma. La pro-piedad Current del BindingSource con-tiene un objeto ClienteDotNetMania,pero no lo podemos enviar así al ser-vicio, así que lo convertiremos antesa un objeto del tipo adecuado. No hayque olvidar realizar antes un EndEditsobre el BindingSource para traspasarposibles cambios pendientes al obje-to subyacente.

La forma concreta de gestionar estemantenimiento dependerá de los gus-tos o las necesidades, pero ya podemosver que, una vez establecida la referen-cia al servicio, VS.NET nos permitetrabajar con la estructura definida en elcontrato de forma totalmente transpa-rente. No es necesario prescindir delpotente data binding, ni tampoco recre-ar en local las estructuras que ya estánconvenientemente definidas en el con-trato de datos.

El cliente ASP.NET

Si hemos escrito poco código para inte-ractuar con nuestro servicio en la apli-cación Windows Forms, aún tendre-mos que escribir menos código parahacerlo desde una aplicación ASP.NET.De hecho, podemos enlazar con el ser-vicio desde una aplicación ASP.NETen lectura y escritura sin escribir ni unasola línea de código. El único códigoque tendremos que escribir serán algu-nas líneas para refrescar la rejilla y paraevitar pasar un parámetro nulo al ser-vicio –eso es todo–.

Pero vayamos por partes. En primerlugar tenemos que crear una referenciaal servicio, cosa que haremos tratando elservicio como si de un servicio Web setratase, añadiendo al proyecto una refe-rencia Web. El que genera Visual Studiopara ASP.NET es distinto del que se creapara una aplicación Windows Forms, yaque todo el proxy está constituido por dife-rentes documentos XSD que definen nosólo la estructura de los datos sino los pro-pios métodos del servicio. Eso no ha deimportarnos: el acceso al servicio es igual-mente sencillo mediante código y pode-mos realizar a él llamadas síncronas o asín-cronas, como si de cualquier otro com-ponente se tratara.

Nuestra página ASP.NET dis-pondrá de un cuadro de texto, un botón,un control GridView y un control Form-View. En la caja de texto pondremosalgún carácter para cargar en la rejillalos clientes cuyo CustomerID comienzapor esos caracteres. Luego configura-remos la rejilla para que, al seleccionarun registro, éste se cargue en el Form-View y podamos actualizar sus valores.

Después de colocar el cuadro de tex-to y el botón sobre el formulario Web,añadiremos un ObjectDataSource al mis-mo. La etiqueta nos permitirá configu-rarlo, y he aquí los pasos a realizar parapoder enlazar su contenido a la rejilla.

• Al configurar el ObjectDataSource,podremos elegir entre cierto núme-ro de objetos disponibles en la listadesplegable que aparece en la pri-mera pantalla del asistente. La figu-ra 3 nos muestra las diferentes posi-bilidades, pero sólo una nos sirve: laque selecciona al servicio como

dim servicio as New ServicioWCF.ServicioDotNetManiaClientme.ClienteDotNetManiaBindingSource.DataSource=servicio.ObtenerClientes

(me.TextBox1.Text)servicio.Close

Listado 6

dim servicio as New ServicioWCF.ServicioDotNetManiaClientme.ClienteDotNetManiaBindingSource.EndEditdim objCliente as ClienteDotNetMania

objcliente=ctype( me.ClienteDotNetManiaBindingSource.Current, _ClienteDotNetMania)

tryservicio.ActualizarCliente(objcliente)

Catch ex As Exceptionmessagebox.Show(ex.Message)

Finallyservicio.Close

End Try

Listado 7

El modelo de enlace a datos de VS.NET es tan poderoso que nos permitirá enlazar cómodamente loscontroles de la capa de presentación a las estructuras

de datos publicadas por los servicios WCF

dotN

etM

anía

<<

29

dnm.plataforma.net<<

“objeto comercial”, tal y como indica la desafor-tunada traducción. Hemos de cuidar no marcar lacasilla “Mostrar sólo componentes de datos”, yaque eso sólo nos muestra componentes que devuel-ven DataSet, y por supuesto que en nuestra apli-cación no hay ninguno.

• La siguiente pantalla del asistente nos solicita elmétodo necesario para realizar la SELECT. En estecaso, Visual Studio no nos facilita tanto las cosascomo en Windows Forms: el resultado de la ope-ración ObtenerClientes es una matriz (claro, loque devuelve el servicio), y no podemos enlazaresa estructura con la rejilla. ¿Qué hacer? Afor-tunadamente, también tenemos un métodoObtenerCliente que recupera un único objeto.Seleccionaremos este método de momento. Noseleccionaremos ningún método para actuali-zar, insertar o eliminar registros, ya que esasoperaciones se realizarán mediante el FormView.

• La última pantalla del asistente nos solicita elorigen para el parámetro IDCliente del métodoObtenerCliente. Fijaremos como origen del pará-metro un control, TextBox1, y desplegaremos lasopciones avanzadas para cambiar la opción Con-vertEmptyStringToNull a False, ya que no pode-mos pasar un argumento nulo al servicio.

Una vez preconfigurado el ObjectDataSource,colocaremos un GridView en el formulario. Lo enla-zaremos al ObjectDataSource y comprobaremos queel control recupera la información de la clase Clien-teDotNetMania y genera las columnas enlazadas a cadauna de las propiedades de la clase. Están desordena-das, pero eso es fácil de arreglar utilizando la etiquetainteligente de la rejilla. Y ya que estamos aquí, habi-

litaremos la función de “Seleccionar” y le daremosalgún formato automático al control para poder resal-tar el registro seleccionado.

Una vez enlazado a la rejilla, ya podemos enlazar“de verdad” el ObjectDataSource. Para ello, volveremosa configurarlo y en la pantalla de selección escogere-mos el método correcto que utilizaremos para llenar larejilla: el método ObtenerClientes. Dejamos el resto dela configuración como estaba (comprobando que elparámetro de entrada sigue obteniéndose del cuadrode texto) y cerramos el asistente. Ahora hemos de pro-curar no seleccionar la opción “Actualizar esquema”,ya que el ObjectDataSource se quejaría de que no pue-de deducir el esquema a partir de la matriz.

El último toque antes de pasar al FormView con-siste en indicarle al GridView cuál es el campo queactúa como clave de los registros. Este es el campoque el GridView utilizará para la propiedad Selec-tedValue. Si el origen fuera un DataTable tipado (quetuviera clave principal, claro está) lo deduciría; perocomo no lo es, tenemos que decírselo. Buscamos lapropiedad DataKeyNames de la rejilla en la ventana depropiedades y escribimos “IDCliente”. De esta for-ma, cuando seleccionemos un registro en la rejilla,el valor del campo IDCliente de ese registro ocuparáel valor de la propiedad SelectedValue.

Añadamos ahora un segundo ObjectDataSourceal formulario. Éste lo configuraremos de forma simi-lar, pero esta vez utilizaremos el método Obtener-Cliente para la SELECT, y seleccionaremos tambiénlos métodos correspondientes para las acciones deUPDATE, INSERT y DELETE. En la pantalla final, el pará-metro necesario para la SELECT lo extraeremos delcontrol GridView y su propiedad SelectedValue.

Sólo nos queda añadir un FormView al formularioWeb y enlazarlo al segundo ObjectDataSource. Paraque no haya problemas al cargar el formulario, pode-mos poner un valor por defecto en el parámetroSELECT o sencillamente ocultar el control FormViewhasta que no se haya seleccionado un registro. Tam-bién actualizaremos el GridView cada vez que se rea-lice una actualización. El código necesario se mues-tra en el listado 8.

No hay que hacer nada más; el formulario con-vertirá los diferentes valores de los controles enla-zados en propiedades de un objeto ClienteDotNet-Mania que se enviará al servicio y al método adecua-do en cada ocasión.

Y después de todo,¿por qué no un DataSet?Ya comentamos al principio que no es recomendableutilizar un DataSet en la comunicación con un servicioWCF, debido sobre todo a la necesidad de interoperar

Figura 3

dotN

etM

anía

<<

30

dnm.plataforma.net<<

con otros sistemas no .NET. Pero, ¿y sino tuviéramos que interoperar, como ocu-rre en muchas aplicaciones corporativasde uso interno? Además, la actualizaciónde los contratos no es un problema dema-

siado importante, sobre todo pudiendoutilizar ClickOnce para distribuir los desa-rrollos sobre Windows. Hay que pensarque en nuestra propia casa podemos hacerlo que queramos…

En tales casos, quizás nos intereseutilizar un DataSet como parte del con-trato de servicios y datos. No hay nadaque nos lo impida. Lo único quetendríamos que hacer es modificar nues-tros contratos para pasar un DataTablecomo parte del contrato. No es necesa-rio cambiar el contrato del servicio, perodebemos modificar el contrato de datos.El objeto ClienteDotNetMania tendría eneste caso una propiedad TablaClientesque devolvería un objeto DataTable tipa-do, ya que no podemos utilizar el Data-Table como DataMember del contrato dedatos. El esquema del DataTable seseriará a través del WSDL generado porWCF y aún será mucho más fácil enla-zar los controles. Los métodos del ser-vicio pueden cargar el DataTablemediante una llamada normal y corrien-te al método Merge.

Pero de todas formas no es necesa-rio utilizar un DataSet. Como hemosvisto, WCF expone claramente el con-trato de datos y Visual Studio es capazde recoger ese contrato y convertirlo enuna estructura utilizable por los con-troles de Windows Forms y ASP.NET.

ConclusiónHace tiempo que pasó la época en quela técnica del data binding era tan peli-grosa que no podía ni pensarse en uti-lizarla. En la actualidad la situación escompletamente opuesta, y resulta muyconveniente aprovechar las caracterís-ticas del modelo de enlace a datos deVS para conseguir crear aplicacionesfiables con rapidez. Siempre existiránsituaciones en que la utilización delenlace a datos quizás no será la mejorsolución, pero estamos claramente enun proceso de perfeccionamiento dedicha técnica.

Windows Communication Founda-tion es una tecnología que no puede que-dar al margen de estos avances, y comohemos mostrado es totalmente compati-ble con la técnica de data binding existen-te. Es una buena idea acostumbrarse des-de ya mismo a manejar estas técnicas:nuestras aplicaciones y nuestro tiempolibre nos lo agradecerán.

Figura 4

Partial Class _DefaultInherits System.Web.UI.Page

Protected Sub FormView1_ItemDeleted(ByVal sender As Object, _ByVal e As System.Web.UI.WebControls.FormViewDeletedEventArgs) _Handles FormView1.ItemDeleted

me.GridView1.DataBindEnd Sub

Protected Sub FormView1_ItemInserted(ByVal sender As Object, _ByVal e As System.Web.UI.WebControls.FormViewInsertedEventArgs) _Handles FormView1.ItemInserted

me.GridView1.DataBindEnd Sub

Protected Sub FormView1_ItemUpdated(ByVal sender As Object, _ByVal e As System.Web.UI.WebControls.FormViewUpdatedEventArgs) _Handles FormView1.ItemUpdated

me.GridView1.DataBind End Sub

Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, _ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged

me.FormView1.Visible=TrueEnd Sub

End Class

Listado 8

Del 18 a l 22 de jun io de l 2007

Una de las principales novedades de WPF es quesu procesamiento de gráficos se realiza a través deDirectX, la principal biblioteca de funciones y tiposgráficos, incluyendo 3D, desarrollada para Win-dows. Esta asociación le da a WPF la posibilidadde aprovechar la velocidad de las tarjetas gráficas,de producir gráficos con la calidad típica de losque se obtienen con DirectX y de manipular elmundo tridimensional. Se pone con esto en manode los desarrolladores de interfaces de usuario unmodo fácil, elegante y transparente de aprovecharlos recursos tridimensionales (3D), algo que has-ta la fecha había sido casi patrimonio exclusivo delas aplicaciones de juegos.

Ahora se podría desarrollar entonces un “botóncon tapa” para dar mayor protección, como se ilus-tra en las tres posiciones del botón de la figura 1.

En este artículo explicamos las bases para lograrefectos 3D en la apariencia de los controles.

El entorno tridimensionalLa apariencia bidimensional de una interfaz seobtiene por composición de controles ubicadossegún una distribución (layout). En el mundo bidi-mensional, la apariencia se logra por combinaciónde figuras coloreadas con brochas, imágenes y tex-to. En un artículo previo en dotNetManía [1] seilustró cómo con WPF podemos incluso definirnuestros propios layouts.

Definir un entorno tridimensional en WPF esun proceso más elaborado. Un entorno 3D seinserta dentro de la apariencia de una aplicacióna través de un elemento Viewport3D, que es un ele-mento de interfaz de usuario que hereda de Fra-meworkElement al igual que los controles, figuras yelementos bidimensionales de WPF.

Claro que todo es finalmente bidimensional sitermina mostrándose en un monitor1. El View-port3D ofrece una proyección en un plano, obte-nida a partir de una “cámara” ubicada en un“entorno tridimensional”. Esta cámara se asociaal Viewport3D a través de la propiedad Camera. Porejemplo, si en el entorno de la figura 2 se pusierauna cámara (figura 2a), lo que se vería en la ven-

Entrando en la

tercera dimensión

plataforma.net

En este artículo se hace una introducción práctica a las nuevas posibili-dades que WPF (Windows Presentation Foundation) abre ante losdesarrolladores para utilizar recursos 3D en las aplicaciones.

Miguel Katrib,Mario del Valle,Iskander Sierra,Yamil Hernández

Figura 1. Botón tridimensional con tapa

1 Al menos hasta que aparezcan los “monitores holográficos”

MMiigguueell KKaattrriibb es doctor yprofesor jefe de progra-

mación del departamentode Ciencia de la Compu-tación de la Universidadde La Habana. Miguel es

líder del grupo WEBOO,dedicado a la orientacióna objetos y la programa-ción en la Web. Es entu-

siasta de .NET y redactorde dotNetManía.

MMaarriioo ddeell VVaallllee, IIsskkaannddeerrSSiieerrrraa y YYaammiill HHeerrnnáánnddeezzson instructores de pro-gramación en C# de la

cátedra de Programacióne Ingeniería de Software

del departamento deCiencia de la Computa-

ción de la Universidad deLa Habana. Son desarro-

lladores del grupoWEBOO dedicados a la

tecnología .NET.

tana de la aplicación sería una imagen como la de lafigura 2b.

La visión del mundo en tres dimensionesLa cámara es el elemento que determina la posición delobservador en el mundo 3D, y lo que se muestra en elViewport3D es lo que ve esta cámara. Se pueden utilizarvarios tipos de cámaras en WPF. Por razones de espa-cio, en este artículo solo explicaremos una de ellas: lacámara de perspectiva (PerspectiveCamera).

Se puede asociar al entorno una cámara de perspec-tiva como se ilustra en el listado 1 (figura 2). Imagine queusted ha tomado la posición de esta cámara (Position).A la propiedad Position se le asignan tres valores que sonlas coordenadas x, y y z en que se ubica la cámara. La pro-piedad LookDirection indica la dirección hacia donde seenfoca la cámara. La propiedad UpDirection indica haciadónde está la parte superior de la cabeza (recuerde quele pedimos imaginarse en la posición de la cámara); siusted estuviera mirando al entorno cabeza abajo, pondría(0,0,-1) en vez de (0,0,1). La propiedad FieldOfViewindica el ángulo de visión dado en grados.

Con iluminación

Un código XAML como el del listado 1 no bastapara ver los cuerpos que se pongan en el entorno 3D.Además, es necesario poner luces. WPF tiene formas deiluminación que simulan algunas de las más comunesque existen en el mundo real. La luz ambiental (AmbientLight) se utiliza para hacer que la luz esté presente entodo el entorno, como la que se tiene cuando una habi-tación está muy iluminada por la luz solar pero sin laincidencia directa de los rayos solares. La luz direccio-nal (DirectionalLight) representa una luz provenientede una fuente muy lejana que incide con un ánguloespecífico, como la luz del sol. La figura 3 (resultantedel listado 2) muestra dos luces direccionales incidien-do sobre una esfera). La luz puntual (PointLight) es otrade las luces disponibles; esta luz proviene de un puntoespecífico, como los faroles urbanos. Como caso parti-

dnm.plataforma.net<<

dotN

etM

anía

<<

33

<Window x:Class=”Paper3D.Window1”xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”Title=”Windows Presentation Foundation 3D” Height=”300” Width=”300”><Viewport3D><Viewport3D.Camera><PerspectiveCamera Position=”1,-1,2” LookDirection=”-1,1,-2”

UpDirection=”0,0,1” FieldOfView=”45”/></Viewport3D.Camera>...

</Viewport3D></Window>

Listado 1

Figura 2.Vista de un entorno 3D.A la izquierda, entorno 3D y cámara. A la derecha, visión del entorno en la ventana de la aplicación.

b)

Para mantener siempre a la cámara miran-do hacia (0,0,0), defina LookDirectioncon los mismos valores x, y y z que Posi-tion, pero con los signos cambiados.[ ]NOTA

a)

dnm.plataforma.net<<

dotN

etM

anía

<<

34

cular de luz puntual está la luz de linterna (SpotLight),que también proviene de un punto (hereda de Poin-tLight) pero que además incide a través de un cono orien-tado en una dirección indicada.

Elementos tridimensionales y cuerpos

En el listado 2 se observan las dos luces direccionalespuestas en un grupo de modelos 3D (Model3DGroup) yéste a su vez en el contenido (propiedad Content) de unmodelo visual 3D (ModelVisual3D). Esta forma de defi-nición es la que se emplea para definir entornos 3D enWPF. En general, los entornos son un conjunto demodelos visuales 3D que agrupan a luces y cuerpos tri-dimensionales en grupos de modelos 3D. A su vez, cadamodelo visual 3D puede también contener otros mode-los, formando una estructura jerárquica de cuerpos yluces muy útil cuando se quieran animar los elementosdel entorno.

Los cuerpos (GeometryModel3D) son elementos tri-dimensionales (herederos de Model3D) que al igual quelas luces se pueden insertar en el entorno poniéndo-los como contenido de un ModelVisual3D. Cada cuer-po se define por una figura geométrica 3D (Geometry3D)y por el material del que está hecho el cuerpo, quepuede ser brilloso y emisor o difusor de luz con tex-turas de brochas de WPF. Los materiales serán des-critos más adelante.

Básicamente, las figuras se definen por una mallade triángulos ubicados en el espacio a través de la pro-piedad Positions, que consiste en una colección devértices, y TriangleIndices que permite indicar cua-les vértices conforman a cada triángulo. Además deestas dos propiedades, debe indicarse una colecciónde vectores que determinan cómo se refleja la luz encada vértice (Normals), y finalmente una colección deíndices con los que se asocia a cada vértice una posi-ción relativa en la imagen que se emplee como tex-tura para el material con que se cubre al cuerpo. Lafigura 4 muestra la malla que define a la esfera de lafigura 3.

Todas estas propiedades tienen una forma dedefinición bastante compleja como para ser incrus-tada manualmente en el XAML. Usualmente seemplean herramientas de diseño de cuerpos o cla-ses que las generen. Lamentablemente, WPF nocuenta con una definición de figuras geométricastridimensionales básicas como prismas, conos o esfe-ras. El listado 3 ilustra cómo podría ser un códigoque genere la definición de la esfera que se mues-tra en la figura 3.

Figura 3. Luces direccionales aplicadas sobre una esfera

Figura 4. Malla de triángulos que define a una esfera

...<Viewport3D><Viewport3D.Camera>...</Viewport3D.Camera><ModelVisual3D><ModelVisual3D.Content><Model3DGroup><DirectionalLight Color=”White” Direction=”1,0,-1”/><DirectionalLight Color=”#8FFF” Direction=”-1,0,1”/>

</Model3DGroup></ModelVisual3D.Content>// ... Aquí vendría la declaración de la esfera

</Viewport3D>

Listado 2

dnm.plataforma.net<<

dotN

etM

anía

<<

3535

public class SphereBuilder {double radius = 1; Geometry3D geometry;int widthSegments = 30, heightSegments = 10;

public double Radius {get { return radius; }set { radius = value; GeometryChangedBy(“Radius”); }

}

public int WidthSegments {get { return widthSegments; }set { widthSegments = value; GeometryChangedBy(“WidthSegments”); }

}

public int HeightSegments {get { return heightSegments; }set { heightSegments = value; GeometryChangedBy(“HeightSegments”); }

}

public int GeometryChangedBy(string propertyName) {...

}

public Geometry3D Geometry {get {if (geometry == null)geometry = BuildGeometry();

return geometry;}

} public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name) {if (PropertyChanged != null)PropertyChanged(this, new PropertyChangedEventArgs(name));

}

protected void GeometryChangedBy(string name) {geometry = null;OnPropertyChanged(“Geometry”);OnPropertyChanged(name);

}

protected Geometry3D BuildGeometry() {MeshGeometry3D geom = new MeshGeometry3D();FillPositions(geom.Positions);FillNormals(geom.Normals);FillTextureCoordinates(geom.TextureCoordinates);FillTriangleIndices(geom.TriangleIndices);return geom;

}protected virtual void FillPositions(Point3DCollection positions) {double hAngle = 2 * Math.PI / widthSegments;double vAngle = Math.PI / heightSegments;for (int y = 0; y <= heightSegments; y++) {double vertAngle = vAngle * y - Math.PI / 2;for (int x = 0; x <= widthSegments; x++) {double horizAngle = hAngle * x;positions.Add(new Point3D(radius * Math.Cos(horizAngle) * Math.Cos(vertAngle), radius * Math.Sin(vertAngle),radius * Math.Sin(horizAngle) * Math.Cos(vertAngle)));

}

dnm.plataforma.net<<

dotN

etM

anía

<<

36

Utilizando el tipo SphereBuilder del listado 3 sepuede luego aplicar la malla que se obtiene con supropiedad Geometry, enlazando esta propiedad con lapropiedad Geometry de un cuerpo (GeometryModel3D)que se ponga en el entorno, como se muestra en ellistado 4.

Tejiendo la mallaCon el nombre de malla (mesh) se conoce a la made-ja de puntos y triángulos que definen una figurageométrica en tres dimensiones. La clase Sphere-

Builder que se definió con el código del listado 3 per-mite configurar algunas propiedades de una esferacomo el radio, la cantidad de divisiones verticales yhorizontales. A partir de éstas, y en demanda de unamalla por parte del Binding del listado 4, se constru-ye una en el método BuildGeometry, que se llama des-de la propiedad Geometry. Observe que se ha imple-mentado la interfaz INotifyPropertyChanged, de modoque cuando se cambia una propiedad del SphereBuil-der se notifican en el método GeometryChangedBy loscambios de valor en dicha propiedad y en la propie-dad Geometry. El método BuildGeometry crea una ins-tancia de MeshGeometry3D y llama a los métodos Fill-

}}protected virtual void FillTriangleIndices(Int32Collection triangleIndices){for (int y = 0; y < heightSegments; y++) {for (int x = 0; x < widthSegments; x++) {int t0 = x + y * (widthSegments + 1);int t1 = t0 + 1;int t2 = x + (y + 1) * (widthSegments + 1);int t3 = t2 + 1;triangleIndices.Add(t0);triangleIndices.Add(t2); triangleIndices.Add(t3);

triangleIndices.Add(t3);triangleIndices.Add(t1);triangleIndices.Add(t0);

}}

}protected virtual void FillNormals(Vector3DCollection normals) {double hAngle = 2 * Math.PI / widthSegments;double vAngle = Math.PI / heightSegments;for (int y = 0; y <= heightSegments; y++) {double vertAngle = vAngle * y - Math.PI / 2;for (int x = 0; x <= widthSegments; x++) {double horizAngle = hAngle * x;normals.Add(new Vector3D(Math.Cos(horizAngle) * Math.Cos(vertAngle),Math.Sin(vertAngle), Math.Sin(horizAngle) * Math.Cos(vertAngle)

));}

}}protected virtual void FillTextureCoordinates(PointCollection textureCoord){double textWidthSize = 1.0 / widthSegments;double textHeightSize = 1.0 / heightSegments;for (int y = 0; y <= heightSegments; y++) {for (int x = 0; x <= widthSegments; x++)textureCoord.Add(new Point(x * textWidthSize, y * textHeightSize));

}}

}

Listado 3

dnm.plataforma.net<<

dotN

etM

anía

<<

37

Positions, FillNormals, FillTextureCoordinates y Fill-TriangleIndices para crear los diferentes elementosde la malla.

Para diferentes valores de las propiedades de laesfera se obtienen mallas diferentes, como se mues-tra en la figura 5. Para valores pequeños de las pro-piedades WidthSegments y HeightSegments se obtienenesferas con bordes rectos, y para valores altos se lograuna mejor aproximación a una esfera perfecta. Mien-tras más puntos y triángulos se tengan, se logra unamejor resolución del objeto que se quiere construir;pero claro, esto se cobra en rendimiento a la hora demostrar el objeto en la ventana.

Los métodos FillPositions y FillTriangleIndicesson primordiales en la construcción de la malla. Ambosse encargan de rellenar las colecciones dadas por laspropiedades Positions y TriangleIndices de MeshGeo-metry3D. Si a una malla le falta por configurar algunasde estas dos colecciones, no se obtiene ningún obje-to 3D. Para obtener los puntos de la malla se utilizala propiedad Positions y se recorren todas las posi-ciones dentro de un rectángulo como el de la figura6. Es decir, se añade primero el punto (0, 0, 0), querepresenta el señalado con el cero, luego el (0.1, 0,0), señalado con el uno y así sucesivamente, hastacubrir la primera fila de puntos. Luego se pasa a la

segunda fila (señalada conlos puntos 7, 8, 9, etc.) y ala tercera, hasta cubrirtodo el rectángulo. Ladiferencia entre construirun plano de esta manera yla esfera de este artículo esque los puntos no se ubi-can en las mismas posi-ciones del espacio. En elplano éstos se distribuyende manera uniforme a lolargo de los ejes X e Y,mientras que en la esfera

<Window ...><Window.Resources><this:SphereBuilder x:Key=”Sphere” Radius=”1”

WidthSegments=”50” HeightSegments=”50”/></Window.Resources><Viewport3D ><Viewport3D.Camera>...</Viewport3D.Camera><ModelVisual3D><ModelVisual3D.Content>

... <!—Luces—></ModelVisual3D.Content><ModelVisual3D> <!—Cuerpos—><ModelVisual3D.Content><GeometryModel3D Geometry=”{Binding Geometry,

Source={StaticResource Sphere}}”>...</GeometryModel3D>

</ModelVisual3D.Content></ModelVisual3D>

</ModelVisual3D></Viewport3D>

</Window>

Listado 4

Figura 5.A la izquierda, una malla menos tupida produce una esfera de baja definición.A la derecha se logra una mejor aproximación visual.

dnm.plataforma.net<<

dotN

etM

anía

<<

38

se ubican realizando barridos alrededor del origen decoordenadas, con puntos equidistantes al centro dela esfera; de ahí que las fórmulas para generarlos seanalgo más complejas para la esfera que para el plano.La analogía entre el plano y la esfera se evidencia enel párrafo siguiente.

Los triángulos de la malla se definen con relacióna los puntos dados en Positions. La propiedad Trian-gleIndices contiene números enteros que represen-tan índices en la lista de puntos de la malla y siemprese manipulan en tríos, de modo que si se añaden losvalores 0, 8 y 1, se está creando el triángulo resalta-do en azul de la figura 6. Si se coloca la malla de fren-te a la cámara, los índices se deben referir en el sen-tido contrario a las manecillas del reloj. En otro casose considera que el triángulo está orientado en sen-tido contrario, y solo se observaría si se coloca la cáma-ra por el “otro lado” del plano. El método Fill-TriangleIndices se puede utilizar para diferentes tiposde objetos que se creen a partir de un plano curvadoen el espacio, como la esfera, un cono o incluso untoroide. En próximos artículos usaremos esto paracrear otros efectos interesantes.

Como características opcionales de una malla sepueden especificar las direcciones de las normalesde cada vértice, relacionada con la forma en que elobjeto refleja la luz a su alrededor, y las coordena-das de texturas, relacionada con la forma en que sepuede dibujar una imagen en la superficie del obje-to. Una normal, o más formalmente un vector nor-mal a una superficie, representa una dirección total-mente perpendicular a la misma. De modo que lanormal del suelo (si su casa es “normal”), es la direc-

ción que va de abajo hacia arriba, y de las paredes,de derecha a izquierda, de delante hacia atrás, etc.Para suavizar la figura y que no parezca formadapor pequeños triángulos, es muy importante la for-ma en que se dirigen las normales. En la colecciónNormals debe haber una instancia de Vector3D porcada instancia de Point3D en la colección Positions,ya que a cada vértice de la malla se asocia la normalcorrespondiente en la colección de normales. Lafigura 7 a la izquierda muestra una esfera que ubi-ca las normales totalmente perpendiculares a lascaras, mientras que en la figura a la derecha las nor-males se han ubicado de forma que toman el pro-medio de las normales de la caras que convergen essu vértice correspondiente. Aún cuando los bordesde la esfera se pueden apreciar rectos, la segunda

Figura 6. Definición de una malla por sus puntos y triángulos

Para que un cuerpo pueda finalmente verseen un Viewport3D no basta con la

descripción de la malla.Hay que definirle unmaterial.Con los materiales se especifica la

coloración de la superficie del cuerpo ycómo afecta la luz a la superficie del mismo

dnm.plataforma.net<<

dotN

etM

anía

<<

39

versión logra un mejor resultado sin afectar el ren-dimiento.

Para representar cuerpos de color completo bas-tará con asociarle un material al cuerpo, de un colorsólido, como en el listado 5. Sin embargo, cuando se

use como brocha una imagen, u otra fuente que noutilice un color sólido, se debe indicar en la colecciónTextureCoordinates a qué punto de la imagen corres-ponde cada punto del objeto 3D. Esta colección admi-te un Point por cada Point3D en la colección Positions.Cada punto de coordenada de la textura está dado enun rectángulo en la posición (0, 0) y de ancho y altoigual a uno. En la figura 8 se muestra la esfera (conbaja resolución, para poder apreciar los vértices), lue-go una imagen que se utilizará como textura, y final-mente se muestra la esfera coloreada con la imagen.Note que el efecto es semejante al de cubrir con laimagen toda la superficie de la esfera.

Materiales

Para que un cuerpo puedafinalmente verse en unViewport3D no basta con ladescripción de la malla.Hay que definirle un mate-rial. Con los materiales seespecifica la coloración dela superficie del cuerpo ycómo afecta la luz a lasuperficie del mismo. Esdecir, si la luz se refleja conbrillantez (SpecularMate-

rial), si el cuerpo emite su propia luz (EmissiveMate-rial), o si la luz simplemente se difunde por toda lasuperficie del cuerpo (DiffuseMaterial). Adicionalmentese pueden definir materiales compuestos que permitanpor ejemplo, que la luz se difumine iluminando a todo

el cuerpo pero a la vez dejando que se refleje parte deella en forma de brillo, como en la figura 3. Esto se pue-de lograr utilizando los grupos de materiales (Material-Group). Para la figura 3 hemos empleado un DiffuseMa-terial para la difusión de la luz y un SpecularMaterialpara la brillantez (listado 5).

Observe en el listado 5 cómo se emplea la propie-dad Brushpara indicar la forma en que se colorea la super-ficie del cuerpo. A esta propiedad se puede asignar cual-quiera de las 5 brochas que normalmente se empleanpara los elementos bidimensionales. El listado 6 mues-tra el uso de un VisualBrush para colorear la esfera dela figura 3. La esfera se está pintando con una brocha

Figura 7.Visualización de la esfera con normales sin suavizar a la izquierda, y suavizadasa la derecha.

Figura 8. Aplicación de una textura a una esfera.

dnm.plataforma.net<<

dotN

etM

anía

<<

40

...<GeometryModel3D Geometry=”{Binding Geometry}”><GeometryModel3D.Material><MaterialGroup><DiffuseMaterial Brush=”RoyalBlue”/><SpecularMaterial SpecularPower=”10” Brush=”#8FFF”/>

</MaterialGroup></GeometryModel3D.Material>

</GeometryModel3D>...

Listado 5

<Window ... ><Window.Resources><VisualBrush x:Key=”Images” ><VisualBrush.Visual><Grid Height=”500” Width=”700” Background=”Transparent”><Grid.RowDefinitions><RowDefinition Height=”2*”/><RowDefinition/><RowDefinition Height=”2*”/>

</Grid.RowDefinitions><StackPanel Grid.Row=”1” Orientation=”Horizontal”><Image Margin=”10,0” Source=”portada26.tif”/><Image Margin=”10,0” Source=”portada27.tif”/><Image Margin=”10,0” Source=”portada28.tif”/><Image Margin=”10,0” Source=”portada29.tif”/><Image Margin=”10,0” Source=”portada30.tif”/><Image Margin=”10,0” Source=”portada33.tif”/><Image Margin=”10,0” Source=”portada34.tif”/><Image Margin=”10,0” Source=”portada35.tif”/>

</StackPanel></Grid>

</VisualBrush.Visual></VisualBrush><this:SphereBuilder x:Key=”Sphere” Radius=”1”

WidthSegments=”50” HeightSegments=”50”/></Window.Resources><Viewport3D DataContext=”{StaticResource Sphere}”><Viewport3D.Camera>...</Viewport3D.Camera><ModelVisual3D>

<ModelVisual3D.Content>...</ModelVisual3D.Content><ModelVisual3D><ModelVisual3D.Content><GeometryModel3D Geometry=”{Binding Geometry”><GeometryModel3D.Material><MaterialGroup><DiffuseMaterial Brush=”{StaticResource Images}”/>

</MaterialGroup></GeometryModel3D.Material><GeometryModel3D.BackMaterial><MaterialGroup><DiffuseMaterial Brush=”{StaticResource Images}”/>

</MaterialGroup></GeometryModel3D.BackMaterial>

</GeometryModel3D></ModelVisual3D.Content>

</ModelVisual3D>

dnm.plataforma.net<<

dotN

etM

anía

<<

41

formada por un StackPanel con imágenes de portada dedotNetManía (figura 9).

Observe que la misma brocha se ha usado para espe-cificar tanto la propiedad Material como la propiedadBackMaterial que tienen todos los GeometryModel3D paracolorear el interior de los cuerpos. Si la malla ha sidobien definida geométricamente, al colorear el Materialy el BackMaterial de la esfera con la misma brocha debe

obtenerse como resultado que la imagen que se ve pordentro es la misma que la que se ve por fuera pero comosi fuese “vista por detrás”; todo esto gracias a que elmaterial con el que se está pintando el exterior de la esfe-ra es tomado de un Grid en el que toda el área que nosea la de las imágenes de las revistas es transparente. Estopermite entonces que se haga visible lo que se ha pinta-do con el BackMaterial en el interior de la esfera.

Si ahora se mueve la cámara al interior de la esfe-ra (Position=”0,0,0” y LookDirection=”-1,0.75,0”) seobtiene una vista como la de la figura 10.

ConclusionesClaro que sería pretencioso suponer que el mundo 3Dpueda abarcarse dentro del límite de páginas que debetener este artículo. Solo hemos querido ilustrarle algu-nos de los fundamentos de la propuesta de WPF paralograr 3D. En próximos artículos se verán otros efectosde apariencia que pueden lograrse con 3D.

No se preocupe, no piense que para incorporar efec-tos tridimensionales a sus aplicaciones tendrá que domi-nar toda la matemática que está detrás de lo que se haexplicado en este artículo.

Lo importante es que la explosión originada conWPF ya está propagándose a alta velocidad. En losmomentos de escribir este trabajo ya están disponiblesprimeras versiones de herramientas para hacer diseño3D que generan XAML, el cual luego podría incorpo-rarse a las aplicaciones a través de WPF. Microsoft estádesarrollando Blend [2] y Electric Rain ZAM3D [3].Próximos trabajos de dotNetManía darán los primerospasos con estas herramientas.

</ModelVisual3D></Viewport3D>

</Window>

Listado 6

Figura 9. Distribución circular de imágenes usandouna esfera coloreada con un VisualBrush

Figura 10. Entorno de la figura 9 con la cámara en el centro de la esfera

ReferenciasSierra Iskander, Hernández Yamil, delValle Mario, Katrib Miguel, “Cómo definirnuestros propios paneles personalizados enWPF”, dotNetManía Nº 35, marzo de 2007.

http://www.microsoft.com/expression/products/over-view.aspx?key=blend

http://www.erain.com/Products/ZAM3D/DefaultPDC.asp

[1]

[2]

[3]

En .NET Framework se puede realizar la serializa-ción de objetos de dos formas: serialización binariay serialización XML. En la primera, hacemos unacopia completa del objeto que queremos almacenar(en formato binario o bit a bit), mientras que en laserialización XML serializamos las propiedades y cam-pos públicos utilizando XML como formato de laserialización, con lo que nos aseguramos de que podre-mos leerlo en cualquier plataforma y con cualquierlenguaje, ya que XML es un estándar.

En este artículo y otro posterior veremos ejem-plos prácticos de cómo usar estos dos tipos de seria-lización con .NET Framework. Empecemos con laserialización binaria.

Serialización binariaComo el propio nombre indica, la serialización bina-ria hace una copia completa del objeto que queremosalmacenar o transferir; es decir, se copia o persiste elobjeto completo. Debido a que se usa un formatobinario, tanto el lenguaje que serializa el objeto comoel que lo vuelve a su estado normal deben conocer lospormenores del formato utilizado. Si estamos usan-do para ambas acciones los lenguajes de .NET, ese“detalle” no debe importarnos; pero si pretendemosserializar un objeto para que pueda ser recuperadosin importarnos el lenguaje o el sistema operativo enel que se realice esa acción, deberíamos optar por laserialización XML –de esta forma de serializar nosocuparemos en el próximo artículo–.

La serialización binaria la podemos hacer de dosformas, dependiendo del grado de control que que-ramos ejercer sobre los datos que se van a serializar.En el primer caso, será el propio runtime de .NET elque se encargue de hacer todo el trabajo, permitien-do que todo el contenido de la clase (o tipo) se pue-da serializar. En el segundo caso, debemos imple-mentar la interfaz ISerializable; de esta forma ten-dremos control sobre qué elementos de nuestra cla-se se van a serializar, en un momento veremos cómo.Independientemente de la forma que queramos usarpara realizar el proceso de serialización, tendremosque indicarle a .NET que nuestra intención es defi-nir un tipo serializable, y por ello tendremos que mar-car la clase que queremos serializar con el atributo

Serialización prácticaEl serializador que lo serialice... o es binario o sabe XML

fundamentos

Guillermo “Guille”Som es Microsoft MVP

de Visual Basic desde1997. Es redactor de

ddoottNNeettMMaannííaa, mentorde SSoolliidd QQuuaalliittyy IIbbeerrooaa--mmeerriiccaannaa, tutor de ccaamm--

ppuussMMVVPP, miembro deIneta Speakers BureauLatin America, y autorde los libros “Manual

Imprescindible de VisualBasic .NET” y “Visual

Basic 2005”.hhttttpp::////wwwwww..eellgguuiillllee..iinnffoo

En algunas situaciones nos veremos en la necesidad de transferir ciertos datosde un lugar a otro, y para poder hacer esa transferencia tendremos que guar-dar los datos de forma tal, que sea fiable la recuperación.Aquí es donde entraen juego la serialización.

Guillermo «Guille» Som

[Serializable]class Colega{

public string Nombre;public string Email;

public Colega(string nombre, string email){

this.Nombre = nombre;this.Email = email;

}

public override string ToString(){

return Nombre + “, “ + Email;}

}

Listado 1. Clase serializable

Serializable. En el listado 1 tenemos una clase listapara ser serializada.

Independientemente de que preparemos nuestrospropios tipos para ser serializados, debemos saber quemuchas de las clases definidas en la librería de clasesde .NET (BCL) ya están preparadas para que las poda-mos serializar.

Clases que implementan IFormatterPara realizar las tareas de serializar y deserializar ten-dremos que usar clases que implementen la interfazIFormatter. Esa interfaz define dos métodos: Seriali-ze y Deserialize. Como podemos imaginar, el prime-ro es el que se encarga de realizar el proceso de seria-lización (guardar el estado del objeto en un Stream),mientras que el segundo realiza la operación contrariade convertir el contenido de un Stream en un objeto.

Son varias las clases e interfaces que implemen-tan IFormatter, pero básicamente hay dos clases de.NET que nos pueden ser de utilidad para realizar elproceso de serialización y deserialización. Una de ellases BinaryFormatter (definida en el espacio de nombresSystem.Runtime.Serialization.Formatters.Binary) yserá la clase que usaremos cuando queramos realizarla serialización binaria. También tenemos la clase Soap-Formatter (definida en el espacio de nombres Sys-tem.Runtime.Serialization.Formatters.Soap), esa cla-se utilizará un “mensaje” SOAP, que básicamente esXML.

Serializar objetos

Cuando vamos a serializar el objeto, utilizaremos unfichero en el que guardarlo. El formato de ese fiche-ro dependerá del “formateador” que usemos: en elcaso de BinaryFormatter, el contenido será totalmen-te binario, mientras que si usamos SoapFormatter elcontenido del fichero resultante será XML.

En el código del listado 2 tenemos un ejemplo decómo serializar un objeto de tipo Colega en un fiche-ro usando la clase BinaryFormatter.

El contenido del fichero resultante tendrá toda lainformación del objeto que hemos serializado, y aldecir toda, me refiero a toda; es decir, que contienelos datos de la clase que define ese objeto, los cam-pos, propiedades, métodos, etc., ya sean públicos oprivados, además de la información del ensamblado.Al estar almacenada la información de forma “pro-pietaria”, solo el runtime de .NET sabrá cómo tra-tarla. La ventaja es que el formato usado es bastantecompacto y además compatible con versiones ante-riores, al menos entre las versiones 1.1 y 2.0.

Deserializar objetosEl proceso de deserialización es parecido. Simple-mente tenemos que indicarle al método Deserializeque recupere un objeto del fichero que le indiquemos(en realidad del Stream indicado, que puede ser decualquier clase derivada de Stream). Ese objeto lo ten-dremos que convertir en el tipo adecuado para poderacceder a los miembros que define. En el listado 3

dotN

etM

anía

<<

43

dnm.inicio.fundamentos<<

const string fic1 = @”E:\tmp\Colega1.binary”;

Colega c = new Colega(“Guille”, “[email protected]”);

// SerializarFileStream fs = new FileStream(fic1, FileMode.OpenOrCreate);

BinaryFormatter bf = new BinaryFormatter();bf.Serialize(fs, c);fs.Close();

Listado 2. Serializar un objeto usando BinaryFormatter

// DeserializarFileStream fs = new FileStream(fic1, FileMode.Open);

BinaryFormatter bf = new BinaryFormatter();

Colega c1 = (Colega)bf.Deserialize(fs);fs.Close();

Console.WriteLine(c1.Nombre);

Listado 3. Recuperar el objeto serializado con BinaryFormatter

Para poder acceder al espacio de nombresSystem.Runtime.Serialization.Format-ters.Soap debemos agregar una referenciaal ensamblado System.Runtime.Serializa-tion.Formatters.Soap.dll[ ]NOTA

dotN

etM

anía

<<

44

dnm.inicio.fundamentos<<

vemos el proceso de deserialización delobjeto guardado con el código anterior.

Realizar la serialización con SoapFormatterLa clase SoapFormatter la utilizaremosde la misma forma que BinaryFormatter,aunque el fichero resultante contendrála información usando SOAP; pero eluso es idéntico al mostrado en los lista-dos 2 y 3. Este “formateador”, aunqueen el fondo utiliza formato XML, tam-bién serializa los campos privados, perosi la compatibilidad entre versiones esun requisito, deberíamos optar porBinaryFormatter. En el listado 4 pode-mos ver el contenido resultante al seria-lizar un objeto de tipo Colega usandoSoapFormatter. Para simplificar, los espa-cios de nombres XML se han omitido.

Personalizar la serialización

Cuando aplicamos el atributo Seriali-zable a una clase, se serializa el conte-nido completo, incluso los campos pri-vados, pero es posible que nos intereseque ciertos campos no se serialicen, esdecir, que ciertos campos no se copienen el objeto serializado.

Si esa es nuestra intención, podemosaplicar el atributo NonSerialized al cam-po o campos que creamos conveniente.Por ejemplo, si tenemos la definición dela clase Colega del listado 5, el campom_Fecha no se serializará.

Como acabo de comentar, en elcódigo del listado 5 el campo m_Fecha nose serializa. Por tanto, si hacemos copia

de un objeto de ese tipo y lo deseriali-zamos, el valor que devolverá la pro-piedad de solo lectura Fecha será la pre-determinada de su tipo, en este caso01/01/0001 00:00:00.

Es posible que el lector piense quesi el campo lo inicializamos en el cons-tructor de la clase tendremos el proble-ma parcialmente resuelto, ya que almenos el valor de la fecha será elmomento en el que se construya el obje-to. Pero eso no hará que el valor pre-determinado siga siendo el valor quetenga por defecto la variable (en esteejemplo, una variable de tipo DateTime),ya que al realizar el proceso de deseria-lización el constructor no es invocado ypor tanto, cualquier tarea realizada en

el constructor será obviada, ya sea unconstructor sin parámetros o uno conparámetros, como es el caso de la claseColega del listado 5.

Como podemos imaginar, este tipode “problema” es obvio, ya que ésa esnuestra intención, es decir, que el valorde ese campo no se persista; por tanto,no habrá rastro ninguno del valor quetuviera. Esto es aplicable tanto a la seria-lización realizada con BinaryFormattercomo a la realizada con SoapFormatter.

<SOAP-ENV:Envelope xmlns:xsi=”...” xmlns:xsd=”...” xmlns:SOAP-ENC=”...”xmlns:SOAP-ENV=”...” xmlns:clr=”...” SOAP-ENV:encodingStyle=”...”><SOAP-ENV:Body><a1:Colega id=”ref-1” xmlns:a1=”...”><Nombre id=”ref-3”>Guille</Nombre><Email id=”ref-4”>[email protected]</Email></a1:Colega></SOAP-ENV:Body></SOAP-ENV:Envelope>

Listado 4. Resultado al serializar con SoapFormatter

[Serializable]class Colega{

public string Nombre;public string Email;

public Colega(string nombre, string email){

this.Nombre = nombre;this.Email = email;

}

public override string ToString(){

return Nombre + “, “ + Email;}

[NonSerialized]private readonly DateTime m_Fecha = DateTime.Now;public DateTime Fecha{

get { return m_Fecha; }}

}

Listado 5.Aplicar el atributo NonSerialized a los campos que no queremos serializar

Herencia de clases serializables

El atributo Serializable nose hereda, lo que viene asignificar que si derivamosuna clase a partir de otraque tiene asignado ese atri-buto, la clase derivada noserá serializable. Por tan-to, debemos aplicar eseatributo a todas las clasesque queramos serializar.

[ ]NOTA

dotN

etM

anía

<<

45

dnm.inicio.fundamentos<<

Personalizar la serialización con ISerializableOtra forma que tenemos de controlarcómo y qué se va a serializar de nues-tras clases es implementando la interfazISerializable (definida en el espacio denombres System.Runtime.Serialization).Esa interfaz define un solo método:GetObjectData, cuya implementaciónserá la que utilicemos para almacenarlos datos que nos interese mantener. La“persistencia” de los datos la haremos através del parámetro de tipo Serializa-tionInfo, el cual define el método Add-Value, que será el que usemos para guar-dar los valores. En el listado 6 podemosver parte de la definición de la claseColega modificada para implementar esainterfaz y cómo usar el método GetOb-jectData. Como puede observarse, losdatos que queremos serializar serán losque agreguemos por medio del métodoAddValue.

Las clases de tipo Formatter se encar-garán de llamar al método GetObjectDa-

ta cuando se invoque el método Seria-lize. Como esa llamada se hace a travésde un objeto del tipo de la interfaz, no esnecesario que definamos GetObjectDatacomo público (al menos si esta clase nola vamos a usar como base de otras cla-ses); por eso en el listado 6 el nombre dela interfaz se indica de forma explícita;

pero también sería válido definir el méto-do como public void GetObjectData. Encualquier caso, en Visual Basic quedaríatotalmente claro, ya que la forma de defi-

nirlo siempre “obliga” a indicar el méto-do de la interfaz que implementa, talcomo vemos en el listado 7.

Ese método debería estar marcadocon el atributo SecurityPermission (defi-nido en System.Security.Permissions) deforma que le demos permisos para rea-lizar las tareas de serialización; en par-

ticular, debemos asignar un valor ver-dadero a SerializationFormatter, talcomo vemos en el listado 8.

Como vemos en el código del lista-do 6, el método GetObjectData se encar-ga de almacenar los valores que quere-mos persistir en la serialización, peroresulta evidente que debemos tener elcódigo correspondiente en el procesode deserialización, es decir, asignar a loscampos correspondientes los valoresanteriormente almacenados. Ese pro-ceso de asignación de los datos a loscampos lo haremos por medio de unconstructor especial que “obligatoria-mente” tenemos que definir en las cla-ses que implementen la interfaz ISeria-lizable. Ese constructor recibe dosparámetros del mismo tipo que el méto-do GetObjectData, y la acción que debe-mos realizar en el constructor es preci-samente la de obtener los valores pre-viamente almacenados. En el listado 9vemos cómo recuperar esos datos.

Lo que debemos tener en cuenta esque los constructores no forman partede las interfaces, por tanto, si no defi-nimos ese constructor (el cual no deberíaser público, y se recomienda que seaprotegido para que las clases derivadaspuedan accederlo), recibiremos un erroren tiempo de ejecución, no en tiempode compilación, ya que el compilador

<SecurityPermission(SecurityAction.Demand, SerializationFormatter:=True)> _Private Sub GetObjectData( _

ByVal info As SerializationInfo, _ByVal context As StreamingContext) _Implements ISerializable.GetObjectData

info.AddValue(“elNombre”, Nombre)info.AddValue(“elEmail”, Email)info.AddValue(“laFecha”, m_Fecha)

End Sub

Listado 7. Definición del método GetObjectData en Visual Basic

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]

void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context)

{

Listado 8.Atributo de permisos de seguridad para realizar la serialización

[Serializable]class Colega : ISerializable{

... resto del código de la clase ...

#region ISerializable Members

void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context)

{info.AddValue(“elNombre”, Nombre);info.AddValue(“elEmail”, Email);info.AddValue(“laFecha”, m_Fecha);

}

#endregion}

Listado 6. Definición parcial de la clase Colega que implementa ISerializable

dotN

etM

anía

<<

46

dnm.inicio.fundamentos<<

solo comprobará si el método estáimplementado, pero no sabe nada deque la clase deba implementar el cons-tructor especial.

Según se indica en la documenta-ción, el método GetObjectData puede serllamado más de una vez cuando se creael objeto; por tanto, el código que gene-re ese método siempre debe producir elmismo resultado.

Herencia en clases que implementan ISerializableSi usamos una clase que implementa lainterfaz ISerializable la usamos comobase de otras clases, en la clase deriva-da (además de asociar también el atri-buto Serializable) debemos asegurar-nos de llamar al constructor de la clasebase pasándole los parámetros del cons-tructor especial. Lo mismo es aplicableal método GetObjectData: antes de rea-

lizar ningún tipo de asignación debe-mos llamar al método de la clase basepara que se encargue de inicializarcorrectamente todos los datos de la cla-se base. Recordemos que al deseriali-zar las clases que implementan ISeria-lizable al único constructor al que sellama es al constructor especial; por tan-to, desde el constructor especial de laclase derivada debemos llamar al de laclase base. De la misma forma, al seria-

// Constructor protegido para asignar los valores a la claseprotected Colega(SerializationInfo info, StreamingContext context){

Nombre = info.GetString(“elNombre”);Email = info.GetString(“elEmail”);m_Fecha = info.GetDateTime(“laFecha”);

}

Listado 9. El constructor especial permite asignar los datos serializados

[Serializable]class Amigo : Colega{

public string Apellidos;public string Telefono;

... resto del código ...

// Constructor protegido para asignar los valores a la claseprotected Amigo(SerializationInfo info, StreamingContext context)

: base(info, context){

Apellidos = info.GetString(“Apellidos”);Telefono = info.GetString(“Telefono”);

}

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]

public override void GetObjectData( SerializationInfo info, StreamingContext context)

{base.GetObjectData(info, context);

info.AddValue(“Apellidos”, Apellidos);info.AddValue(“Telefono”, Telefono);

}}

Listado 10. Clase derivada de Colega que implementa ISerializable

Como podemos observaren el código mostrado, losnombres que usemos paraalmacenar los valores en elobjeto de tipo Serializatio-nInfo no tienen por qué serlos mismos que los de loscampos a los que hacen lareferencia; lo único impor-tante es que tanto en elconstructor como en elmétodo usemos los mismosnombres.

[ ]NOTA

Si usamos una clase que implementa ISerializablecomo base de otra, en la clase derivada debemos

asegurarnos de llamar al constructor de la clase base

dotN

etM

anía

<<

47

dnm.inicio.fundamentos<<

lizar un objeto se llama al método GetObjectData, ypor tanto debemos asegurarnos de que se llame almétodo correspondiente de la clase base.

En el listado 10 tenemos parte de la definición dela clase Amigo, derivada de Colega, en el que podemosver cómo debemos asegurarnos de que todo el pro-ceso de serialización se efectúa de forma correcta.

En el código del listado 10 debemos notar un parde cosas. La primera es lo comentado anteriormen-te: desde el constructor protegido de la clase llama-mos al de la clase base y desde el método GetOb-jectData hacemos una llamada al mismo método dela clase base, y en ambos casos debemos “almace-nar” los valores de las propiedades que esa clase defi-ne. Y es precisamente en la llamada al método GetOb-jectData de la clase base (y en la definición comopublic override) en la que debemos centrar la aten-ción, ya que para poder definir de esa forma el méto-do en la clase derivada, la definición mostrada en ellistado 6 no nos serviría. Por tanto, si la clase queestamos definiendo con ISerializable la vamos ausar como base de otras clases, debemos definir elmétodo GetObjectData como público y virtual, talcomo se muestra en el listado 11.

La forma de serializar (y deserializar) una clasederivada de otra serializable no cambia en nada, sal-vo por el tipo de datos utilizado, tal como vemos en

el listado 12. Como es natural suponer, el objeto pre-viamente guardado en el fichero al que apunta la varia-ble fic1 debe ser del tipo Amigo.

Comprobar el tipo de datos serializadoPara finalizar el artículo, vamos a ver un ejemplo decómo serializar una colección genérica, aunque (comopodemos comprobar en el listado 13), no tenemos quehacer nada especial, ya que todos los tipos de datosserializables se manejan de la misma forma.

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]

public virtual void GetObjectData( SerializationInfo info, StreamingContext context)

{info.AddValue(“elNombre”, Nombre);info.AddValue(“elEmail”, Email);info.AddValue(“laFecha”, m_Fecha);

}

Listado 11. El método GetObjectData de la clase base debe ser público y virtual

BinaryFormatter bf = new BinaryFormatter();

FileStream fs = new FileStream(fic1, FileMode.Open);

Amigo a1 = (Amigo)bf.Deserialize(fs);fs.Close();

Console.WriteLine(“{0}, {1}”, a1.Nombre, a1.Apellidos);

Listado 12. Recuperar un objeto de un tipo derivado

List<Colega> colegas = new List<Colega>();

colegas.Add(new Colega(“Paco”, “[email protected]”));colegas.Add(new Colega(“Pepa”, “[email protected]”));colegas.Add(new Colega(“Pedro”, “[email protected]”));

FileStream fs = new FileStream(fic2, FileMode.OpenOrCre-ate);

BinaryFormatter bf = new BinaryFormatter();bf.Serialize(fs, colegas);fs.Close();

Listado 13. Serializar una colección genérica de objetos de tipo Colega

dotN

etM

anía

<<

48

dnm.inicio.fundamentos<<

A lo único que debemos prestar atención es a lahora de “reconstruir” el objeto, ya que debemos hacerla conversión (cast) adecuada según el tipo de datosque hemos almacenado. Y si no sabemos con seguri-dad qué tipo de datos es el que se ha almacenado enel fichero, siempre nos queda el recurso de realizar elproceso de deserialización a una variable de tipo objecty comprobar el tipo que tiene, de forma que esa con-versión la hagamos de forma correcta. En el listado14 tenemos un ejemplo en el que comprobamos si elcontenido del objeto serializado es Colega o una colec-ción genérica de tipo List<Colega>.

Conclusiones

En el presente artículo hemos dado un repaso prin-cipalmente a la serialización binaria, o al menos a laforma de usar la serialización con las clases que imple-mentan IFormatter para realizar el proceso de seriali-zación y deserialización mediante los métodos Seria-lize y Deserialize, respectivamente. También hemosvisto cómo configurar nuestras clases para que el pro-ceso de serialización se realice como nosotros quere-mos que se haga, tanto por medio de atributos comousando la interfaz ISerializable.

En el próximo artículo veremos cómo utilizarlas clases que nos permiten realizar la serializa-ción XML, que es el sistema usado preferente-mente por los servicios Web y cuando queremosmantener la información basándonos en sistemasestandarizados.

Como de costumbre, en el ZIP con el código deejemplo de este artículo el lector encontrará las ver-siones tanto para Visual Basic como para C#. En esosproyectos, los numerados con números impares uti-lizan la clase BinaryFormatter y los numerados connúmeros pares utilizan la clase SoapFormatter.

static void deserializar(string fic)

{

FileStream fs = new FileStream(fic, FileMode.Open);

BinaryFormatter bf = new BinaryFormatter();

object o = bf.Deserialize(fs);

fs.Close();

if (o is List<Colega>)

{

List<Colega> colegas = (List<Colega>)o;

foreach (Colega c in colegas)

{

Console.WriteLine(c);

}

}

else if (o is Colega)

{

Colega c = (Colega)o;

Console.WriteLine(c);

}

}

Listado 14. Comprobación del tipo de datos que se ha serializado

La clase SoapFormatter no admite laserialización de colecciones genéricas,aunque sí de colecciones “normales”como ArrayList o Hashtable. [ ]NOTA

dotN

etM

anía

<<

49

De acuerdo, te ahorraré la enésima explicación delas siglas de AJAX. Asumiremos que es un equi-po de fútbol holandés o un héroe griego. Comotú, tengo un amigo que no está muy al tanto delas tecnologías Web. Tener amigos y colegas a losque les encanten las aplicaciones y tecnologías desoftware de escritorio no es nada para preocu-parse. El problema surge cuando esos amigos espe-ran llevar la razón con argumentos más que dis-cutibles. Uno de mis debates favoritos en estemomento es AJAX vs. aplicaciones de escritoriobasadas en Web (por ejemplo, ClickOnce, o apli-caciones WPF). Es como el debate popular delque nunca me libro entre manzanas o naranjas.Yo prefiero las naranjas. Tienen mucha vitaminaC y un agradable sabor agridulce.

Aparte de las metáforas de la fruta, AJAX yClickOnce son cosas distintas. En concreto, ¿quées ClickOnce? Es una tecnología de .NET 2.0para añadir mecanismos de instalación sencillospara las aplicaciones Windows. Con ClickOnce,instalar y ejecutar una aplicación es tan sencillocomo hacer clic en una página Web. La aplica-

ción que se activa, por tanto, es una aplicaciónWindows. Punto.

Lo mismo sucede con aplicaciones de nave-gador tipo Windows Presentation Foundation.Son esencialmente aplicaciones Windows quepueden ser albergadas dentro de un navegadorcomo Internet Explorer. Estas aplicaciones seejecutan en un entorno de confianza parcial, yno tienen acceso completo a los recursos delordenador. Por ejemplo, no pueden hacer ningúntipo de entrada/salida. Aunque se tiene la sensa-ción de que la aplicación se ejecuta en el nave-gador, se ejecuta dentro de un proceso separadodel propio del navegador. Desde un punto de vis-ta visual, sin embargo, parece como una aplica-ción WPF real, con animación, multimedia ygráficos avanzados.

Si eres nuevo en el trabajo con aplicacionesClickOnce y WPF, probablemente te pareceránmuy atractivas a primera vista, y son tecnologíasconvincentes. Pero, ¿dónde están las diferen-cias entre ClickOnce, WPF-de-navegador yAJAX?

Más cosas extrañas:esta vez de ASP.NET

Dino Esposito

He leído un poco sobre AJAX (sé bien lo que significa el nombre, no hace falta repetirlo) y mehe hecho una idea de sus capacidades y potencial. Incluso diría que AJAX potencia mi pasión,pero eso es algo personal.Pero no me hubiera imaginado que a la hora de explicar por qué AJAXes preferible a las tecnologías smart client tuviera tantas dificultades. Necesito la opinión de unexperto para demostrarle a mi colega que tengo razón.

todonet@qa

A los lectores parecen gustarles las cosas extrañas, o quizás es que las cosasextrañas son tan comunes que sorprenden a muchos desarrolladores.Así queeste mes volvemos sobre técnicas poco corrientes, pero que tienen un ele-mento común: la Web.

DDiinnoo EEssppoossiittooes mentor de SSoolliiddQQuuaalliittyy LLeeaarrnniinngg.. Esponente habitual en

los eventos de laindustria a nivel

mundial.Visite sublog en: hhttttpp::////wweebbllooggss..

aasspp..nneett//ddeessppooss.(ttooddoottNNeett..QQAA@@

ddoottnneettmmaanniiaa..ccoomm)

t to od d

o ot tN N

e et t. .q q

a a@ @

d do ot t

n ne et tm m

a an ni ia a. .c c

o om m

dotN

etM

anía

<<

50

dnm.todonet@qa<<

Los clientes de AJAX son aplicaciones Web. Losclientes ClickOnce son aplicaciones Windows Forms:aplicaciones .NET 2.0 con un conjunto de buenascaracterísticas en lo que se refiere a la instalación.Finalmente, las aplicaciones de navegador tipo WPFson aplicaciones .NET 3.0 extendidas por WPF quese ejecutan en un contexto especial (sandbox) en elentorno gráfico del navegador. ¿Son similares? ¿Sig-nifica eso que WPF es el asesino de las aplicacionesAJAX o Web?

Más allá del ruido, las aplicaciones Windows distri-buidas con ClickOnce, las WPF de navegador y las apli-caciones AJAX son opciones válidas para añadir un clien-te rico a un sistema empresarial. Dicho esto, cada unatiene su rol y su lugar. AJAX (y ASP.NET AJAX como

plataforma concreta) es para aplicaciones Web puras,tradicionales. Las otras son para aplicaciones de escri-torio. Lo primero, tendrás que decidir si quieres unaaplicación Web o Windows. Lo segundo, seleccionar latecnología que mejor encaje con tus necesidades. Pue-de ser AJAX o aplicaciones ASP.NET estándar. Puedeser Windows Forms o WPF. Finalmente, considera lasopciones de combinación. Se puede distribuir median-te ClickOnce una aplicación Windows o una WPF. Opuedes añadir capacidades WPF a AJAX para una inter-faz de usuario todavía más refinada y amigable.

De vuelta con las frutas, puedes tener manzanas,naranjas, plátanos y lo que quieras; incluso naranjasy manzanas al mismo tiempo. Pero no puedes decirque son la misma cosa.

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

He oído que Microsoft va a lanzar lo que hoy se llama WPF/E en un par de meses, más o menos parael verano. Para mí,WPF/E es el clon perfecto de un producto muy conocido para los desarrolladoresWeb:Adobe Flash. ¿Es esto así? ¿Qué piensa que sucederá en los próximos meses?

Dicho simplemente, ¿tu pregunta es si WPF destro-nará a Flash? Yo no soy un experto en programacióncon Flash, pero ambos parecen dos productos confuncionalidad similar, construidos a partir de una ideasimilar.

Desarrollado originalmente por Macromedia,Flash es ahora un producto de Adobe, al adquirir estacompañía a Macromedia el año pasado. Flash es unaherramienta multiplataforma que permite crear appletsespecíficos. Flash se caracteriza por gráficos vecto-riales interpretados gráficamente (rasterization) ysoporte de audio y vídeo (streaming) bidireccional.Además, dispone de un lenguaje de script denomina-do ActionScript a través del cual los desarrolladorespueden añadir lógica programable a los elementos delapplet.

¿Qué es WPF/E a su vez? Significa Windows Pre-sentation Foundation Everywhere y está pensado paraañadir capacidades propias de WPF (en realidad, unsubconjunto de ellas) a virtualmente cualquier plata-forma. WPF/E dispone de gráficos vectoriales, capa-cidades multimedia (sin necesidad de Windows MediaPlayer), streaming, y puede programarse medianteJavaScript. ¿Dónde está la diferencia? Simplemente,son competidores. Microsoft va a lanzar WPF/E conun bonito nombre nuevo en los próximos meses1, jun-to con una nueva herramienta de desarrollo, Expres-sion Web. Un applet WPF/E es un fichero XAML con

acceso a un subconjunto de las clases propias de WPF.Cada componente incluido en el código XAML pue-de ser referenciado por un guión de JavaScript y modi-ficado programáticamente.

Como Flash, WPF/E se basa en un plug-in. Actual-mente, es un objeto de soporte del navegador en elcaso de Internet Explorer y un plug-in para otros nave-gadores. El motor WPF/E consiste en una descargaseparada disponible hoy para plataformas Windowsy Mac. Flash se introdujo hace 10 años, y es utiliza-do habitualmente –de hecho, es un estándar de fac-to– para crear animaciones, publicidad y, últimamen-te, para enriquecer las aplicaciones Web. WPF/E nacecon los mismos objetivos. Flash y WPF/E son la mis-ma cosa, pero de compañías distintas. Podría presen-tarse como la representación por excelencia de lascompetencia empresarial. Tenemos un estándar esta-blecido que crece continuamente y un nuevo y boyan-te producto preparado para hacer su aparición.

Por su parte, WPF/E tiene la fuerza de WPF, lafamiliaridad de JavaScript, y –tal como se ha anun-ciado para su versión definitiva– un conjunto de con-troles para enlace a datos que favorecerán la progra-mación. Puedes usar WPF/E con distintos navega-dores (en la actualidad lo soportan IE, FireFox y Safa-ri) y no requiere .NET 3.0 como podría pensarse enun principio. El plug-in que se instala es auto-conte-nido, como en el caso de Flash.

1 Recientemente se ha anunciado el nombre: Silverlight

dnm.todonet@qa<<

dotN

etM

anía

<<

51

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.comEstoy en la fase de migración de una vieja aplicación Web desde ASP clásico a ASP.NET. Desafor-

tunadamente, no voy a tener el placer de reescribir completamente la aplicación en ASP.NET.Poralgún tiempo,el sistema viejo y el nuevo tienen que coexistir.Lo que me lleva al punto difícil: ¿cómopuedo compartir el estado de la sesión entre aplicaciones ASP y ASP.NET?

Cuando navego en general buscando información sobre contenidos de AJAX,a menudo me encuen-tro con el término REST. Cuando me centro en ASP.NET AJAX Extensions, sin embargo, no meaparece ninguna referencia a él. ¿Quién está equivocado? O, ¿quién tiene la razón?

Compartir el estado de sesión es un problema com-plejo. Fue una de las primeras preguntas que se plan-teaban hace algún tiempo, y todavía hoy sigue estan-do vigente, siete años después del anuncio de la pri-mera versión de .NET Framework. Recapitulemosbrevemente algunas de las diferencias entre ASP yASP.NET.

El estado de sesión es un diccionario de datos queASP almacena en la memoria del servidor Web y quepublica para ser manejado por el motor de scriptingmediante el nombre público de la sesión. De formasimilar, el estado de sesión es un diccionario de datosen ASP.NET y puede ser almacenado en una varie-dad de medios: memoria (predeterminado), memo-ria de un proceso externo o base de datos. EnASP.NET, el estado de la sesión es recuperado paracada petición y añadido al contexto HTTP que con-tiene la respuesta a la petición.

Como puede verse, los dos entornos manejan la sesiónen formas radicalmente distintas, con poco sitio para unafácil compartición. Para compartir datos, ambos entor-nos necesitan que su propio estado esté disponible. Estopuede conseguirse mediante envío directo o publicandola información. Puedes conseguir que ASP y ASP.NETse pasen esta información mediante un campo oculto, o,mejor todavía, cargándola a partir de una tabla de unabase de datos que usen en común. La segunda opción esfácil de implementar en ASP.NET y solo requiere alma-cenar el estado de la sesión en la base de datos. Editas elfichero web.config y está casi hecho. Simplemente, tie-nes que insertar algo de código al principio de cada pági-na que se conecte a la base de datos, ejecutar la consul-ta, y rellenar el objeto sesión con los datos apropiados.Esta aproximación al problema está exhaustivamente des-crita en el artículo: http://msdn2.microsoft.com/en-us/library/aa479313.aspx.

REST son las siglas de Representational State Transfer.Puedes leer más sobre el tema y objetivos en la direc-ción http://en.wikipedia.org/wiki/Representational_Sta-te_Transfer. El término REST se usa a menudo paradescribir cualquier servicio que transmite datos sobreHTTP, sin una capa de mensajería tal como SOAP yel seguimiento de sesión. La ecuación fundamental deREST es que cada operación solicitada a un servicio seidentifica con una URL, se invoca vía verbos HTTP,y, opcionalmente, se le califica después con un conjun-to de valores de cabecera. Los parámetros pueden serparte del cuerpo del mensaje. REST, por tanto se ase-meja a SOAP y a servicios del estilo RPC. REST es unode los más importantes y seguidos patrones de las apli-caciones AJAX, debido a su flexibilidad y facilidad demantenimiento. ¿Hay algo de REST en ASP.NETAJAX Estensions? Sí, hay algo. Pero, ¿dónde?

En realidad, los servicios que consume una apli-cación cliente ASP.NET AJAX son servicios estilo

RPC, pero con algunos principios REST imple-mentados internamente. Por eso, la mayor parte delos desarrolladores no se dan cuenta de su presencia.Debido a lo remoto del estilo RPC, los beneficios deREST se reservan para el framework y versiones pos-teriores. Lo que no significa que eso sea malo nece-sariamente. Haz una aproximación pragmática al pro-blema, y verás que dispones de una interfaz familiarde programación, y, con Visual Studio “Orcas”, herra-mientas ad hoc para autoría y depuración. Al final,hay unos cuantos principios de REST dentro deASP.NET AJAX, incluso si no resultan patentes paralos desarrolladores.

Deberías preocuparte por REST como un estilode arquitectura, si vas a crear tu aplicación AJAX sinASP.NET AJAX Extensions. Si no, simplementerecuerda crear servicios sin estado con un contratoclaro e impleméntalos vía ASP.NET Web Services oWCF, y no tendrás más problemas.

En la medida en que el tamaño de las aplicacionescorporativas crece, cobra una importancia cada vezmayor la necesidad de disponer de herramientas quenos permitan ejecutar periódicamente procesos deanálisis de nuestras aplicaciones que nos den la cer-teza de que la arquitectura de éstas sigue respon-diendo a los criterios bajo los que fueron diseñadasoriginalmente, y que nos permitan obtener indica-dores cuantitativos acerca de la calidad del códigoincorporado en dichas aplicaciones. NDepend 2.1,creado por Patrick Smacchia, reconocido arquitec-to de software y autor de diferentes libros sobre laplataforma .NET, es precisamente una herramientade este tipo. Mediante NDepend, los responsablesde proyectos y desarrolladores podrán obtener nume-rosas métricas que les darán una visión integral de lacomplejidad y calidad del código de sus proyectos.

Ediciones del productoEl producto se ofrece en dos ediciones diferentes:una versión de prueba que se descarga gratuitamente,ofrece menos posibilidades y puede ser utilizada solopara propósitos no comerciales, y la edición profe-sional, que brinda todas las facilidades disponiblesen el producto y se vende según un escalado de pre-cios por licencias.

Instalación y primer uso

Instalación

La instalación de NDepend es sencilla: basta condesempaquetar en un directorio el .ZIP que se des-

carga de la Web. En el caso de la edición profesio-nal, luego hay que colocar en ese directorio el fiche-ro de licencia que suministra el fabricante y que habi-lita la funcionalidad completa del producto.

El software

NDepend ofrece dos ejecutables diferentes: unaaplicación de consola que puede ser invocada desdela línea de comandos para ejecutar en lote un con-junto de acciones (especificadas en un fichero XMLque se conoce como “fichero de proyecto NDe-pend”) sobre un conjunto de ficheros fuente u obje-to, y una completa aplicación Windows Forms(Visual NDepend) que permite de una manera visualcrear nuevos proyectos (desde cero o a partir de pro-yectos de Visual Studio 2005), abrir proyectos NDe-pend existentes, generar una comparación (nuevaopción de la versión 2, que permite hacer un segui-miento de la evolución temporal del código fuente)o simplemente especificar los ensamblados compi-lados a analizar (figura 1). La aplicación visual seapoya en la aplicación de consola para la ejecuciónde los proyectos.

NDepend

Laboratorio.netOctavio Hernández

Octavio Hernándezes DevelopmentAdvisor de PlainConcepts, editor

técnico dedotNetManía y tutor

de campusMVP.Es MVP de C# desde2004, MCSD y MCT.

Nombre: NDependVersión: 2.1Fabricante: Patrick SmacchiaSitio Web: http://www.NDepend.com/Categoría: UtilidadesPrecios: -licencia: 299 EUR

-20+ licencias: 179 EUR c/u.

Ficha técnica

Este mes presentamos NDepend 2.1, una herramienta que permite analizartanto el código fuente como el código objeto (ensamblados) que componenuna aplicación .NET y generar diversos informes que facilitan una mejor com-prensión de la arquitectura y la evolución del código, así como una evaluaciónobjetiva de la calidad del mismo.

dotN

etM

anía

<<

53

dnm.laboratorio.net<<

Primer uso

La manera más simple de comenzara utilizar NDepend consiste en indicardirectamente uno o más ensambladosde código manejado a analizar. En esteartículo utilizaremos como “conejillo deIndias” a la aplicación de ejemplo Black-Jack, que se suministra como ejemplode iniciación a Visual C# Express1.

Si se especifica BlackJack.exe comoensamblado a analizar en el diálogo de lafigura 1 y se pulsa el botón “Ok”, se lanzaun proceso de análisis que produce comoresultado una pantalla como la que semuestra en la figura 2. En la siguiente sec-ción se describen las posibilidades que ofre-cen los diferentes paneles de esa ventana.

Descripción del producto

La ventana de resultados que generaNDepend permite obtener una gran can-tidad de información objetiva sobre labase de código que compone la aplica-ción. Esta ventana es altamente configu-rable, permitiendo por ejemplo cerrar,abrir, mover o maximizar cualquiera delos paneles en todo momento para unamejor visualización. Los principales pane-les que la componen (tomando comoreferencia la figura 2) son los siguientes:

• En la esquina superior izquierdatenemos el árbol de código, que pre-senta el contenido de los ensambla-dos organizado en una jerarquía deespacios de nombres, clases y sus res-

Figura 1. Opciones de inicio de NDepend

Figura 2.Visual NDepend en ejecución

1 http://msdn.microsoft.com/vstudio/express/visualcsharp/starterkit/default.aspx#blackjack

Novedades

Infragistics anuncia la primeralibrería de componentes WPF

Infragistics acaba de sacar al mer-cado NetAdvantage for WPF2007 Volumen 1, una librería decomponentes que extiende las posi-bilidades de la plataforma WPFmediante diferentes controles degran utilidad para el desarrollo deaplicaciones corporativas, comoxamDataGrid, una rejilla muy poten-te y flexible que ofrece caracterís-ticas como la edición de datos,visualización jerárquica y ordena-ción y agrupación de datos. Paramás información y descargas, visi-te http://www.infragistics.com/wpf.

Nevron anuncia la disponibilidadde .NET Vision Q4 2006

Nevron ha anunciado reciente-mente la disponibilidad de .NETVision Suite Q4 2006. Este paque-te de componentes de interfaz deusuario para Windows y la Web estácompuesto por tres librerías (quetambién se venden de forma inde-pendiente):• Nevron Chart (WinForms y

ASP.NET) – conjuntos decomponentes para la presenta-ción de gráficos comerciales.

• Nevron Diagram (WinFormsy ASP.NET) – conjuntos decomponentes para la genera-ción de diagramas.

• Nevron UI Suite (WindowsForms) – librería de controlesvisuales que extienden las posi-bilidades de los controlesincluidos de serie en .NET Fra-mework.

Más información y descargasen http://nevron.com.

En próximas ediciones de dotNet-Manía analizaremos estos productos.

noticias • noticias

pectivas propiedades, métodos yeventos. En principio, se muestrantanto los ensamblados seleccionadospor el usuario como aquellos de losque ellos dependen; pero podemosespecificar cuáles queremos que seanobjeto de análisis. Una segunda pes-taña de este panel permite mostrar elresultado de la ejecución de consul-tas (sobre lo que hablaremos a con-tinuación).

• Debajo del árbol de código tenemosel panel de detalles; en él se muestrala información sobre el elemento queseleccionemos en cualquiera de losotros paneles de la aplicación. Porejemplo, si en el árbol de códigoseleccionamos un método de una cla-se cualquiera (figura 3), en la venta-na de detalles se mostrarán las carac-terísticas básicas de ese método,además de un conjunto de métricasútiles asociadas a él, como la canti-dad de líneas de código o la comple-jidad ciclomática.

• En la esquina superior derecha tene-mos la vista de métricas. Este panel

presenta de una maneragráfica las clases que com-ponen la aplicación, y den-tro de ellas, los métodos,propiedades, campos otipos (según la característi-ca que estemos analizando)de todas esas clases. Paracada una de las caracterís-ticas anteriores (y no solopara los métodos), NDe-pend ofrece un conjunto demétricas relevantes (unas60 en total). Aunque, porsupuesto, los métodos sellevan la palma, porque sonen definitiva los que con-tienen el código objeto deanálisis. Si se están anali-zando los métodos, éstos serepresentarán gráficamente dentrode su clase utilizando áreas propor-cionales a los valores de la métricaseleccionada para cada uno de ellos.

• El siguiente panel es la vista de depen-dencias. Gracias a ella podremosobtener valiosa información relativaa las dependencias internas entre lasdiferentes partes de nuestro código.Por ejemplo, en la figura 4 puede ver-se cómo hay tres métodos en la claseDeck que utilizan la enumeraciónFaceValue. Esta información se pre-senta de manera textual en el panelde detalles, para que no haya duda

alguna acerca de la interpretación delos valores. También es posible obte-ner diagramas detallados, como el quese muestra en la figura 5.

• Por último, en la zona inferior dere-cha de la ventana tenemos el panelde consultas. En este panel se puedeespecificar el conjunto de consultasa ejecutar sobre el código del pro-yecto para detectar el cumplimien-to o violación de ciertas condicionesque puedan ser importantes para elarquitecto o desarrollador. En lasiguiente sección se describe con másdetalle esta posibilidad.

Figura 5. Detalle de la vista de dependencias

dotN

etM

anía

<<

54

dnm.laboratorio.net<<

Figura 3. Detalles de un método

Figura 4. La vista de dependencias

dotN

etM

anía

<<

55

dnm.laboratorio.net<<

El lenguaje de consultas CQL

La “joya de la corona” de este intere-sante producto es el hecho de queofrece un lenguaje, llamado CQL(Code Query Lenguage), mediante elcual se especifican las consultas a eje-cutar sobre el código fuente de la apli-cación para comprobar el cumpli-miento o violación de diferentesreglas. Gracias a esta característica, nosolo podemos utilizar las decenas dereglas que NDepend trae pre-progra-madas de antemano, sino que tambiénpodremos crear nuestras propiasreglas personalizadas. Esta posibilidadhace de NDepend un producto abier-to, que puede ser aplicado paramuchas más tareas que aquellas paralas que fue concebido originalmente.

El lenguaje CQL guarda cierto pare-cido con SQL. Por ejemplo, la siguien-te sentencia lista en orden descenden-te los diez métodos con mayor com-plejidad ciclomática (siempre mayorde 5) del código fuente:

WARN IF Count > 0 IN SELECT TOP 10 METHODS

WHERE CyclomaticComplexity > 5 ORDER BY CyclomaticComplexity DESC

Una mayor complejidad ciclomá-tica hace a los métodos más difícilesde comprender y mantener, lo quepuede indicar la conveniencia de divi-dirlos o reestructurarlos. En la figura6 se muestra el resultado de la consul-ta anterior. Este resultado se puedeexportar a HTML (figura 7), XML,Excel o texto. Es de señalar tambiénque caso de que se disponga del enla-ce al código fuente del proyecto, des-de NDepend se podrá abrir Visual Stu-dio 2005, mostrando en él directa-mente el código del método corres-pondiente.

Integración continuaLa arquitectura de NDepend (basadaen una aplicación de consola encarga-

da del análisis y generación de los infor-mes) facilita la integración continua deNDepend dentro de la cadena de gene-ración de los productos de software.De hecho, NDepend ya incorpora deantemano módulos para MSBuild yNAnt que hacen posible incorporar lageneración de los informes dentro delproceso de generación del productofinal, automatizando así la obtenciónde los datos que nos mantienen al díay nos alertan sobre cualquier posible

desviación en la calidad del código pro-ducido.

ConclusionesEn este artículo hemos intentado resu-mir las principales características deNDepend, un producto cuya adquisi-ción se rentabiliza rápidamente demuchas maneras diferentes. Estaherramienta le ayudará a comprendermejor el código fuente de sus proyec-tos, entender su arquitectura, auditarla calidad del código, detectar las posi-bilidades de refactorización y reduc-ción de la complejidad, documentarlos cambios producidos entre versio-nes y muchas otras tareas.

Figura 7. Exportación de resultados a HTML

Figura 6. Resultados de la ejecución de una consulta CQL

Referencias

Toda la documentación sobre lautilización de la aplicación, lasmétricas disponibles, la definicióndel lenguaje CQL, etc. está dispo-nible en la página Web del pro-ducto, http://www.NDepend.com.

❑ Deseo suscribirme a dotNetManía por un año (11 números) por un precio de 65,00€ IVA incluido. Si su dirección está fuera deEspaña consulte los detalles en www.dotnetmania.com.

❑ Deseo que me envíen los números atrasados marcados según el precio de portada. Otros:

FORMA DE PAGO❑ Talón nominativo a nombre NETALIA, S.L.❑ Transferencia bancaria a nombre de NETALIA, S.L. a:

La Caixa - Número de cuenta 2100 4315 48 2200014696 (Indique su nombre en la transferencia)

❑ Domiciliación Bancaria (con renovación automática, previo aviso)Indique su número de cuenta:

❑ Tarjeta de crédito❑ VISA ❑ MASTERCARDNúmero de su tarjeta: Fecha de caducidad: / (imprescindible)

Firma y/o sello

a de de 2007

DATOS DE ENVÍO

CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

DATOS DE FACTURACIÓN (sólo si son distintos a los datos de envío)

CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Usted autoriza a la mecanizaciónde estos datos. El responsable ydestinatario de éstos es Netalia,S.L. Usted tiene derecho a acce-der a sus datos, modificarlos ycancelarlos cuando lo desee. Susdatos no serán cedidos en ningu-na de las formas posibles a terce-ras partes y no se utilizarán másque para el buen funcionamien-to de su suscripción a la revistadotNetManía y para informar-le de las actividades comercialesque realice la editorial Netalia,S.L. Si no desea recibir informa-ción comercial de dotNetManíamarque la casilla siguiente ❑Puede enviar sus datos por Fax al 91 499 13 64, o por teléfono al 91 666 74 77,

o por email a la dirección [email protected], o también puedeenviarlos por correo postal a la siguiente dirección:

Netalia, S.L.C/ Robledal, 13528529- Rivas Vaciamadrid (Madrid)

Oferta válida hasta el 31 de mayo de 2007 o hasta agotar existencias

❑ Nº23 (6,50€) ❑ Nº24 (6,50€) ❑ Nº25 (6,50€) ❑ Nº26 (6,50€) ❑ Nº27 (6,50€) ❑ Nº28 (6,50€) ❑ Nº29 (6,50€)

❑ Nº30 (6,50€) ❑ Nº31 (6,50€) ❑ Nº32 (6,50€) ❑ Nº33 (6,50€) ❑ Nº34 (6,50€) ❑ Nº35 (6,50€) ❑ Nº36 (6,50€)

Programación Web con Visual Studio y ASP.NET 2.0José Manuel Alarcón Aguín

Editorial: Krasis PressPáginas: 235Publicado: febrero/2007ISBN: 9788493548902Idioma: castellano

En el mundo del desarrollo en nuestro país, no hay muchos que desconozcan la yalarga trayectoria de Alarcón, con varios libros y más de 300 artículos publicados. Apropósito de la especialidad en la que es MVP (ASP.NET), José Manuel nos vuelcaen esta obra (de edición excelente) muchos de sus conocimientos sobre el tema, conel nivel de calidad que él acostumbra. Que no se engañe el lector por la extensión deesta obra: un libro no es más válido por su cantidad sino por su calidad. Felices quie-nes saben decir mucho con las palabras justas.

El enfoque es hacia el programador que se inicia ahora en el desarrollo con ASP.NET2.0, pero los conocedores de la plataforma también agradecerán un repaso al fondoy a la forma, al orden y al estilo, a la estructura y al detalle. No creo que hiciera jus-ticia, ni pudiera describir la obra a través de una simple enumeración de sus conte-nidos: es mucho más justo que los vea el lector por sí mismo.

Profesional Visual Studio Team SystemJean-Luc David,Tony Loton, Erick Gunvaldson, Cristopher Bowen, Noah Coad yDarren JeffordEditorial: Anaya Multimedia - WroxPáginas: 784Publicado: 2006ISBN: 9788441521186Idioma: castellano

El lanzamiento de Visual Studio Team System ha sido uno de los acontecimientosmás importantes de Microsoft en el campo de las herramientas para la gestión delciclo de vida de las aplicaciones. Esta obra revisa todos los aspectos fundamentalesde ese conjunto de herramientas, pero con un nivel de detalle que le convierte real-mente en una referencia para los productos de esta suite. Además de analizar los 4“teams” que distingue el producto en sí (Arquitectos, Desarrolladores, Evaluadoresy Foundation), no se olvidan de la importancia de que todas esas labores sean abor-dadas desde un marco de trabajo que nos ayude a mantener las cosas bajo control:Microsoft Solutions Framework, con sus variantes para la programación ágil y parala mejora de procesos con principios CMMI. Una obra muy completa en su género.

biblioteca.net

nove

dad

es Bases de datos con SQL Server 2005 (castellano)

Solid Quality Learning. Editorial Anaya Multimedia. Págs.: 384. Publicado: marzo, 2007.

ISBN: 9788441521315.

AJAX Francisco Charte. Editorial: Anaya Multimedia. Pág.: 303. Publicado: febrero, 2007. ISBN:

9788441521346.

TEXTO: MARINO POSADAS

dotN

etM

anía

<<

58

desvánTanto va el cántaro a la fuente… el ordenador cuántico ya está disponible

(15 años antes de lo que esperaban los más optimistas)

Así es. En esta sección hemosido informando al lector delas —casi diarias— noveda-des que se iban produciendoal respecto. No obstante, en

mi opinión, la noticia hay que tomarla con la prudencia necesaria, aun-que su realidad es incontrovertible: la empresa D-Wave Systems hacíapública en una presentación a bombo y platillo en EE.UU. el pasado13 de febrero de 2007 (fecha histórica según ellos afirman), la disponi-bilidad del primer ordenador construido con algunos componentes basa-dos totalmente en los principios que rigen la Mecánica Cuántica. Exis-ten 4 posibles formas de abordar el problema: a) El ensamblado de áto-mos individuales atrapados mediante láseres b) Circuitos ópticos (cris-tales fotónicos) c) Diseños basados en semiconductores dopados1, y d)Electrónica de superconductores.

D-Wave ha utilizado esta últimatécnica, debido a su “factor multiplica-dor”: se pueden crear estructuras gran-des (hablando en términos atómicos),que se siguen comportando de acuerdocon las reglas cuánticas, y sin requerirel desarrollo de nuevas tecnologías. (Elprocesador utilizado en la solución con-tiene 16 Qubits, como se aprecia en laimagen adjunta). Según sus datos, se hanutilizado dos superconductores de alu-

minio y niobio, metales a temperatura ambiente, pero que forman “paresde Cooper” cuando se les enfría a temperaturas cercanas al cero absoluto.Los “pares de Cooper” son bosones (tienden a ocupar el mismo espaciofísico) a diferencia de los electrones, que son fermiones (se comportan deacuerdo con el Principio de Exclusión de Pauli, que impide que dos de ellosse encuentren en el mismo lugar simultáneamente). Como, además, todosellos se encuentran siempre en el mismo estado, se consigue un efecto deamplificación, muy práctico y manipulable para el tratamiento posterior,sin perder sus características de resistencia eléctrica nula, y aislamiento defenómenos magnéticos exteriores.

¿Es esto aplicable al día a día de la computación? De momento, no,pero uno ya no se atreve a dar fechas. Por ahora, sus aplicaciones fun-damentales se centrarán en la simulación de procesos de la naturaleza(en Física, Meteorología, BioInformática, Simulación de Sistemas ySimulación Cuántica), donde las ecuaciones a resolver se vuelven inma-nejables a partir de un pequeño número de variables, como sucede conla Función de Onda de Schroedinger, a partir de unos 30 electrones.En este sistema el crecimiento de la complejidad de un problema no esexponencial, sino lineal, permitiendo cálculos que ahora están muy porencima del más potente de los ordenadores. En este contexto, una delas dificultades estriba en el propio planteamiento del problema, paralo que se utilizan varios niveles de abstracción y se han seleccionadodiversos lenguajes de programación en sus implementaciones entre losque destaca uno (solo ese) que nos resulta muy familiar: SQL. Para másdatos, visitar la web de la empresa (en inglés): www.dwavesys.com.

Marino Posadas

Application Compatibility - The 30 minute checklist esun documento disponible en http://blogs.technet.com/ask-perf/archive/2007/04/17/application-compatibility-the-30-minu-te-checklist.aspx, que nos permite comprobar si nuestra apli-cación puede sufrir algún problema de compatibilidad al serejecutada desde Windows Vista. Recomendable antes deponer aplicaciones en producción.

Los 19 pecados de la seguridad en elsoftware (“Sins of Software Security”)es un interesante documento publica-do en “Coding Horror”, que abordatípicos problemas de seguridad másallá de un lenguaje concreto, e inclu-so de una plataforma dada. No estaríamal un repaso previo a la construc-ción de una aplicación, para los que no quieran o no se atre-van a profundizar en las necesidades que otros marcos dedesarrollo seguro como MSF/Threat Modelling ofrecen.Se puede descargar de http://www.codinghorror.com/blog/archi-ves/000841.html.

Query Application: utilidad paraobtener un montón de datos técnicosde Internet, pero con una sola herra-

mienta. Desde conversores de IP a DNS, hasta Whois y Fingerintegrados. Disponible desde http://www.leeos.com/query_appli-cation.html.

En el conocido sitio SourceFor-ge.NET puede encontrarse la utili-dad DOSBox DOS Emulator, paraaquellos nostálgicos que quieran ejecutar sus viejos progra-mas o juegos de MS-DOS pero tengan problemas bajoXP/Vista. Se puede descargar de http://sourceforge.net/pro-jects/dosbox.

Sitio Mike Woodring

Asociado al conjunto de blogspublicados en PluralSight, Mike es un experto en códi-go .NET al más bajo nivel. Muchas cosas sobre depu-ración y manejo de recursos básicos de la plataforma.http://pluralsight.com/blogs/mike.

También es recomendable una visita a un viejo conoci-do y popular autor de obras de bajo nivel en EE.UU.,Keith Brown, que tiene su blog publicado en el mismoespacio: http://pluralsight.com/blogs/keith.

documentos en la red

sitios del mes

utilidades del mes

noticias.noticias.noticias.noticias

1 Consisten en la inclusión de átomos de otros elementos dentro de su estruc-tura cristalina, lo que les confiere propiedades especiales.