dotnetmanía - sergiogonzalezc.files.wordpress.com · miembro del equipo de desarrollo de c#...

60
Eventos en XAML. El enrutador que los enrute…• Atributos, aspectos y cómo entretejer código desde Visual Studio para hacer AOP en .NET (y II) • Introducción a los patrones de diseño • Sobrecarga de operadores en Visual Basic 2005 Laboratorio BusyBoxDotNet, RichText to HTML y PDFRasterizer.NET TodotNet@QA Asíncrono es la clave Comunidades .NUGG (.Net User Group Galicia) dedicada a los profesionales de la plataforma NET Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System nº 34 febrero 2007 6,50 dotNetManía www.dotnetmanía.com entrevista Karen Liu Miembro del equipo de desarrollo de C# dotNetManía Actualizando ASP.NET 2.0 con Microsoft AJAX ASP.NET Extensions

Upload: trinhdung

Post on 18-Oct-2018

224 views

Category:

Documents


0 download

TRANSCRIPT

Eventos en XAML. El enrutador que losenrute…• Atributos, aspectos y cómoentretejer código desde Visual Studio parahacer AOP en .NET (y II) • Introducción a lospatrones de diseño • Sobrecarga deoperadores en Visual Basic 2005

LaboratorioBusyBoxDotNet, RichText to HTML yPDFRasterizer.NET

TodotNet@QAAsíncrono es la clave

Comunidades.NUGG (.Net User Group Galicia)

dedicada a los profesionales de la plataforma NET

Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows Systemnº 34 febrero 2007 6,50 €

dotNetManíawww.

dotne

tman

ía.co

m

entrevistaKaren Liu

Miembro del equipo de desarrollo de C#

dotNetManíaActualizando ASP.NET 2.0 con

Microsoft AJAX ASP.NET Extensions

dotN

etM

anía

<<

3

Bienvenido al número 34, de febrero de2007, de dotNetManía.

Después de un tiempo sin noticias deOrcas, por fin tenemos la CTP de ene-ro, que es la esperada CTP de diciembre,que parece encaminarse lentamente a surampa de lanzamiento. Y viene con unalarga lista de novedades que podrá encon-trar en la sección de noticias.

El artículo de portada de este mes espara “Actualizando ASP.NET 2.0 conMicrosoft AJAX ASP.NET Extensions”de Miguel Jiménez, aprovechando ellanzamiento de la primera versión delproducto, que antes conocíamos gené-ricamente como Atlas. Y ¡qué difícil senos empieza a poner seguir la línea delproducto!, con las distintas licencias deuso del código fuente que se entrega, ycon las distintas partes que lo compo-nen, en un producto en continuo desa-rrollo y crecimiento, realmente dinámi-co. Recomendable, muy recomendable.

Sin duda, el mes de enero pasado hasido el mes para Ajax y Orcas. Con elpermiso de Windows Vista, Office 2007,MOM 2007...

Publicamos una entrevista a KarenLiu, del equipo de desarrollo del len-guaje C#, en Redmond, y a la que abor-damos en el pasado Tech-Ed 2006 deBarcelona. No era de las personas“entrevistables”, pero aquí está.

Quiero dar la bienvenida a Hora-cio N. Hernández, un jovencísimo yprometedor autor al que le da la alter-nativa el maestro Guillermo “Guille”Som, prestándole su sección dnm.ini-cio. Su trabajo “Sobrecarga de opera-dores en Visual Basic 2005” es un buencomienzo. Guillermo aprovecha estaspequeñas vacaciones que le da Horaciopara colaborar generosamente con elproyecto Hospital DotNet que están

poniendo en marcha desde DotNet-Solidario (www.dotnetsolidario.com).Especialmente si usted tiene una pági-na Web, puede colaborar con esteambicioso proyecto solidario sin ningúnesfuerzo. Por favor, consulte la páginadel proyecto. El artículo, a todo esto,es muy recomendable: “Eventos enXAML. El enrutador que los enrute…”El Guille en su línea.

También quiero dar la bienvenidaformal a José Luis Latorre, que aun-que el mes pasado ya nos mandó su auto-presentación del grupo de usuarios deBarcelona, es en este mes cuando nosmanda su primer artículo técnico:“Introducción a los patrones de diseño”.Publicar de forma más o menos regulardiseccionando los distintos patrones dediseño es una asignatura pendiente deesta revista. José Luis amenaza conhacerlo. !Ustedes son testigos!

Después de tres años, nos hemosdecidido a hacer una pequeña reformaa esta revista, una simple manita de pin-tura, que ya se nos estaba amarilleando,sin más pretensión que la de darle unaspecto renovado. En lo fundamental nocambia prácticamente nada. Espero quele guste.

Si usted es suscriptor, deberá teneren sus manos el sexto cuaderno técnicode dotNetManía, “Programación conSharepoint 2007”, de Gustavo Vélez.Como ya ocurrió con el anterior, y comoocurrirá con el siguiente, este libro pue-de tenerlo gratuitamente gracias, ademásde nuestro esfuerzo, al patrocinio deMSDN España, cuya labor de divulga-ción de las tecnologías de Microsoft paradesarrolladores es realmente encomia-ble y un ejemplo para otros fabricantes.

Espero que lo presentado y lo que lequeda por leer sea de su agrado.

Orcas y Ajax,protagonistas

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 34 • Febrero 2007Precio: 6,50€

EditorPaco Marín ([email protected])

Redactor jefeMarino Posadas([email protected])

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

RedacciónAntonio Quirós, Dino Esposito, Guillermo'Guille' Som, José Manuel Alarcón, LorenzoPonte y Miguel Katrib (Grupo Weboo)

Colaboradores habitualesBraulio Díez, Carlos Quintero, Eladio Rincón,Jorge Serrano, José Miguel Torres, IvánGonzález, Luis Miguel Blanco, Pepe Hevia,Salvador Ramos y Sergio Vázquez

Empresas ColaboradorasAlhambra-EidosRaonaSolid Quality Learning

Además colaboran en este númeroHoracio N. Hernández, José Luis Latorre,Juan Blázquez, Miguel Jiménez, y YamilHernández

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

IlustracionesYamil Hernández

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

sumario 34

4

Entrevista a Karen Liu 8-9Karen Liu pertenece al equipo de desarrollo del lenguaje C#, en Redmond, y está encargada dela optimización de ciertas características de la interfaz de usuario dentro del editor de VisualStudio 2005, en lo que se refiere a este lenguaje. Aunque no figuraba entre las“entrevistables” en el pasado Tech-Ed 2006 de Barcelona, Karen fue tan amable de acceder anuestra invitación, aunque fuese durante unos pocos minutos.

¿Riesgos?, ¿qué riesgos? 10-11Identificar, planificar y controlar los riesgos en que podemos caer cuando desarrollamossoftware es una labor que presenta una importancia trascendental y, desde luego, superior a laque habitualmente solemos darle. Como ya he mencionado en otras múltiples ocasiones, losfallos técnicos en los proyectos de software son, tradicionalmente, menor causa de problema quelos aspectos no tecnológicos que rodean a dicho proceso.

Eventos en XAML.El enrutador que los enrute… 12-16Con la llegada de XAML y las aplicaciones para Windows Presentation Foundation (WPF) hancambiado ciertos conceptos en la programación para el entorno .NET, y los eventos no son unaexcepción a este cambio. De hecho, ahora debemos cambiar un poco el chip para dejar paso a loseventos enrutados (routed events), y en este artículo veremos qué son, cómo funcionan y lo másimportante: cómo utilizarlos.

Atributos,aspectos y cómo entretejer código desde Visual Studio para hacer AOP en .NET (y II) 18-23

En nuestra entrega anterior presentamos los tipos de aspectos que podemos colocar en nuestrocódigo C# basándonos en atributos .NET. En esta segunda parte, vamos a ver cómo hacer queVisual Studio entreteja el código para aplicar la funcionalidad de los aspectos.

Actualizando ASP.NET 2.0 con Microsoft AJAX ASP.NET Extensions 24-33Algunas cosas vienen y van, como las estaciones, pero siempre permanecen. Este es el caso deJavascript, un lenguaje odiado por muchos y amado por otros tantos, siempre presente en elmundo del desarrollo Web. Cuando ya parecía que había sido excluido de la escena, reaparececon más fuerza que nunca gracias a AJAX. Sin embargo, aunque parezca el buque insignia deAJAX, existen alternativas más sencillas de utilizar donde este lenguaje queda relegado asituaciones puntuales en las que se requiera un control muy específico.

Introducción a los patrones de diseño 34-38¿Para qué inventar una solución si ésta ya existe? Básicamente, esa es la premisa que siguenlos patrones de diseño y que tantos arquitectos han adoptado. Seguido os introducimos de llenoen ellos y os proponemos cambiar vuestro punto de vista en el a veces complejo mundo de laarquitectura de software.

Técnicas de ofuscación de filtros de correo.El éxito del spam 40-43Pocos son los usuarios que, manteniendo una cuenta de correo activa en Internet, no hayanexperimentado en sus propias carnes el incordio constante y diario de recibir multitud demensajes con peregrinas ofertas. Cuando no es el método definitivo para hacersemultimillonario, es la oferta de milagrosos fármacos de toda índole, cuando no otros contenidosmás procaces. Mensajes que parece imposible detener.

Sobrecarga de operadores en Visual Basic 2005 44-48En el número 9 de esta revista se incluyó un artículo acerca de cómo llevar a cabo la sobrecargade operadores en C#. Por aquellos tiempos, la sobrecarga de operadores estaba vetada para losprogramadores de Visual Basic .NET, debido a que el equipo de desarrollo del lenguaje no pudoincluirla por razones de tiempo. Afortunadamente, con la llegada de Visual Studio 2005 yapodemos contar con esta funcionalidad.

dnm.comunidad.net 50-51.NUGG (.Net User Group Galicia)

dnm.laboratorio.net 52-53BusyBoxDotNet, RichText to HTML y PDFRasterizer.NET

dnm.todotnet.qa 54-56Asíncrono es la clave

dnm.biblioteca.net 57Inside Microsoft SQL Server 2005: T-SQL Querying Programming .NET Components

dnm.desvan 58

Microsoft ha puesto a disposición de los desarrolla-dores la CTP de enero de 2007 de Orcas, la próxima ver-sión de Visual Studio que permitirá desarrollar rápida-mente aplicaciones que ofrezcan las experiencias de usua-rio más avanzadas y que aprovechen todas las ventajas deWindows Vista y 2007 Office System. Puede descargar-la desde http://www.microsoft.com/downloads.

Novedades en la CTP de Orcas de enero de 2007:

Lenguajes y sus librerías de soporte• Soporte para las características de C# 3.0: esta CTP

implementa todas las características del lenguaje C#3.0 que ofrecía la CTP de LINQ de mayo de 2006: - Expresiones de consulta.- Inicializadores de objetos y colecciones.- Métodos extensores.- Inferencia de tipo de variables locales y tipos anónimos.- Lambdas asociadas a delegados y árboles de expresiones.

• Soporte para las características de VB 9.0: esta CTPimplementa todas las características del lenguaje VB9.0 que ofrecía la CTP de LINQ de mayo de 2006:- Expresiones de consulta.- Inicializadores de objetos y colecciones.- Métodos extensores.- Inferencia de tipo de variables locales.- Tipos anónimos.

• LINQ to Objects- La API de LINQ to Objects permite consultas sobre cual-

quier colección .NET, como arrays y listas genéricas.

• LINQ to XML (XLinq)- Se han añadido nuevas funcionalidades al soporte ya

existente en la CTP de octubre de 2006, como laposibilidad de aplicar transformaciones XLST y vali-dación basada en esquemas a árboles XLinq.

Acceso a datos• Nuevas API de acceso a datos, incluyendo el Marco de

entidades de ADO.NET y LINQ to ADO.NET.- Mediante el Modelo de datos de entidades, los desa-

rrolladores podrán diseñar modelos que reflejen losconceptos que maneja la aplicación, en vez de tener quemapearlos a las construcciones disponibles en la basede datos relacional. Una vez que el modelo esté listo, lapotente API del Marco de entidades de ADO.NETpodrá utilizarse para manipular los datos como clases.NET o como un conjunto de filas y columnas.

- ADO.NET se integra completamente con LINQ yofrece varias API para utilizar LINQ en diversos esce-narios: LINQ to SQL permite el acceso directo a lastablas de la base de datos desde el entorno de pro-gramación, LINQ to Entities permite utilizar LINQsobre modelos EDM, y LINQ to DataSet permiteaplicar toda la potencia expresiva de LINQ sobreobjetos DataSet.

Otras librerías• Soporte para la gestión avanzada de add-ins y sus domi-

nios de aplicación.- Se han añadido clases auxiliares para gestionar el

tiempo de vida de los add-ins y de los dominios enque ellos residen.

• Soporte de servicios para autenticación, roles y perfiles.- Los servicios de aplicación para autenticación, roles

y perfiles de ASP.NET 2.0 no están en principio ata-dos a ASP.NET y pueden ser utilizados en otros tiposde aplicaciones, como clientes inteligentes.

• Nuevas clases para la encriptación y firma digital median-te el algoritmo de Curva elíptica de Diffie-Hellman.

• Un nuevo escuchador de trazas de alto rendimientoque graba los eventos en el ETW (Event Tracing forWindows) de Windows Vista.

• Un nuevo tipo numérico que ofrece soporte para núme-ros muy grandes (más allá del rango de Int64).

Otras características

• Intellisense para Jscript.- El formato de código y soporte Intellisense para el

código Jscript ofrecerá a los desarrolladores Web unaexperiencia de edición mucho más rica.

• Mejoras en ClickOnce.- Esta CTP permite el despliegue ClickOnce de apli-

caciones WPF y ofrece soporte para otros nave-gadores.

• Soporte de diseño y ejecución para Office 2007 (inclu-yendo Outlook 2007).- Los desarrolladores podrán crear add-ins para Offi-

ce 2003 y 2007 con una experiencia consistente.

• SQL Server Compact Edition (SSCE) - SSCE ofrece un almacén relacional local ligero y embe-

bible para clientes con conexión ocasional.

dotN

etM

anía

<<

6

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

CTP de Orcas de enero de 2007

dotN

etM

anía

<<

7

dnm.directo.noticias<<

Microsoft ASP.NET AJAX 1.0 ha sidoliberado para su libre descarga, al tiem-po que se han presentado importantesactualizaciones del sitio de la comunidadhttp://ajax.asp.net, haciéndolo coincidircon este lanzamiento. ASP.NET AJAX1.0 es un producto completamente sopor-tado por Microsoft y está apoyado poruna licencia estándar de soporte de 10años (con soporte telefónico 24 horas aldía, 7 días a la semana). Todas las carac-terísticas de ASP.NET AJAX 1.0 estaránintegradas directamente dentro de la pró-xima versión de Visual Studio.

Microsoft ha puesto a disposiciónpública todo el código fuente bajo el nom-bre ASP.NET AJAX 1.0 Source Rele-ase. Incluye el código de la AJAX Library,la parte cliente, bajo licencia MicrosoftPermissive License (MS-PL), que da alos desarrolladores derecho a modificary personalizar la librería libremente, asícomo distribuir la versiones derivadas deesta librería Javascript, incluso con propó-sitos comerciales. También incluye, paraayudar con la depuración y el desarrollo,todo el código fuente de ASP.NET AJAX1.0 del lado de servidor; éste bajo licen-cia Microsoft Reference License (MS-RL), más restrictiva que la MS-PL.

La compañía ha lanzado tambiénuna actualización de AJAX ControlToolkit –proyecto de código compar-tido, desarrollado tanto por Microsoftcomo por desarrolladores indepen-dientes– para el nuevo ASP.NET AJAX1.0, con más de 30 controles. Todo elcódigo fuente se entrega completa-mente gratis, con derechos para reuti-lizarlo y modificarlo. Puede visitar lapágina de estos controles en CodePlex:http://www.codeplex.com/Wiki/View.aspx?ProjectName=AtlasControlToolkit.

Por último, Microsoft también hapuesto a disposición de los desarro-lladores el ASP.NET 2.0 AJAXFutures January CTP, que aportacaracterísticas que extienden el núcleode la plataforma ASP.NET AJAX 1.0(requiere tener instalado previamen-te ASP.NET AJAX 1.0) que está bajolicencia go live.

Así lo ha informado Scott Guthriedesde su blog en http://weblogs.asp.net/scottgu.

Para descargar cualquiera de estasnuevas versiones, así como demos,ejemplos con código fuente, documen-tación, vídeos, foros, blogs, etc., visitehttp://ajax.asp.net.

ASP.NET AJAX 1.0

Con Windows Presentation Foundationy el nuevo Lenguaje Extensible de Mar-cas para Aplicaciones (XAML) será fácilejecutar asombrosas visualizaciones en3D de tus aplicaciones y animaciones. Losnuevos servicios Windows Live™ y losVista Sidebar Gadgets permiten la gene-

ración de miniaplicaciones personaliza-das. El Panel es el lugar donde reunirmuestras de las nuevas experiencias delusuario y explicar cómo fueron genera-das. Si lo desea, puede presentar su pro-yecto inscribiéndose en http://www.micro-soft.com/emea/msdn/thepanel/eses.

Desde hace unos días están publicadas enMSDN las traducciones de diversos docu-mentos previamente solo disponibles eninglés. En particular, están disponibles tra-ducciones al castellano de la documenta-ción preliminar de C# 3.0 y LINQ, reali-zadas por nuestro editor técnico OctavioHernández:

• Especificación de C# 3.0.• El proyecto LINQ.• Operadores de consulta estándar de

LINQ.• Acceso a datos de próxima generación• Presentación técnica de ADO.NET vNext.• El marco de entidades de ADO.NET

vNext.

También han sido publicadas dos traduccio-nes relacionadas con WCF realizadas por nues-tro columnista César de la Torre:• Aprende el ABC de WCF.• Visión global de la arquitectura de WCF.Puede acceder a estos documentos a través dela URL:http://www.microsoft.com/spanish/msdn/articulos/architec/fecha/enero.mspx.

Nuevas traducciones al castellano en MSDN

eevveennttooss

eevveennttooss

eevveennttooss

eevveennttooss

eevveennttooss

eevveennttooss ¿Qué trae .NET 3.0?

En estas sesiones técnicas tendremos la opor-tunidad de ver en detalle las nuevas funcionali-dades de Microsoft .NET Framework 3.0: Win-dows Presentation Foundation, Windows Com-munication Foundation, Windows WorkflowFoundation, además de las novedades de Share-point 2007. Fechas:

6 de febrero Vic (Barcelona).8 de febrero Murcia.

21 de febrero Torrelavega (Cantabria).22 de febrero Huelva.

MSDN Talleres

Los MSDN Talleres son jornadas gratuitasdirigidas a personal técnico, moderadas y dirigi-das por expertos en tecnología Microsoft. Tie-nen como fin compartir experiencias y resolverdudas, de forma totalmente interactiva con ungrupo reducido de desarrolladores.

Madrid 23 de febrero• MSDN Taller Windows Vista y Office

2007. Novedades para el Desarrollador.• MSDN Taller: Desarrollo con BizTalk Ser-

ver 2006.

Training Days:Seguridad en Aplicaciones Web

Los nuevos Training Days están orientadosa analizar las tecnologías, herramientas y proce-dimientos que se deben utilizar para la creacióny el mantenimiento de aplicaciones Web segu-ras. Las plazas son limitadas.

• Madrid 26 de febrero.• Navarra 27 de febrero. • Torrelavega (Cantabria) 28 de febrero.

The Panel.Creating front end experiences

una presentación de ti mismapara nuestros lectores? Es una pregunta ya habitualen nuestras entrevistas…

Por supuesto. Soy program manager del IDE de C# enVisual Studio, allá en Redmond, y me encargo de la opti-mización y mejora de la experiencia de usuario de cara aldesarrollador de C#.

En tu última presentación, todos estábamos literal-mente embobados escuchándote y viendo las demos. ¿Pue-des hacernos un breve resumen de su contenido?

Claro. La presentación fue acerca de característicasadicionales, trucos y consejos, respecto a cómo conseguirque los desarrolladores sean más productivos utilizandoel IDE. Había muchos trucos, atajos de teclado, carac-terísticas que solo aparecen cuando se está realizando cier-to tipo de edición...

También, aspectos como la modificación o la propiaescritura del código, que en muchas situaciones puedenverse notablemente mejorados si conocemos estas posi-bilidades presentes en el entorno de edición. Igualmen-te, hay elementos muy importantes en la forma en que secomporta el depurador, y cómo podemos configurar esedepurador para que sea de auténtica ayuda en la edición.

entrevista a Karen Liu

Karen Liu pertenece al equipode desarrollo del lenguaje C#,en Redmond, y está encargadade la optimización de ciertascaracterísticas de la interfaz deusuario dentro del editor deVisual Studio 2005, en lo que serefiere a este lenguaje.Aunqueno figuraba entre las“entrevistables” en el pasadoTech-Ed 2006 de Barcelona,Karen fue tan amable deacceder a nuestra invitación,aunque fuese durante unospocos minutos.

<< ¿Puedes hacer

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

Ya sabes que la nueva versión ha inclui-do un buen número de mejoras en ladepuración, que se extienden a la posi-bilidad de definir cómo y con qué tipode herramienta de usuario desea reali-zarse una depuración en concreto.

Por eso decía que estábamos todospendientes de lo que hacías, porque haymuchas cosas que nos resultaban des-conocidas. ¿Por cierto, has estadomucho tiempo en el equipo de desa-rrollo de C#?

Más o menos, unos dos años.¿Has estado trabajando anterior-

mente con otros lenguajes como C++?Mi background viene, efectivamen-

te, de C++, pero también programabaen Java hace tiempo, así que ese tiposintaxis es con la que he convivido lamayor parte de mi carrera.

Pero yo he visto algunos trabajostuyos en Internet, donde se te vinculacon algún tipo de investigación en elcampo de la síntesis de imágenes, apren-dizaje artificial y otros...

¡Ah sí! Bueno, yo vengo delM.I.T., dentro del Media Lab. Allítrabajábamos en temas como Machi-ne Learning, y allí coincidí con otra detus entrevistadas –según me comen-tabas antes-, Nuria Oliver. Luego, elcambio desde allí a Microsoft fue algopositivo, aunque los ambientes erancompletamente distintos. Pero meapetecía volver a la costa oeste, por-que soy de California.

Resulta inevitable en este tipo detemática volver a preguntar sobre ladicotomía entre C++ y C#. ¿Cuál es tuopinión? Aunque dirás que C# es lomejor, claro…

Hemos hecho un montón de códi-go en C++. Para mí, C# dispone de unaserie de características muy avanzadas,como la plataforma administrada. Notienes que preocuparte por punterosperdidos y cosas así, pero, sobre todo,la experiencia de trabajar en C#, espe-cialmente lo que llamamos la “expe-riencia sintáctica”, es mucho más cómo-da que con C++.

Realmente, muchas de las cosas quehemos hecho en el entorno de ediciónde Visual Studio tienen que ver con qué

odemos hacer para que el desarrolladorpueda escribir mejor el código (en laforma, no en la calidad, claro, aunquetambién…). La refactorización tienemucho que ver con esta experiencia yes una de las características más impor-tantes de esta versión.

Ahora que hablas de refactorización,¿cómo es que esa característica no esta-ba incluida más que en C#, dentro deVisual Studio, y no aparecía disponiblepara Visual Basic?

Sucedió que había muchas cosasnuevas que queríamos incorporar en eleditor de esta nueva versión. Una deellas era la refactorización, pero inclu-so más importante era la característica“editar y continuar”. Es cierto que eramás fácil en C# precisamente por elhecho de ser sensible al caso (mayús-culas/minúsculas). Pero no puedo decir-te las razones por las que el equipo deVisual Basic no la incluyó por defecto.

También estarás al tanto de la apa-rición de las primeras CTP de la plata-forma XNA, para la programación dejuegos y multimedia, que utiliza exclu-sivamente C# como lenguaje…

XNA es un intento de conseguirmuchas cosas en una dentro de unaplataforma de programación multi-media. La primera con la que hemostenido que lidiar es con el rendi-miento, y podemos decir ahora queresulta bastante bueno. Como se tra-ta de un tipo de programas más com-plejo, y podíamos utilizar muchas delas cosas hechas para C#, en la betaactual se exige el uso de C# Express.Por una cuestión de accesibilidad a laherramienta por parte de muchosinteresados. Pero está todavía entran-do en fase beta, realmente.

De todas formas, ya existen bastan-tes ejemplos de juegos antiguos con-vertidos a esta plataforma, y hemospodido comprobar que el rendimientoes más que aceptable, aunque quedanmuchas cosas por depurar, claro. Aun-que de momento no se puede decir quesea una herramienta para la construc-ción de grandes juegos al estilo de losmás populares de grandes casas pro-ductoras.

¿Piensas que una de las cosas másatractivas de la plataforma XNA va a serla programación para pequeños disposi-tivos, como PDA, PocketPC, etc.

No sé hasta qué punto eso será real-mente una revolución, y, sobre todo,hasta dónde las dos plataformas deconstrucción pueden ser portables,supongo que se harán cosas, pero porel momento, no están ahí.

¿Nos puedes decir algo de lasnuevas características de C# en Orcas?¿De aquellas que más te gustan per-sonalmente, incluyendo LINQ, porsupesto?

Estamos haciendo los mayoresesfuerzos posibles para que el desa-rrollador de C# adopte LINQ de laforma más fácil y productiva posible.Una de las muchas cosas que tene-mos en mente, y en la que estamostrabajando ahora, es la compilaciónen background. Es una característicacompleja, en la que tenemos quetener en cuenta muchas cosas distin-tas, tanto en lo concerniente a la sin-taxis como al comportamiento delcompilador. Trabajando en este tipode características, a veces se presen-tan problemas difíciles y tenemos queevaluar el alcance que pueden tener.Pero ése es uno de nuestros objetivosactuales.

Observamos en tu ponencia algu-nas características del IDE que recor-daban postulados propuestos por la“Programación Intencional”, los sis-temas que se anticipan a las necesida-des del desarrollador…, ¿hay algo deeso aquí?

Pues no lo sé, supongo que sí. Perotodo va acerca de cómo podemos hacerpresente en todo momento la infor-mación que un desarrollador necesitaen el IDE, sin distraerlo de lo que essu tarea fundamental. Ese sería nues-tro “gran objetivo principal”. Y sí,algunas cosas pueden parecer sacadasde las ideas de la Programación Inten-cional, ya que ese es nuestro foco, real-mente. Supongo que estamos incor-porando aspectos de investigacióncomo los que te comentaba antes sobreMachine Learning. do

tNet

Man

ía<<

9

dnm.directo.entrevista<<

de desarrollo tenga un análisis que agluti-ne diversas técnicas tales como modelización de clases, casos deuso, etc., parece algo que todos estamos dispuestos a confesarque es, cuando menos, necesario. Pasar ya a que tenga plan decalidad, casos de uso de pruebas, etc. parece que, aunque nossuena como más prescindible, todos estamos dispuestos a con-fesar que lo haríamos en nuestras aplicaciones si tuviéramostiempo, pero ¿riesgos?, ¿qué demonios es eso?, ¿para qué quie-ro controlarlos en mi proyecto?

Pues es bien sencillo. Con la documentación técnica garanti-zo que mi proyecto hará lo que el cliente quiere que haga. Con losplanes de pruebas y calidad garantizo que eso que hago para micliente funciona como se espera que funcione. Cuando contrololos riesgos estoy añadiendo un nuevo nivel de fiabilidad a mis pro-yectos, de modo que intento arrojar luz sobre la incertidumbre,prever aquello que puede acontecer que modifique mis previsio-nes, intentar actuar sobre ello para mitigarlo y, por último, reali-zar planes de actuación para controlarlo si sucede.

El plan de riesgos es algo que típicamente se queda sinhacer en muchos proyectos y luego, cuando las cosas ocurren,no sabemos cómo actuar, no tenemos planes de acción, y elloredunda típicamente en retrasos y roturas de planificación queterminan por afectar a nuestros clientes. Pensemos en esa situa-ción típica donde nuestra planificación dice que desplegare-mos una aplicación en 20 delegaciones de una compañía a lolargo de 20 días viajando cada día a la siguiente una vez ter-minada la actual. Nuestro plan de riesgos debería prever lo quehacer si nos falla el coche (por ejemplo, tener alternativas detransporte público) o si alguna carretera está cortada (por ejem-plo, poder alterar el ritmo de las instalaciones e ir a otro lugar),etc. Si nadie ha pensado en este tipo de cosas al hacer la pla-nificación es seguro que surgirán los retrasos, ya que la posi-bilidad de la existencia de un riesgo es casi causa segura de quese dé realmente.

¿Riesgos?, ¿qué riesgos?

<<Que un proyecto

AAnnttoonniioo QQuuiirróóss escolaborador habitual

de ddoottNNeettMMaannííaa. Co-fundador de las revis-

tas clippeRManía,FOXManía y Algorit-mo.Actualmente es

director de operacio-nes en Alhambra-

Eidos.

Identificar, planificar ycontrolar los riesgos enque podemos caercuando desarrollamossoftware es una labor quepresenta una importanciatrascendental y, desdeluego, superior a la quehabitualmente solemosdarle. Como ya hemencionado en otrasmúltiples ocasiones, losfallos técnicos en losproyectos de softwareson, tradicionalmente,menor causa de problemaque los aspectos notecnológicos que rodeana dicho proceso.

opinión

Antonio Quirós

Pero, ¿cómo realizar un plan de ries-gos? Casi todas las metodologías nos dansu receta acerca de lo que tenemos quehacer, incluso existe algún software1 quenos ayuda a hacerlo. Si nos inclinamos,por ejemplo, por MSF, los pasos que nospropone para gestionar los riesgos son:

1) Identificar todos los posibles ries-gos que podrán ocurrir duranteel proceso.

2) Analizarlos y priorizarlos.3) Planificar la posible mitigación y

las acciones de contingencia.4) Chequear continuamente el pro-

ceso para detectar la aparición delos riesgos e informar cuando estosucede.

5) Controlar el riesgo a través delcorrespondiente plan de mitigación.

6) Aprender de lo ocurrido paramejorar en el futuro.

Para llevar a cabo todo este tra-bajo, lo esencial es que tengamos unasistemática adecuada que nos permi-ta identificar y catalogar de formacorrecta todos los riesgos. La tablaadjunta nos muestra el mínimo elen-co de atributos que deberíamos ano-

tar para cada uno de los riesgosencontrados.

Hay que mencionar también unpar de elementos clave en el controlde riesgos: se trata de los planes de con-tingencia y de mitigación. Por plan demitigación entendemos el conjunto deacciones que podemos llevar a cabopara tratar de evitar que un riesgo seproduzca o para incrementar nuestronivel de preparación en caso de pro-ducirse. Así, siguiendo con el ejemplodesarrollado en la tabla, un plan decontingencia debería contener accio-nes como tener una relación fluida conotros miembros de la dirección de lacompañía del cliente para que, en casode cambio del director de sistemas, labuena relación con otros facilitara laslabores de introducción con el nuevointerlocutor. Por plan de contingen-cia entendemos todo aquello que debe-mos ejecutar en caso de que la condi-ción del riesgo se haya producido ya.Siguiendo nuestro ejemplo, sería aque-llo que deberíamos hacer una vez cam-biado el director de sistemas; por ejem-plo, pedir al director general que nosfacilite el contacto a través de una pri-mera reunión.

Que una empresa tenga la costum-bre operativa de realizar acciones paracontrolar los riesgos es uno de los sig-nos de madurez más escasos entre lascompañías de software y, por tanto, unode los que denotan la fuerte capacidadde repetibilidad en el éxito de sus pro-yectos cuando se tiene.

dotN

etM

anía

<<

11

dnm.opinión<<

Que una empresa tenga la costumbre operativa derealizar acciones para controlar los riesgos es unode los signos de madurez más escasos entre lascompañías de software

Atributo Descripción Ejemplos

Identificador Código único que identifica a cadauno de los riesgos dentro de nues-tro catálogo.

Riesgo1, Riesgo2 …

Descripción Una descripción detallada del ries-go en cuestión.

Cambio del actual interlocutor porparte del cliente, el director de siste-mas de la compañía.

Condición Disparador que cuando se produ-ce pone en marcha nuestros meca-nismos de contingencia para solu-cionar los problemas que el impac-to del riesgo traería consigo.

Comunicación del interlocutor o dela compañía indicando que se va a pro-ducir el cambio.

Consecuencia Las acciones a llevar a cabo paraaminorar el impacto del riesgo.

a) Comunicación con la direccióngeneral del cliente.

b) Convocatoria inmediata de reu-niones con el nuevo director desistemas, etc.

Probabilidad Grado de posibilidad de que el ries-go catalogado se produzca.

Lo usual es medirla porcentualmente,por ejemplo, 40%.

Impacto Grado de incidencia que el riesgotendrá sobre nuestro proyecto.

Un sistema habitual es puntuar de 1 a10 en función del mayor o menorimpacto.

Exposición Grado de importancia del riesgo enfunción de su probabilidad y de suimpacto.

Típicamente, el producto de la pro-babilidad por el impacto.Así, un ries-go con bajo nivel de probabilidad,perocon un alto impacto debe tener unaexposición alta en nuestro sistema.

1 Puede verse, por ejemplo, el software PILAR asociado a Magerit, la gestión de riesgos que en paralelo a su metodología Métrica 3, tiene validada laadministración pública española. http://www.csi.map.es/csi/pg5m20.htm

dotN

etM

anía

<<

12

la descripciónde eventos enrutados (routed events). Se-gún la documentación del SDK deWindows, un evento enrutado es unainstancia de un evento que se propagapor un árbol de elementos relaciona-dos en lugar de apuntar a un solo ele-mento. Según esa misma documenta-ción, hay tres tipos de enrutamiento:bubbling (de burbuja), tunneling (de tú-nel) y directo. Con el enrutamiento bub-bling, el evento se propaga (“sube”) des-de el elemento que lo produce hasta laparte superior del árbol de elementos.Por otra parte, en el caso del enruta-miento tunneling esa propagación “ba-ja” desde la parte superior del árbol has-ta el elemento que produce el evento.

Por último, el enrutamiento directo nopropaga el evento en ninguna direccióny se comporta como los eventos “nor-males” a los que estamos acostum-brados.

Para comprender mejor estas nue-vas definiciones, debemos tener encuenta cómo funcionan o se compor-tan los elementos de una aplicaciónWPF, que como sabemos, en este tipode aplicaciones están definidos enXAML. Por regla general, los elemen-tos de una aplicación XAML suelen es-tar contenidos en otros elementos; dehecho, al igual que ocurre con las apli-caciones normales de Windows, siem-pre hay algún contenedor que “contie-ne” los controles, aunque sea el propioformulario, en el caso de las aplicacio-nes de Windows, o cualquiera de loscontenedores de las aplicaciones deWPF.

La diferencia de las aplicaciones ba-sadas en Windows Forms con las apli-caciones para WPF, es que, por ejem-plo, un botón no solo es un botón, yaque tal como se crean las aplicacionescon XAML ese botón puede contenerotros elementos, por ejemplo un blo-que de texto o una imagen, y a diferen-cia de las aplicaciones “normales”, esoselementos que contiene se pueden tra-tar de forma independiente. Pero en elcaso de ese botón compuesto, no ten-dría mucho sentido tratar cada uno delos eventos de los elementos que lo

HHoossppiittaall DDoottNNeett

Guillermo Som ha cedido los derechos de autor de esteartículo al proyecto Hospital DotNet. Este proyecto es unainiciativa del portal DOTNETSOLIDARIO que pretenderecaudar fondos para la creación de un hospital en una delas zonas más desfavorecidas del tercer mundo.

Usted puede colaborar con este proyecto.Visite la Weben www.dotnetsolidario.com para conocer los detalles.

<< Empecemos viendo

Guillermo “Guille” Somfirma solidaria

El enrutador que los enrute…Eventos en XAML

Con la llegada de XAML y las aplicaciones para Windows Presentation Foundation (WPF)han cambiado ciertos conceptos en la programación para el entorno .NET, y los even-tos no son una excepción a este cambio. De hecho, ahora debemos cambiar un poco elchip para dejar paso a los eventos enrutados (routed events), y en este artículo veremosqué son, cómo funcionan y lo más importante: cómo utilizarlos.

Guillermo “Guille” SomEs Microsoft MVP de Visual Basic des-

de 1997. Es redactor dedotNetManía, mentor de Solid Qua-

lity Iberoamericana, tutor de cam-pusMVP, miembro de Ineta SpeakersBureau Latin America, y autor de loslibros “Manual Imprescindible de Visual

Basic .NET” y “Visual Basic 2005”.http://www.elguille.info

dotN

etM

anía

<<

13

dnm.firma.solidaria<<

componen de forma independiente, si-no que nos resultaría más práctico tra-tarlos como un todo. En este caso loseventos enrutados nos pueden ser demucha utilidad, en particular los de ti-po tunneling, los que se producen pri-mero en la parte superior del árbol deelementos, en nuestro caso, el propiobotón. Veamos otros conceptos relacio-nados con estos eventos enrutados y có-mo detectarlos antes de que lleguen alelemento que realmente lo produce.

Los tipos de enrutamiento delos eventos XAML

En WPF cada evento se puede de-tectar de dos formas diferentes, segúnlo queramos interceptar antes de llegaral elemento que realmente lo produce(tunneling), en cuyo caso el nombre delevento va precedido de Preview, lo quenos da una idea de cuál es la intenciónde dicho evento: tener la posibilidad deinterceptarlo antes de que realmente seproduzca. Por otro lado tenemos loseventos bubbling, a los que no se añadeningún prefijo. Como regla general, to-dos los eventos de los elementos deWPF van en pareja, y por cada eventosuele haber uno previo y uno normal.Por ejemplo, la pulsación de las teclassuele detectarse con el evento KeyDown,evento de tipo bubbling (lo detectaría-mos en el control que lo produce) y elcorrespondiente de tipo tunneling esPreviewKeyDown (para detectarlo antesde que llegue al control). Aclarar queeste tipo de eventos emparejados tam-bién están disponibles en la versión 2.0de .NET Framework, aunque eviden-temente sin la misma potencia “enru-tadora” que en .NET Framework 3.0.

Hay ciertos eventos que no van en pa-rejas, aunque sí que suelen estar relacio-nados con otros eventos; por ejemplo, elevento Click de un botón sería del tipobubbling, aunque no tiene emparejado elequivalente al enrutamiento tunneling (noexiste un evento PreviewClick). En prin-cipio, podría parecer que ese evento es detipo directo, ya que solo se produce en elcontrol que lo define y, aparentemente,no tiene equivalente previo. Aunque enel caso de los eventos relacionados con el

ratón, siempre hay formas de buscar losequivalentes previos; por ejemplo, el even-to Click va precedido de varios eventos,entre ellos los que detectan la pulsacióndel botón izquierdo del ratón: MouseLeft-ButtonDown y PreviewMouseLeftButton-Down, aunque en este caso en particulardel evento Click, el propio control quedetecta la pulsación marca el evento co-mo manipulado (Handled), impidiendoque se propague por el árbol de contene-dores. Pero tal como XAML nos permi-te definir los eventos enrutados, tambiénpodemos indicar que se intercepte elevento Click de un botón en el contene-dor (o padre) de ese botón; además, deforma independiente al evento intercep-tado por el propio botón.

Enrutamiento bubbling

La mejor forma de entender estosconceptos es viéndolos con un ejemplo.

Para mantener las cosas simples, el có-digo XAML de ejemplo está muy simpli-ficado (pero 100% operativo) y consisteen una ventana (Window) que contiene unStackPanel que a su vez contiene dos bo-tones y dos etiquetas; en el StackPanelde-finimos un evento que interceptará la pul-sación en cualquiera de los botones quecontenga, además, de forma independien-

te, cada botón define su propio eventoClick. Para saber cuál es el orden en el quese producen los eventos tengo definidauna función que simplemente incremen-ta una variable y devuelve el valor de lamisma. En los fuentes 1 y 2 tenemos tan-to la definición del código XAML comoel correspondiente al uso desde C# parainterceptar esos eventos.

El evento Click es de tipo bubbling,por tanto, primero se produce en el ele-mento que provoca el evento y despuésse propaga al resto de elementos que es-tán en el mismo árbol, es decir, al conte-nedor del control y al contenedor del con-tenedor, etc.; en nuestro caso al StackPa-nel y, si así lo hubiéramos previsto, al ob-jeto Window. Por tanto, tal como está elcódigo del fuente 2, primero se mostra-rá el mensaje en la etiqueta labelInfo2 ydespués en labelInfo.

En el elemento StackPanel indica-mos que queremos interceptar el even-to Click de los botones que contengaeste control y en el código del métodoque intercepta ese evento mostramos elnombre del control que lo produce. Enese código usamos la propiedad Origi-nalSource del objeto recibido en el se-gundo parámetro, aunque en este casoparticular también nos hubiera validousar el valor devuelto por la propiedad

<Window x:Class=”dnm.eventosXAML01_cs.Window1” ... ><StackPanel Name=”stackPanel1” Button.Click=”stackPanel_ButtonClick”><Button Name=”btnUno” Content=”Uno” Click=”btnUno_Click” /><Button Name=”btnDos” Content=”Dos” Click=”btnDos_Click” /><Label Name=”labelInfo” Content=”Info” /><Label Name=”labelInfo2” Content=”Info2” Background=”LightBlue” />

</StackPanel></Window>

private void stackPanel_ButtonClick(object sender, RoutedEventArgs e){

Button btn = (Button)e.OriginalSource;labelInfo.Content = “Has pulsado en “ + btn.Name + “ “ + total();

}private void btnUno_Click(object sender, RoutedEventArgs e){

labelInfo2.Content = “Botón Uno “ + total();}private void btnDos_Click(object sender, RoutedEventArgs e){

labelInfo2.Content = “Botón Dos “ + total();}

Fuente 1. Código XAML del primer ejemplo

Fuente 2. Código de C# del primer ejemplo

dotN

etM

anía

<<

14

dnm.firma.solidaria<<

Source. Como hemos comentado, elevento interceptado por ese método seproducirá después de que se haya pro-ducido el evento en cada uno de los bo-tones. En cualquier caso, si dentro delos métodos que interceptan los even-tos particulares de cada botón quisié-ramos dejar de “reproducir” el evento,es decir, evitar que se propague a loscontenedores del botón, podemos asig-nar un valor verdadero a la propiedadHandled del segundo parámetro.

En el código de los fuentes 3 y 4 te-nemos los cambios a realizar en el ejem-plo anterior para propagar el eventoClick de los botones al objeto Window,y para marcar como manejado dichoevento, pudiendo comprobar todo loaquí comentado.

En la figura 1 vemos la aplicaciónen ejecución después de haber pulsadoen el segundo botón, en la que pode-mos apreciar el orden en el que se eje-cuta el código.

Enrutamiento tunneling

La otra forma de “enrutar” los even-tos en XAML es la técnica conocida co-mo tunneling, que consiste en la propa-gación de los eventos desde el contene-dor de nivel más superior hasta el ele-mento que en realidad produce el even-to. Los eventos clasificados en el tipotunneling contienen en el nombre elprefijo Preview. Por ejemplo, si quere-mos detectar el movimiento del ratónen una serie de controles de una apli-cación de tipo WPF, podríamos escri-bir un código como el mostrado en elfuente 5.

En el control StackPanel defini-mos el evento PreviewMouseMove, ade-más en cada uno de los dos botonesque contiene ese panel hay definidotambién un evento MouseMove. El pri-mero se producirá antes que cualquie-ra de los otros dos, al menos cuandoel ratón se mueva por cualquiera deesos dos botones. Pero al estar defi-nido a nivel del contenedor, ese even-to será capaz de detectar el movimien-to del ratón en cualquiera de los con-troles que contiene además de en símismo.

Con el código del fuente 6 pode-mos saber en qué control está el ra-tón en cada momento y gracias al va-lor devuelto por la función total()también sabremos en qué orden seejecutan los eventos, al menos si esemovimiento de ratón lo hacemos so-bre cualquiera de los dos botones, yaque si movemos el ratón encima decualquiera de las dos etiquetas, tam-bién se producirá (e interceptará) elevento a nivel del panel.

Como ya sabemos, cada control delas aplicaciones XAML en realidad es-tá formado por otros controles. Porejemplo, las etiquetas (o los botones)para mostrar el texto en realidad utili-zan un control del tipo TextBlock, y sivemos el resultado mostrado en la fi-gura 2, nos daremos cuenta que el con-trol que se recibe en la propiedad Ori-ginalSource del segundo parámetro delmétodo stackPanel_MouseMove en rea-lidad es un control TextBlock, mientrasque el control indicado por la propie-

<Window x:Class=”dnm.eventosXAML01b_cs.Window1” ... Button.Click=”Window1_ButtonClick” >

Fuente 3. Modificando el fuente 1 podemos interceptar en el objeto Window el evento Click de los botones

private void Window1_ButtonClick(object sender, RoutedEventArgs e){

Button btn = (Button)e.OriginalSource;labelInfo.Content += “\n(Window)Has pulsado en “ + btn.Name + “ “ + total();labelInfo.Content += ‘\n’ + ((FrameworkElement)e.Source).ToString();

}private void stackPanel_ButtonClick(object sender, RoutedEventArgs e){

Button btn = (Button)e.OriginalSource;labelInfo.Content = “(StackPanel)Has pulsado en “ + btn.Name + “ “ + total();labelInfo.Content += ‘\n’ + ((FrameworkElement)e.Source).ToString();

}// Al indicar e.Handled = true el evento no se propagará.private void btnUno_Click(object sender, RoutedEventArgs e){

labelInfo2.Content = “Botón Uno “ + total();labelInfo.Content = “”;e.Handled = true;

}

Fuente 4. Cambios al fuente 2 para usarlo con el fuente 3

<Window x:Class=”dnm.eventosXAML02_cs.Window1” ... ><StackPanel Name=”stackPanel1” PreviewMouseMove=”stackPanel_MouseMove”><Button Name=”btnUno” Content=”Uno” MouseMove=”btnUno_MouseMove” /><Button Name=”btnDos” Content=”Dos” MouseMove=”btnDos_MouseMove” /><Label Name=”labelInfo” Content=”Info” /><Label Name=”labelInfo2” Content=”Info2” Background=”LightBlue” />

</StackPanel></Window>

Fuente 5. Código XAML del ejemplo de tunneling

Figura 1. El segundo ejemplo enejecución después de pulsar

en el botón “Dos”

dotN

etM

anía

<<

15

dnm.firma.solidaria<<

dad Source hace referencia al propiobotón en el que se está efectuando elmovimiento del ratón.

Y si desplazamos el cursor del ra-tón sobre una parte que no tiene tex-to, tal como vemos en la figura 3, nosindicará que el origen “real” del even-to es “algo” llamado ButtonChrome,que como podemos suponer (al me-nos viendo el espacio de nombres alque pertenece), es un elemento usa-do para “pintar” el color dependien-do del tema actual que tengamos ennuestro equipo.

RoutedEventArgs: tipo basede los eventos enrutados

A diferencia de las aplicaciones“normales” (las basadas en WindowsForms), los tipos de datos usados co-mo segundo parámetro de los méto-dos que interceptan los eventos en lasaplicaciones XAML (o que usan loscontroles de WPF) se derivan (direc-ta o indirectamente) del tipo Route-dEventArgs. Como acabamos de ver,ese tipo define ciertas propiedadesque nos permiten saber qué elemen-to (o control) es el que realmente haproducido el evento.

Si nos fijamos bien en el códigodel fuente 6, particularmente en la de-finición del método que intercepta elevento PreviewMouseMove, veremosque el segundo parámetro lo hemosdefinido como RoutedEventArgs, cuan-do en realidad el delegado que defi-ne ese evento indica que ese segundoparámetro debería ser del tipo Mouse-EventArgs (que es el que hemos usa-do en los otros dos métodos). Sin em-bargo, el código ha compilado correc-tamente; esto es así, al menos en C#,porque este lenguaje permite usarcualquier clase base que tenga la cla-se esperada como parámetro, algo co-nocido como contravarianza (ver dot-NetManía número 30). Sin embar-go, si nuestro lenguaje de programa-ción es Visual Basic, siempre tendre-mos que indicar el tipo de parámetrocorrecto.

Eventos XAML definidos co-mo estilos

No son solo los eventos “normales”,es decir, los definidos directa y explícita-mente, los que podemos enrutar enXAML, ya que gracias a los triggers (des-encadenadores) podemos “jugar” un po-co con los eventos en las aplicacionesXAML. No voy a entrar en demasiadosdetalles sobre esta forma de definir even-tos, ya que en el número 27 de esta mis-ma revista Luis Miguel Blanco hablócon detalle de los estilos XAML en ge-neral, así como de los desencadenadoresrelacionados con los eventos. Pero paraaquellos lectores que no tienen ese nú-mero de dotNetManía a mano, y paracerrar este artículo con algo puramenteXAML, veamos cómo podemos definirlas acciones que queremos que se reali-cen cuando un evento en particular ocu-rra, pero sin necesidad de escribir ni unasola línea de código, al menos de códigoen C# o Visual Basic, ya que ese códigosí que habrá que escribirlo en XAML.

En el fuente 7 podemos ver cómo “li-gar” ciertos eventos con los controles detipo Buttonque definamos en nuestra apli-cación, particularmente para que se eje-cuten ciertas acciones sobre determina-das propiedades, en este caso usando unpoco de “animación” por medio de ele-mentos de tipo Storyboard. En ese códi-go hemos definido un estilo para todoslos controles de tipo Button, y en parti-cular interceptamos dos eventos: Mouse-Enter y MouseLeave. Esos eventos los in-dicamos por medio del atributo (o pro-piedad) RoutedEvent del elemento Event-Trigger. En cada Storyboard (el guión dela película que nos queremos montar conese evento) le decimos qué es lo que que-remos que haga cuando se produzca eseevento. En este caso, en el evento Mouse-Enter indicamos que queremos animar lapropiedad Width hasta que alcance el va-lor indicado. En el evento MouseLeave de-cimos que también queremos animar esamisma propiedad del control, pero al noindicar el valor, se usará el que tuviera ini-cialmente. Aclarar que si pretendemos“animar” una propiedad que no está pre-viamente definida con un valor inicial, re-cibiremos una excepción.

private void stackPanel_MouseMove(object sender, RoutedEventArgs e){

FrameworkElement elem = (FrameworkElement)e.Source;labelInfo.Content = “El ratón está en “ + elem.Name + “ “ + total();// OriginalSource y Source no tienen porqué ser lo mismolabelInfo.Content += “\nSource= “ + e.Source.ToString();labelInfo.Content += “\nOriginalSource= “ +

e.OriginalSource.ToString();}private void btnUno_MouseMove(object sender, MouseEventArgs e){

labelInfo2.Content = “El ratón está en el botón Uno “ + total();}private void btnDos_MouseMove(object sender, MouseEventArgs e){

labelInfo2.Content = “El ratón está en el botón Dos “ + total();}

Fuente 6. Código C# del ejemplo de tunneling

Figura 2. Resultado de ejecutar elcódigo del fuente 6

Figura 3. El origen del evento puedeser cualquier elemento que

forme el control

dotN

etM

anía

<<

16

dnm.firma.solidaria<<

Si queremos definir esos eventos pa-ra cualquier tipo de control, tendremosque cambiar el valor indicado en Tar-getType, pero como hemos comprobado,ese estilo (y sus correspondientes even-tos) solo se aplicarán a los controles quecoincidan con ese “tipo destino”. Si qui-siéramos definir ese estilo para diferen-

tes tipos de controles, podríamos definir-lo como un estilo con nombre; de esa for-ma, podríamos aplicar dicho estilo de for-ma independiente a ciertos controles.

En el código que acompaña al artícu-lo he definido el mismo estilo del códigofuente 7 (con pequeños cambios), pero aldefinirlo como un estilo con nombre, so-

lo será aplicable a los controles que “quie-ran” usar ese estilo en concreto. En nues-tro ejemplo, lo aplicamos a uno de los dosbotones y a la etiqueta. En ese código, nosolo animamos el ancho del control, si-no también el tamaño de la fuente. Vuel-vo a recordar que esto solo funcionará siesos controles han definido de forma ex-plícita los valores iniciales de las propie-dades a animar.

ConclusionesEn este artículo hemos dado un pe-

queño repaso a los distintos tipos deeventos que podemos utilizar en lasaplicaciones para WPF, centrándonosen los eventos enrutados (routed events),de los cuales como hemos visto existenprincipalmente dos tipos, según la for-ma que tenga el evento de propagarse.También hemos visto cómo podemosinterceptarlos de forma generalizada ode forma concreta, todo dependiendode dónde definamos el evento. Por úl-timo, hemos comprobado que por me-dio de los desencadenadores (triggers)podemos definir e interceptar eventosusando solo código XAML.

Quisiera aclarar que todo el códigoaquí mostrado se puede usar sin necesi-dad de utilizar ninguna versión beta, yaque lo único que necesitamos es tenerinstalado Visual Studio 2005 y la versión3.0 de .NET Framework, versión queya está incluida en Windows Vista, pe-ro que también podemos instalar encualquier equipo con Windows XP SP2o Windows 2003 SP1. Por supuesto, laforma más fácil de crearlos es usando lasextensiones “Orcas” para Visual Studio2005, pero solo si queremos ver el dise-ño de los “formularios” mientras escri-bimos el código XAML.

En la Web de la revista está dispo-nible todo el código de ejemplo, tantopara Visual Basic como para C#. En elZIP con el código he añadido dos pro-yectos vacíos que puede usar comoplantillas para crear sus proyectos paraWPF, ya que en una instalación normalde Visual Studio 2005 no existen esostipos de proyectos ni tampoco los fi-cheros de tipo .xaml usados para incluirel código XAML.

<Window x:Class=”dnm.eventosXAML03_cs.Window1” ... ><Window.Resources><Style TargetType=”{x:Type Button}”><Style.Triggers><EventTrigger RoutedEvent=”Mouse.MouseEnter”><EventTrigger.Actions><BeginStoryboard><Storyboard><DoubleAnimation Duration=”0:0:.5”Storyboard.TargetProperty=”Width” To=”270” />

</Storyboard></BeginStoryboard>

</EventTrigger.Actions></EventTrigger><EventTrigger RoutedEvent=”Mouse.MouseLeave”><EventTrigger.Actions><BeginStoryboard><Storyboard><DoubleAnimation Duration=”0:0:1”Storyboard.TargetProperty=”Width” />

</Storyboard></BeginStoryboard>

</EventTrigger.Actions></EventTrigger>

</Style.Triggers></Style>

</Window.Resources><Canvas><Button Name=”btnUno” Content=”Uno”

Canvas.Left=”10” Canvas.Top=”10” Width=”100” Height=”26” /><Button Name=”btnDos” Content=”Dos”

Canvas.Left=”10” Canvas.Top=”40” Width=”100” Height=”26” /><Label Content=”Mueve el ratón por los botones”

Background=”Indigo” Foreground=”White”Canvas.Left=”10” Canvas.Top=”80” />

</Canvas></Window>

Fuente 7. Eventos y acciones definidas directamente en XAML por medio de estilos

NOTA

Aclarar que solo podremos acceder desde el código a los controles cre-ados en el fichero XAML si esos controles tienen la propiedad Name (oel atributo x:Name) asignada (podemos usar indistintamente cualquierade las dos “propiedades”, pero solo una de ellas en cada control o ele-mento XAML). Además, debemos compilar el proyecto para que se cre-en las definiciones de esos controles en el código y así podamos accedera ellos. Sin estos dos “requisitos” los controles no serán accesibles des-de el código de nuestro lenguaje favorito.

][

En nuestra entrega anterior [1] vimos, por ejem-plo, cómo auditar cada vez que comience la eje-cución de un método F1 decorándolo con un atri-buto de tipo BeforeAspect. Éste es el caso del atri-buto LogBefore del siguiente ejemplo:

class A{

// ...[LogBefore(“Log.txt”)]public void F1(){...}public void F2(){...}

}

Vimos también cómo extender Visual Studioagregando un add-in que permite especificar puntosde corte (point cut) en nuestro código. Al especificarlos puntos de corte, indicamos los lugares del códi-go donde nuestro add-in debe realizar el entretejidode la semántica expresada por los aspectos que serepresentan mediante atributos .NET. Estos pun-tos de corte son configurables; en la entrega anteriormostramos cómo se colocan dentro del IDE loscomandos para poner y quitar puntos de corte.

Una vez colocados los puntos de corte, nosqueda ahora mostrar cómo hacer el entretejido.Para ello, vamos a ver cómo hacer que nuestroadd-in interactúe con Visual Studio para que duran-te la generación de un ensamblado éste logre entre-tejer el código que en ejecución lleve a cabo la fun-cionalidad expresada en los aspectos.

Al culminar esta segunda parte, usted podrádisponer de un mecanismo para aplicar concep-

tos de AOP en .NET, a la vez que contará con losconocimientos necesarios para extender la fun-cionalidad de Visual Studio 2005 utilizando elmecanismo de add-ins que éste ofrece.

El editor de textoEl editor de texto de Visual Studio (en ade-

lante, VS) posee la capacidad de manejar el códi-go fuente específico de los lenguajes .NET. El tex-to es escrito a un búfer, que lo muestra en un docu-mento de texto en el editor.

Los objetos para la automatización del editorde texto de VS pueden utilizarse para controlar lasoperaciones que ocurren tanto sobre el texto (códi-go fuente) que se muestra en el editor como sobreel texto almacenado en el búfer. El editor de tex-to de VS controla en un primer plano el texto quese muestra, y en un segundo plano un búfer de tex-to que está siendo manipulado a otro nivel.

Existen cuatro objetos principales para el controlde las operaciones sobre el editor: TextSelection,TextPoint, EditPoint y VirtualPoint, siendo TextSe-lection y EditPoint los principales a través de los cua-les se puede manipular el código en el editor de VS:• TextSelection: Permite manipular el texto en

el documento visible. Representa el punto deinserción donde está situado el cursor o el tex-to seleccionado en el documento visible.

• EditPoint: Permite manipular el texto en el búfer.Un objeto EditPoint representa una posición par-

Atributos,aspectos y cómo entretejer códigodesde Visual Studio para hacer AOP en .NET (II)

plataforma.net

En nuestra entrega anterior presentamos los tipos de aspectos quepodemos colocar en nuestro código C# basándonos en atributos .NET.En esta segunda parte, vamos a ver cómo hacer que Visual Studio entretejael código para aplicar la funcionalidad de los aspectos.

MMiigguueell KKaattrriibbes Dr. en Computación yCatedrático del Dpto. deCiencia de la Computa-

ción de la Universidad deLa Habana. Dirige el

Grupo WEBOO, dedica-do a la enseñanza y desa-rrollo de la Orientación a

Objetos y la Programa-ción en la Web. Miguel es

redactor de ddoottNNeett--MMaannííaa y asesor de pro-gramación y tecnología.NET para CCAARREE TTeecchh--

nnoollooggiieess SS..AA..

YYaammiill HHeerrnnáánnddeezzes instructor de progra-

mación de la Cátedra deProgramación e Inge-niería de Software delDpto. de Ciencia de la

Computación de la Uni-versidad de la Habana.

Yamil es desarrollador yprogramador del grupo

WEBOO, donde se dedi-ca especialmente a la

Programación Orientadaa Aspectos, Metaprogra-

mación y Reflexión. Escolaborador e ilustrador

de ddoottNNeettMMaannííaa.

Miguel KatribYamil Hernández

ticular dentro de un bloque de texto. Los objetosEditPoint son similares a los objetos TextSelection,salvo que actúan sobre datos del búfer de texto enlugar de actuar sobre texto mostrado en el editor. Ladiferencia consiste en que el texto del búfer no se veafectado por los estados globales del editor, comopor ejemplo el ajuste de líneas y los espacios.

Con estos objetos se puede, entre otras operacio-nes (tanto en la ventana de texto visible del editorcomo en el búfer):• Seleccionar, eliminar, adicionar y mover un texto.• Mover el cursor o el punto de inserción.• Buscar posiciones en un documento, números de

línea, caracteres en una línea así como columnasmostradas.

• Buscar y reemplazar un texto en base a un patrónde búsqueda.

• Crear una región, que puede ser colapsada (ocul-tada) o expandida.

• Obtener información acerca del texto, como elinicio y el final del documento, etc.

En resumen, con ellos se puede hacer programáti-camente casi de todo sobre el texto que se ha escrito enel editor de VS. En el siguiente código se obtiene el obje-to de tipo CodeElement que representará al método al quese le ha añadido un punto de corte. Para ello se especi-fica un punto de comienzo (el cual lo obtenemos a par-tir de la propiedad TopPoint, que indica el inicio del tex-to seleccionado) para reconocer en el texto y el tipo deelemento vsCMElement.vsCMElementFunctionque se quie-re reconocer a partir de ese comienzo (en nuestro casoun método).

TextSelection selection = (TextSelection)_applicationObject.ActiveWindow.Selection;

EditPoint Start = selection.TopPoint.CreateEditPoint();CodeElement element = _applicationObject.ActiveDocument.ProjectItem.

FileCodeModel.CodeElementFromPoint(Start, vsCMElement.vsCMElementFunction);

En la sección siguiente se verá cómo interactuar conel código fuente contenido en el editor de texto de VSpor mediación del Modelo de código.

Del texto al CodeElementCodeElement es el tipo principal dentro del conjunto

de tipos definidos en el Modelo de código de .NET.Mediante los tipos de este modelo se pueden programarlos add-ins para reconocer o generar código en cualquierlenguaje .NET. La propiedad Kindde CodeElementnos dael tipo específico del objeto CodeElement, que se utilizapara preguntar si el lugar donde se está pretendiendo ponerel punto de corte corresponde realmente a un método.

Para entender mejor qué es el Modelo de código,veamos cuál sería la representación en él del siguien-te segmento de código:

namespace MyNamespace{class A{

[LogBefore(“Log.txt”)][LogAfter(“Log.txt”)]public void F(){

Console.WriteLine(“F with aspects”);}

}}

Dicha representación se ilustra en la figura 1.

La jerarquía de elementos de código de la figura1 puede ser navegada en busca de un elemento especí-fico de una manera sencilla. En este diagrama estánrepresentadas algunas de las clases derivadas de Code-Element más utilizadas. En nuestra entrega anteriorhemos ilustrado cómo a partir de un texto en el edi-

dotN

etM

anía

<<

19

dnm.plataforma.net<<

Figura 1. El Modelo de código

dotN

etM

anía

<<

20

dnm.plataforma.net<<

tor de VS es posible obtener el objetoCodeElement que lo representa. Por ejem-plo, obtenemos el CodeElement querepresenta al método al que se le hacolocado un punto de corte con la ins-trucción:

CodeElement element = _applicationObject.ActiveDocument.

ProjectItem.FileCodeModel.CodeElementFromPoint(Start, vsCMElement.vsCMElementFunction);

CodeElementFromPointdevuelve el ele-mento de código asociado a un TextPointbasándose en el ámbito especificado. Sino existe ningún elemento de código deltipo especificado que contenga la ubica-ción del editor, entonces CodeElement-FromPoint producirá un error.

Lamentablemente, en el Modelo decódigo los atributos no tienen la mismafuncionalidad que otros CodeElement. Así,por ejemplo, si bien para CodeVariableexiste una propiedad Type de tipo CodeTy-peRef que nos da información sobre eltipo del que ha sido declarada la varia-ble, no existe una propiedad semejantepara CodeAttribute. Esto resulta unalimitación para lo que se propone eneste trabajo, ya que sería deseable podercontrolar que solo se pudieran colocarpuntos de corte en aquellos métodos alos que se les hubiera colocado un atri-buto de tipo AspectAttribute.

En la siguiente sección se verá cómohacer el entretejido del código base conla funcionalidad descrita mediante losatributos-aspectos.

El entretejido de los aspectoscon el código principal

El mecanismo mediante el cual seintegra la funcionalidad de los aspectoscon la funcionalidad del código principalse denomina entretejido (weaving). Esteentretejido podría realizarse durante lacreación o utilización de un ensamblado.

De manera general, se puede hablarde dos formas de entretejido: estático ydinámico. El entretejido estático es cuan-do el código fuente principal se modificainsertando el código de los aspectos segúnse haya indicado con los puntos de corte(point cuts). El entretejido estático se uti-

liza, por ejemplo, en AspectJ [2]. La prin-cipal ventaja de esta forma de entretejidoes que una vez compilado el código fuen-te entretejido, la funcionalidad de losaspectos quedará reflejada directamenteen el código ejecutable, lo que implica unmayor rendimiento en la ejecución. Sinembargo, a partir de este código entrete-jido y compilado resulta difícil hacer elproceso inverso e identificar los aspectosen el código resultante. Esto limitaría laposibilidad de adaptar o reemplazardinámicamente los aspectos en tiempode ejecución.

Otra posible vía es la de realizar elentretejido de forma virtual dinámica-mente. Para ello, habría que monitorizarla ejecución del programa, de modo quecada vez que en ejecución se alcance unpunto de corte se pueda ejecutar la fun-cionalidad del (los) aspecto(s) asociado(s),extrayendo esta funcionalidad mediante elmecanismo de reflexión. Esta monitori-zación implica por tanto un coste adicio-nal en cuanto a rendimiento. Una estrate-gia de solución para esta variante dinámi-ca (basada en intermediarios o proxies) fuedesarrollada en un trabajo previo de estosautores publicado en dotNetManía [3].

La solución que se propone en elpresente trabajo hace una mezcla de las

dos estrategias anteriores. El add-in inte-grado en el IDE generará en tiempo decompilación en los puntos de corte elcódigo que durante la ejecución seencargará de extraer dinámicamente einvocar la funcionalidad de los aspectos.Todo ello manteniendo sin modificarlos archivos con el código fuente origi-nal. Al estar la funcionalidad de losaspectos definida dentro de los atribu-tos, éstos podrán ser modificados sinafectar el código fuente principal.

¿Cómo y cuándo funciona eladd-in que entreteje el código?

Además de interactuar con el códi-go del editor de VS, en un add-in se pue-de también saber casi de todo lo que estáocurriendo dentro del IDE. Para esto,VS dispone de distintas categorías demanejadores de eventos (tabla 1), quecontienen la mayoría de las acciones queun usuario puede realizar en el IDE;cada categoría contiene distintos mane-jadores para eventos específicos.

Entre todos estos eventos, destaca-remos especialmente los dos siguientes: • OnBuildBegin: Ocurre cuando desde

el IDE se inicia alguna de las accionesde generación (build) de un proyecto.

DTE events Document events Window events

ModeChanged DocumentClosing WindowActivated

OnBeginShutdown DocumentOpening WindowClosing

OnMacrosRuntimeReset DocumentOpened WindowCreated

OnStartupComplete DocumentSaved WindowMoved

Task List events Find events Output window events

TaskAdded FindDone PaneAdded

TaskModified PaneClearing

TaskNavigated PaneUpdated

TaskRemoved

Debugger events Build events Solution events

OnContextChanged OnBuildBegin AfterClosing

OnEnterBreakMode OnBuildDone BeforeClosing

OnEnterDesignMode OnBuildProjConfigBegin Opened

OnEnterRunMode OnBuildProjConfigDone ProjectAdded

OnExceptionNotHandled ProjectRemoved

OnExceptionThrown ProjectRenamed

QueryCloseSolution

Renamed

Selection events

OnChange

Tabla 1.Categorías y manejadores de eventos

dotN

etM

anía

<<

21

dnm.plataforma.net<<

• OnBuildDone: Ocurre cuando el pro-ceso de generación ha terminado.

El proceso de entretejido se iniciacuando comienza la ejecución del coman-do “Generar” del IDE, por lo que el add-in debe anotar al evento OnBuildBegin elmétodo que hace el entretejido:

buildEventsCategory.OnBuildBegin += new_dispBuildEvents_OnBuildBeginEventHandler(

WeaveAspectsCode);

Note que buildEventsCategory, detipo BuildEvents, sería la categoría, yOnBuildBegin el evento al cual asociamosel código del método manejador Weave-AspectsCode, que es un delegado de tipo_dispBuildEvents_OnBuildBeginEvent-

Handler. WeaveAspectsCode es el métodoque se encarga de generar (usando elModelo de código) el código necesariopara extraer y ejecutar los métodos Advi-cede los aspectos, en todos aquellos méto-dos a los que se colocó un punto de cor-te de la forma que se ilustró en la figura2 y que se mantienen en la colecciónaspectizedMethods.

Para un método como el del códigosiguiente, al que se le han colocado losaspectos y se le ha establecido un pun-to de corte:

class A{//...[LogBefore(“Log.txt”)][LogAfter(“Log.txt”)]public void F()

{Console.WriteLine(“F with aspects”);

}//...

}

El manejador WeaveAspectsCode ano-tado al OnBuildBegin provocará cambiosen la representación del código fuenteen el IDE para que el código generadopor la compilación sea el equivalente asi el código a compilar hubiese sido elque se muestra en el fuente 1.

En el fuente 1, Aspect_Of_Method_F[0]contiene los BeforeAspect del método F;Aspect_Of_Method_F[1] contiene el Ins-teadAspect del método F (puede haber unsolo InsteadAspect, como se especificóen su definición mediante AllowMultiple

= false); y Aspect_Of_Method_F[2] con-tiene los AfterAspect del método F. Noteque el nuevo método F es el encargadode realizar el entretejido de los aspectoscon la funcionalidad del método F origi-nal, que ahora ha quedado renombradocomo Hidden_F. Observe además que elmétodo F del fuente 1 no retorna valor;por lo tanto, el parámetro result no seutiliza en este caso.

A continuación se presenta un ejem-plo en el que un aspecto de tipo AfterAs-pect incide sobre el valor devuelto por unmétodo. En tal caso, el parámetro resultdel método Advice sí es de utilidad, por-

que la funcionalidad del aspecto puedetener que ver con el valor que el métododevuelve. En el ejemplo se coloca un aspec-to para convertir a mayúsculas cada cade-na que se devuelva desde un método G.

class A

{//...[ToUpper] public string G(){return “soy el método G()”;

}//...

}

class A{

private AspectAttribute[][] Aspect_Of_Method_F;

[LogBefore(“Log.txt”)][LogAfter(“Log.txt”)]private void Hidden_F(){

Console.WriteLine(“F with aspects”);}

[LogBefore(“Log.txt”), LogAfter(“Log.txt”)]public void F(){

object result = null;if (Aspect_Of_Method_F == null){

Aspect_Of_Method_F = new AspectAttribute[3][];Aspect_Of_Method_F[0] = (BeforeAspect[])MethodBase.

GetCurrentMethod().GetCustomAttributes(typeof(BeforeAspect), true);

Aspect_Of_Method_F[1] = (InsteadAspect[])MethodBase.GetCurrentMethod().GetCustomAttributes(typeof(InsteadAspect), true);

Aspect_Of_Method_F[3] = (AfterAspect[])MethodBase.GetCurrentMethod().GetCustomAttributes(typeof(AfterAspect), true);

}foreach (BeforeAspect b in Aspect_Of_Method_F[0])

b.Advice(this, this.GetType().GetMethod(“Hidden_F”,BindingFlags.NonPublic |BindingFlags.Instance), null);

if (Aspect_Of_Method_F[1].Length != 0)((InsteadAspect)Aspect_Of_Method_F[1]).Advice(

this, this.GetType().GetMethod(“Hidden_F”,BindingFlags.NonPublic |BindingFlags.Instance), null);

elsethis.Hidden_F();

foreach (AfterAspect a in Aspect_Of_Method_F[3])a.Advice(this, this.GetType().GetMethod(“Hidden_F”,

BindingFlags.NonPublic |BindingFlags.Instance),ref result, null);

}}

Fuente 1

dotN

etM

anía

<<

22

dnm.plataforma.net<<

La definición del aspecto ToUppersería:

public class ToUpper : AfterAspect{public override void Advice(

object targetObject, MethodBase targetMethod, ref object result, params object[] parameters)

{result = ((string)result).ToUpper();

}}

Note cómo en el código del Advi-ce anterior sí se utiliza el parámetroresult. A través de este parámetro, quese pasa por referencia, el código entre-tejido (fuente 2) pasa el valor devueltopor el método; entonces la implemen-tación del Advice anterior lo modifica,y el efecto se produce sobre la variableresult del método G del fuente 2; quiena su vez la devuelve como resultado dela evaluación del método G.

Sin embargo, no se quiere que este“entretejido” quede formando parte delcódigo fuente del proyecto para no dis-turbar la comprensión de este códigocon el de los aspectos. De modo que elcódigo fuente como el que se ha pre-sentado en los fuentes 1 y 2 solo es intro-ducido al comenzar el proceso de com-pilación para que el compilador genereel código IL correspondiente en elensamblado; luego es eliminado del pro-yecto. Es decir, el código quedará entre-tejido a nivel del IL del ensamblado,pero no estará reflejado en el códigofuente. Para ello, el add-in anota tam-bién el evento OnBuildDone:

m_BuildEvents.OnBuildDone += new_dispBuildEvents_OnBuildDoneEventHandler(

UnWeaveAspectCode);

Al terminar la compilación, seinvoca entonces el método UnWeaveAs-pectCode (fuente 3), que hace el pro-ceso inverso al del método WeaveAs-pectCode; de modo que al guardar elproyecto los cambios no queden refle-jados en el código fuente original.

La figura 2 ilustra el proceso de tra-bajo del add-in que se ha incorporado aVS 2005 para realizar el trabajo de entre-tejido explicado anteriormente.

Expresando aserciones através de aspectos

Según el Diseño por contratos [4],las aserciones son cláusulas lógicas quese pueden asociar al código para espe-cificar la funcionalidad del mismo.Basándonos en la propuesta de entrete-jido presentada en este trabajo, se podríaimplementar la evaluación de asercio-nes asociadas a código fuente .NETmediante atributos. Considere elsiguiente código, que establece una pre-

condición y una poscondición al méto-do Push de una clase Stack.

class Stack{//...public bool Full{...}public bool Empty{...}//...[PreConditionAspect(“!Full”)][PostConditionAspect(“!Empty”)]public void Push(Object x){//...

}//...

}

class A{private AspectAttribute[][] Aspect_Of_Method_G;

[Capitalize]private string Hidden_G(){return “soy el método G()”;

}

[Capitalize]public string G(){object result = null;if (Aspect_Of_Method_G == null){ Aspect_Of_Method_G = new AspectAttribute[3][];Aspect_Of_Method_G[0] = (BeforeAspect[]) MethodBase.

GetCurrentMethod().GetCustomAttributes(typeof(BeforeAspect), true);

Aspect_Of_Method_G[1] = (InsteadAspect[]) MethodBase. GetCurrentMethod().GetCustomAttributes(typeof(InsteadAspect), true);

Aspect_Of_Method_G[3] = (AfterAspect[]) MethodBase.GetCurrentMethod().GetCustomAttributes(typeof(AfterAspect), true);

}foreach (BeforeAspect b in Aspect_Of_Method_G[0])b.Advice(this, this.GetType().GetMethod(“Hidden_G”,

BindingFlags.NonPublic | BindingFlags.Instance), null);

if (Aspect_Of_Method_G[1].Length != 0)result = ((InsteadAspect)Aspect_Of_Method_G[1]).Advice(

this, this.GetType().GetMethod(“Hidden_G”,BindingFlags.NonPublic | BindingFlags.Instance), null);

elseresult = this.Hidden_G();

foreach (AfterAspect a in Aspect_Of_Method_G[3])a.Advice(this, this.GetType().GetMethod(“Hidden_G”,

BindingFlags.NonPublic | BindingFlags.Instance), ref result, null);

return (string) result;}

}

Fuente 2

Usando una estrategia similar a laaquí presentada, el “entretejedor” podríacolocar código para evaluar las asercio-nes, produciendo un código equivalen-te al que se muestra a continuación:

class Stack{// ...[PreConditionAspect(“!Full”)][PostConditionAspect(“!Empty”]public void Push(object x){if (!(!Full)) throw new Exception(

“Precondition Fail”);try{//...código original de Push

}

finally{

if (!(!Empty)) throw newException(“Postcondition Fail”);

}}

}

Conclusiones

El modelo de extensibilidad de VisualStudio .NET nos permite enriquecernuestro entorno de trabajo con nuevasfuncionalidades. Este artículo no ha pre-tendido ser un tutorial sobre add-ins, peroilustra cómo usar los mismos para darsoporte al entretejido de código de la AOP.

La forma en que ha sido abordada laintroducción de la AOP sirve de basepara introducir otros temas como el tra-bajo con aserciones dentro del mismoentorno de desarrollo. El trabajo conaserciones es una derivación interesan-te del uso de atributos para poder inter-calar, en un tipo y sus métodos, precon-diciones, poscondiciones e invariantes,dando con ello soporte en .NET a lametodología conocida como Programa-ción por contratos. La colocación deaserciones en código .NET es un temade gran interés, que aunque ha sido tra-tado por diferentes autores aún lamen-tablemente no forma parte de .NETFramework. Una implementación deaserciones por la vía de atributos-aspec-tos y entretejido será posiblemente obje-to de un futuro artículo.

El lector puede haberse preguntadosi es posible colocar aspectos dentro deensamblados de los cuales no se tiene elcódigo fuente. Para solucionar esto esta-mos trabajando con la herramientaReflector.Editor, que fue presentada enun trabajo previo en dotNetManía [5].La intención es lograr una forma de inte-ractuar con el Explorador de objetos deVS para colocar aspectos en una DLL ydefinir puntos de corte desde el propioexplorador.

dotN

etM

anía

<<

23

dnm.plataforma.net<<

public void UnWeaveAspectCode (){for (int i = 0; i < aspectManagerMethods.Count; i++){string originalName = aspectManagerMethods[i].Name;vsCMAccess originalAccess = aspectManagerMethods[i].Access;

((CodeClass)originalMethods[i].Parent).RemoveMember(aspectManagerMethods[i]);

originalMethods[i].Name = originalName;originalMethods[i].Access = originalAccess;

}

foreach (CodeVariable cv in aspectManagerVars)((CodeClass)cv.Parent).RemoveMember(cv);

aspectManagerMethods.Clear();aspectManagerVars.Clear();

}

Fuente 3

Figura 2.Weaver Add-In y el entretejido de aspectos

Referencias

[1] Hernández, Yamil y Katrib, Miguel“Atributos, aspectos y cómo entrete-jer código desde Visual Studio parahacer AOP en .NET (I)”, publicado endotNetManía Nº 33, enero de 2007.

[2] Kiczales, Gregor et al “An Overviewof AspectJ”, Springer-Verlag, Procee-dings of ECOOP 2001.

[3] Hernández, Yamil y Katrib, Miguel“Aspectos e intercepción de métodos en.NET”, publicado en dotNetManía Nº10, diciembre de 2004.

[4] Meyer, Bertrand “Object OrientedSoftware Construction (2nd Edition)”,Prentice Hall, 1997.

[5] Bacallao, Erick, Katrib, Miguel yParodi, Yoelvis “Reflection.Editor: unabiblioteca para programar la edición deensamblados .NET“, publicado en dot-NetManía Nº 15, mayo de 2005.

En el número 31 de dotNetManía, dedicado a AJAX,se descubrió cuál es la estrategia de Microsoft para abor-dar el desarrollo de aplicaciones Web más eficaces yusables. El plan de la compañía despliega un conjuntode librerías y extensiones para ASP.NET 2.0 que per-miten incluir las bondades de AJAX con el menoresfuerzo posible para el desarrollador. De entre los dife-rentes paquetes disponibles, el primogénito y más útilpara el desarrollador gracias a su integración con elentorno de desarrollo Web en Visual Studio 2005 esMicrosoft AJAX ASP.NET Extensions.

Ante todo, hay que destacar la simplicidad que seha añadido en las extensiones de AJAX para ASP.NET2.0, ya que es realmente sencillo hacer nuestras apli-caciones más usables y dinámicas. Lo primero que debe-mos hacer para obtener estos beneficios es descargarlas extensiones para Visual Studio 2005 dehttp://ajax.asp.net e instalarlas en nuestro equipo dedesarrollo. Una vez instaladas, se dispone de cinco nue-vos controles y una nueva plantilla para proyectos Web.Ahora ya se puede comenzar.

Algo habrá que configurar, ¿no?Digámoslo así: no, no hay nada que configurar.

Bueno, igual esto no es del todo cierto. La verdad esque debería decir que no nos queda nada que configu-

rar si utilizamos la plantilla que proporcionan las exten-siones de AJAX. Y como es evidente, esta plantilla síque dispone de configuración; mucha configuración.A la hora de crear un nuevo sitio Web, se selecciona lanueva plantilla de sitios Web con AJAX que se mues-tra en la figura 1. De esta forma se obtiene un sitio Webpreconfigurado para usar las librerías de AJAX; estoincluye las referencias necesarias y las entradas en elWeb.config relacionadas con AJAX: se añaden diferen-tes controladores para nuevas secciones de configura-ción como <system.web.extensions>, <scripting> y<webServices>; se registra el prefijo de etiquetas asppara los controles incluidos en el espacio de nombres

Actualizando ASP.NET 2.0 con Microsoft AJAX ASP.NET Extensions

Algunas cosas vienen y van, como las estaciones, pero siempre permanecen. Estees el caso de Javascript, un lenguaje odiado por muchos y amado por otrostantos, siempre presente en el mundo del desarrollo Web.Cuando ya parecía quehabía sido excluido de la escena, reaparece con más fuerza que nunca gracias aAJAX. Sin embargo, aunque parezca el buque insignia de AJAX, existen alternativasmás sencillas de utilizar donde este lenguaje queda relegado a situacionespuntuales en las que se requiera un control muy específico.

Miguel Jiménez

MMiigguueell JJiimméénneezz es Soft-ware Development Engi-

neer y responsable deformación para iilliittiiaa

TTeecchhnnoollooggiieess. Coordinael MMaaddrriidd ..NNEETT UUsseerr

GGrroouupp, es MVP deVisual C#, líder de INE-TA en España y colabo-ra frecuentemente conMSDN y otros grupos

de usuarios.Blogs: bbllooggss..cclleeaarrssccrree--

eenn..ccoomm//mmiiggss,ggeeeekkss..mmss//bbllooggss//mmjjiimmee--

nneezz. Contacte con él enmmiigguueell@@iilliittiiaa..ccoomm.

Figura 1.Diálogo de “Nuevo Sitio Web” > “Ajax Enabled Web Site”

dnm.asp.net.ajax<<

dotN

etM

anía

<<

25

<?xml version=”1.0”?><configuration><configSections><sectionGroup name=”system.web.extensions” type=”System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions,

Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”><sectionGroup name=”scripting” type=”System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0,

Culture=neutral, PublicKeyToken=31bf3856ad364e35”><section name=”scriptResourceHandler” type=”System.Web.Configuration.ScriptingScriptResourceHandlerSection,

System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”requirePermission=”false”/>

<sectionGroup name=”webServices” type=”System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”>

<section name=”jsonSerialization” type=”System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” requirePermission=”false” />

<section name=”profileService” type=”System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” requirePermission=”false” />

<section name=”authenticationService” type=”System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”requirePermission=”false” />

</sectionGroup></sectionGroup>

</sectionGroup></configSections>

<system.web><pages><controls><add tagPrefix=”asp” namespace=”System.Web.UI” assembly=”System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

PublicKeyToken=31bf3856ad364e35”/></controls><tagMapping><add tagType=”System.Web.UI.WebControls.CompareValidator” mappedTagType=”System.Web.UI.Compatibility.CompareValidator,

System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/><add tagType=”System.Web.UI.WebControls.CustomValidator” mappedTagType=”System.Web.UI.Compatibility.CustomValidator,

System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/><add tagType=”System.Web.UI.WebControls.RangeValidator” mappedTagType=”System.Web.UI.Compatibility.RangeValidator,

System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/><add tagType=”System.Web.UI.WebControls.RegularExpressionValidator”

mappedTagType=”System.Web.UI.Compatibility.RegularExpressionValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/>

<add tagType=”System.Web.UI.WebControls.RequiredFieldValidator”mappedTagType=”System.Web.UI.Compatibility.RequiredFieldValidator, System.Web.Extensions, Version=1.0.61025.0,

Culture=neutral, PublicKeyToken=31bf3856ad364e35”/><add tagType=”System.Web.UI.WebControls.ValidationSummary” mappedTagType=”System.Web.UI.Compatibility.ValidationSummary,

System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/></tagMapping>

</pages><!—

Set compilation debug=”true” to insert debuggingsymbols into the compiled page. Because thisaffects performance, set this value to true onlyduring development.

—><compilation debug=”false”><assemblies><add assembly=”System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/>

</assemblies></compilation>

<httpHandlers><remove verb=”*” path=”*.asmx”/><add verb=”*” path=”*.asmx” validate=”false” type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions,

Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/><add verb=”GET,HEAD” path=”ScriptResource.axd” type=”System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Ver-

sion=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” validate=”false”/></httpHandlers>

<httpModules>

Fuente 1. Fichero Web.config de un sitio Web con Ajax habilitado (sigue...)

System.Web.Extensions; se añaden con-troladores especiales para las extensiones.asmx de servicios Web y un gestor derecursos para scripts llamado ScriptRe-source.axd; y finalmente, algunos con-troladores de seguridad para servicios Weby gestores de recursos. En el fuente 1 sepresenta un ejemplo del fichero Web.con-fig recién creado a través de la nueva plan-tilla de AJAX Extensions.

Parece que ahora podemos comen-zar directamente con nuestro código por-que la “configuración” está lista. Comoen todos los proyectos Web, se disponepor defecto de la página Default.aspx,pero ¿cómo se debería comenzar un pro-yecto de esta índole?, ¿hay algo especialque añadir a las páginas?

Sí. Teniendo en cuenta que las apli-caciones aderezadas con AJAX se basan

en el uso de Javascript en el cliente, seha de disponer de un gestor para dichosscripts que orqueste las peticiones y res-puestas del servidor; además, es necesa-rio incluir los scripts de Microsoft AJAXLibrary (la base de código Javascript yabstracción del objeto XmlHTTPRequestcreada para dar soporte tanto aASP.NET como a otras plataformas dedesarrollo Web) y poder gestionar los

dnm.asp.net.ajax<<

dotN

etM

anía

<<

26

<add name=”ScriptModule” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/>

</httpModules></system.web><system.web.extensions><scripting><webServices><!— Uncomment this line to customize maxJsonLength and add a custom converter —><!—

<jsonSerialization maxJsonLength=”500”><converters><add name=”ConvertMe” type=”Acme.SubAcme.ConvertMeTypeConverter”/>

</converters></jsonSerialization>—><!— Uncomment this line to enable the authentication service. Include requireSSL=”true” if appropriate. —><!—<authenticationService enabled=”true” requireSSL = “true|false”/>

—>

<!— Uncomment these lines to enable the profile service. To allow profile properties to be retrievedand modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties andwriteAccessProperties attributes. —>

<!—<profileService enabled=”true”

readAccessProperties=”propertyname1,propertyname2”writeAccessProperties=”propertyname1,propertyname2” />

—></webServices><!— <scriptResourceHandler enableCompression=”true” enableCaching=”true” />—>

</scripting></system.web.extensions>

<system.webServer><validation validateIntegratedModeConfiguration=”false”/><modules><add name=”ScriptModule” preCondition=”integratedMode” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions,

Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/></modules><handlers><remove name=”WebServiceHandlerFactory-ISAPI-2.0”/><add name=”ScriptHandlerFactory” verb=”*” path=”*.asmx” preCondition=”integratedMode”

type=”System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”/>

<add name=”ScriptResource” verb=”GET” path=”ScriptResource.axd” type=”System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” />

</handlers></system.webServer>

</configuration>

(... continuación)Fuente 1. Fichero Web.config de un sitio Web con Ajax habilitado

dnm.asp.net.ajax<<

dotN

etM

anía

<<

27

eventos en tiempo de ejecución. El con-junto de controles que integran lasAJAX Extensions, mostrado en la figu-ra 2, incluye un control capaz de rea-lizar esta orquestación de eventos ypeticiones.

Un buen gestor:ScriptManagerEl control ScriptManager es, como su

nombre indica, el gestor de scripts decualquier página ASP.NET que deseeincluir AJAX Extensions. El uso del con-trol es relativamente sencillo: arrastrary soltar. Este sencillo gestor incluye enla página .aspx, una vez compilada y ren-derizada, los scripts necesarios para quese ejecuten el resto de controles. Sin másconfiguración. Simple, ¿verdad?

Aun así, el control ScriptManager tie-ne varias propiedades que es interesantetener en cuenta y que se presentan en lafigura 3. Este control es el responsable decargar, en función del navegador utiliza-do y sus posibilidades, los ficheros concódigo Javascript de Microsoft AJAXLibrary incluidos como recursos en la pro-pia DLL de AJAX Extensions. Comoambos productos (AJAX Library y AJAXExtensions) se versionan y distribuyenindependientemente, existe la posibilidadde que surjan cambios en AJAX Libraryque no se incluyan directamente en AJAXExtensions, y por tanto, la más importante

de las propiedades del control ScriptMa-nager es ScriptPath; a través de ella pode-mos especificar la ruta a los scripts deAJAX en caso de utilizar una versión dis-tinta o incluso modificada por nosotrosmismos; otras propiedades como Scrip-tLoadTimeout y AsyncPostBackTimeoutnospermiten controlar el tiempo de esperapara la carga de scripts y la respuesta depeticiones al servidor a través del objetoXmlHTTPRequest; o incluso disponemos deopciones para gestionar los errores pro-ducidos durante las peticiones asíncronas.

Una vez se dispone de un controlScriptManager en la página .aspx, el res-to de los controles pueden registrar susscripts y hacer uso de los postbacks asín-cronos. Este control es necesario en cadapágina para poder habilitar la funcio-nalidad de AJAX Extensions, es obliga-torio, y además solo puede existir unopor página; pero entonces ¿qué pasa encasos como aquellos en los que se utili-zan MasterPages o UserControls? Puesbien, la práctica habitual es incluir unScriptManager en la página principal, laMasterPage en caso de existir, y en el res-to de páginas utilizar el control Script-ManagerProxy. Este control proporcionala misma funcionalidad que el primero,pero no registra todos los servicios yscripts, sino solo aquellos elementos sus-ceptibles de ser variables; por ejemplo,referencias a servicios, scripts propios oservicios de autenticación. Se puedenincluir tantos proxies como sea necesa-rio, pero ha de existir al menos un con-trol ScriptManager en la jerarquía de lapágina durante el proceso de renderi-zación de la misma. En tiempo de eje-cución, la información proporcionadaen el control principal y todos los pro-xies se mezcla para ser enviada al clien-te como una única pieza, lo que pro-porciona una solución inteligente y efi-

Figura 2.Controles de AJAX Extensions

Figura 3. Propiedades del controlScriptManager

dnm.asp.net.ajax<<

dotN

etM

anía

<<

28

caz para aplicaciones Web, general-mente bastante modulares.

La modularidad es importante en laWeb, de ahí que UserControls y Master-Pages proporcionen reusabilidad y ver-satilidad durante el desarrollo. Sinembargo, a la hora de la puesta en pro-ducción es otra funcionalidad de .NETla que resulta extremadamente útil: losficheros de configuración. El controlScriptManager no podía ser menos, y parasimplificar las tareas de carga de pará-metros de la configuración incluye unapropiedad Expressions que permiteespecificar desde dónde se cargará elvalor asignado a cada propiedad del con-trol. En la figura 4 se puede apreciarcomo cada una de las propiedades delcontrol se mapea a una expresión paralocalizarla en una base de datos, fiche-ro de configuración o de los recursos dela aplicación. Todo un detalle.

Y entonces, ¿cómo orquestolas peticiones asíncronas?

Todo lo que AJAX predica gira entorno a realizar peticiones asíncronasal servidor; por debajo, sin que elusuario perciba dicha petición y ofre-ciéndole una interfaz más dinámicadonde no se producen constantesrecargas de la página. Por tanto, elprincipal objetivo de diseño de apli-caciones Web orientadas a AJAX con-siste básicamente en determinar lazona o zonas de la página que sufriránactualizaciones asíncronas.

Como ejemplo, utilizaremos la Webde dotNetManía para detectar las zonasque son actualizables independientemen-te. En la figura 5 se puede visualizar cómose desea generar la página, y a simple vis-ta se pueden detectar tres áreas indepen-dientes que pueden actualizarse de mane-ra asíncrona e independiente o que no esnecesario que se actualicen siempre: lacabecera, el menú lateral izquierdo y laparte central de contenido. Con esta sim-ple detección de áreas obtenemos las sec-ciones de la figura 6 y podemos comen-zar a utilizar el control UpdatePanel.

Una vez están claras laszonas actualizables en lapágina, necesitamos uncontenedor lógico que per-mita su actualización asín-crona. En AJAX Extensionseste contenedor es el con-trol UpdatePanel y funcionaexactamente como eso, uncontenedor. Al igual que elresto de contenedores deASP.NET (PlaceHolder oPanel), permite incluir ensu interior todos aquelloscontroles ASP.NET oHTML necesarios paramaquetar la página desea-da. Como peculiaridad, hayque decir que los controlesque se anidan en su interiorhan de ir incluidos entre lasetiquetas ContentTemplate;de esta forma, sería necesa-rio el código del fuente 2para incluir un botón den-tro de un UpdatePanel. Eldiseñador de Visual Studio2005 se encarga de añadirestos tags automáticamenteal arrastrar cualquier con-trol dentro de un UpdatePa-nel, pero hay que tenerlo encuenta si incluimos contro-les directamente en la vistade código. Este contenedor,el UpdatePanel, tiene lacapacidad de interceptarcualquier postback que seproduzca en su interior(siempre que no se modifi-que la propiedad Childre-nAsTriggers con el valorfalse) y realizar una llama-da asíncrona al servidor deASP.NET para posterior-mente recoger la respuestay actualizar su contenido.Et voila, esto es lo que sedeseaba; sin embargo, sepuede complicar un pocomás. Con AJAX Extensionssolo se puede realizar una

Figura 4. Expresiones de configuración para el ScriptManager

Figura 5. Página de dotNetManía

Figura 6.Determinación de zonas de actualizaciónindependientes

<asp:UpdatePanel ID=”UpdatePanel1” runat=”server”><ContentTemplate><asp:Button ID=”Button1” runat=”server”

Text=”Button”/></ContentTemplate>

</asp:UpdatePanel>

Fuente 2. Incluyendo contenido en un UpdatePanel

dnm.asp.net.ajax<<

dotN

etM

anía

<<

29

petición asíncrona al servidorcada vez, y se ha de disponer dealgún modo de notificar el esta-do de la misma al usuario. Además, taly como se muestra en la figura 7, dis-ponemos de otras opciones que per-miten controlar el comportamiento decada uno de los controles UpdatePaneldisponibles en la página. En primerlugar, aparece el concepto de triggero disparador, que no es más que unevento que produce un postback en esepanel. Por defecto, todos los contro-les incluidos en el contenido del Upda-tePanel funcionan como disparadoresde la actualización, como indiquéanteriormente, si no se modifica lapropiedad ChildrenAsTriggers; perotambién se puede usar como dispara-dor de actualización un evento lanza-do por un control que no se encuen-tra en su interior. La propiedad Trig-gers representa una colección de dis-paradores donde se puede seleccionara través del cuadro de diálogo mos-trado en la figura 8 los controles de lapágina y los eventos de los mismos queprovocarán una actualización delpanel; en la vista de código de la pági-na, se añaden los triggers tal y comose muestra en el fuente 3.

Hasta este punto, como veis, es bas-tante sencillo incluir, sin apenas escri-bir código, áreas que se actualicen demanera asíncrona en aplicaciones Web.Ahora se es capaz de crear una páginaque soporte AJAX Extensions, añadirun ScriptManager y un par de UpdatePa-nel que realizan operaciones asíncronas;y todo ello sin despeinarse lo más míni-mo y aplicándolo al código ASP.NETque existe actualmente en la mayor par-te de aplicaciones Web, sin modifica-ciones. Sin embargo, uno de los puntosque quedan pendientes con respecto ala actualización asíncrona de conteni-dos es la monitorización del progreso.

Algo más de control sobre elasincronismo

Controlar el progreso de un Upda-tePanel es relativamente sencillo.Generalmente se desea mostrar alusuario qué tarea se está realizando ysi aún sigue procesándose. Como nopodía ser menos, disponemos de uncontrol creado para este propósito yse llama UpdateProgress. Este controlfunciona como un contenedor, al igualque el UpdatePanel, y puede contenercualquier control ASP.NET o HTMLque se desee mostrar al usuario mien-tras se realiza la operación; lo idealsería una imagen animada que indica-se que algún tipo de proceso se está

realizando. Un único controlUpdateProgress puede controlartoda la actividad de los UpdatePa-

nel de una página, mostrando el mis-mo mensaje para todos ellos según sevan produciendo actualizaciones en sucontenido. Sin embargo, es posibleque este no sea el comportamientoesperado y se desee utilizar varios con-troles UpdateProgress que monitori-cen diferentes UpdatePanel. Por estemotivo, tal y como se muestra en lafigura 9, se puede especificar el Upda-tePanel cuyo progreso será monitori-zado en la propiedad AssociatedUpda-tePanelID del control UpdateProgress,facilitando aún más la labor del desa-rrollador. También es convenienteestablecer el tiempo que esperará elcontrol al producirse una peticiónasíncrona antes de mostrar el panel deprogreso; de esta forma en conexio-nes rápidas o locales no será necesa-rio mostrar dicho panel.

En los procesos de actualización decontenidos, al realizarse de manera asín-crona y solo poder realizarse uno simultá-neamente (una segunda petición asín-crona cancela la anterior), es importantedisponer de una opción que permita can-celar la petición en curso. Esta funciona-lidad se puede implementar de cara a lainterfaz de usuario o simplemente utili-zarla desde el código Javascript en clien-te. En el ejemplo que se muestra en lafigura 10 se ha creado el código HTMLnecesario para mostrar el progreso através de un GIF animado y un enlace

Figura 7. Propiedades delcontrol UpdatePanel

Figura 8.Colección de triggers del control UpdatePanel

<Triggers><asp:AsyncPostBackTrigger

ControlID=”Button1”EventName=”Click” />

</Triggers>

Fuente 3. Enlazando triggers via HTML

Figura 9. Propiedades delcontrol UpdateProgress

dnm.asp.net.ajax<<

dotN

etM

anía

<<

30

para poder cancelar el mismo. Pero,¿cómo cancelamos una petición asíncro-na que ya está en curso? Es sencillo, perohay que tocar código Javascript en el ladodel cliente. Se necesita hacer uso de lajerarquía de espacios de nombres de AJAXLibrary para obtener una instancia delobjeto PageRequestManager, ubicado enSys.WebForms.PageRequestManager. Esteobjeto es el responsable de actualizar con-tenidos parciales en la página, definidospor el uso de diferentes UpdatePanel y unScriptManager, por lo que no es necesa-rio crear una instancia del mismo sinoobtener la existente. A partir de la tabla1se puede inferir que la lógica para cance-lar la operación asíncrona incluirá obte-ner el objeto PageRequestManager actuala través del método getInstance, paraposteriormente comprobar el valor de lapropiedad isInAsyncPostBack y en casode que sea verdadero, llamar al métodoabortPostBack. Solo queda mostrar elcódigo (fuente 4) que introduce el ejem-

plo de la figura 10 y crea una función encliente para detener el postback asíncronocuando el usuario hace clic sobre el tex-to de cancelación.

A veces, los procesos de carga asín-crona no tienen por qué ser provocadospor el usuario. Por ejemplo, en una apli-cación de correo Web es la propia aplica-ción la que cada determinado tiempo se

encarga de verificar si hay nuevos mensa-jes en el buzón, y en tal caso determinaqué controles han de actualizarse. Estecomportamiento está totalmente sopor-tado por AJAX Extensions, y para ello dis-ponemos del último de los cinco contro-les: el control Timer. Como su nombreindica, es un temporizador que ejecutauna porción de código cada cierto inter-valo y toma decisiones en función de susresultados. Este control puede funcionarcomo disparador para uno o varios con-troles UpdatePanel. En la figura 11 se pue-de observar que la propiedad Intervalnosproporciona el intervalo de tiempo en quequeremos lanzar una actividad en el ser-vidor a través del evento Tick; y es en el

<script language=”javascript” type=”text/javascript”><!— var prm = Sys.WebForms.PageRequestManager.getInstance();

function CancelAsyncPostBack() {if (prm.get_isInAsyncPostBack()) {prm.abortPostBack();

}}

// —></script>

<asp:UpdateProgress ID=”UpdateProgress1” runat=”server”><ProgressTemplate>

<div><img src=”loader.gif” />Cargando,

<a href=”” onclick=”CancelAsyncPostBack()”>clic aquí para cancelar</a></div>

</ProgressTemplate></asp:UpdateProgress>

Fuente 4.Cancelando una petición asíncrona al servidor

EventosinitializeRequest Se lanza antes de procesar una petición asíncrona.beginRequest Se lanza antes de procesar un postback asíncrono al servidor.

pageLoadingSe lanza tras recibir la respuesta del servidor a una petición asín-crona, pero antes de recibir contenido.

pageLoadedSe lanza una vez se ha refrescado la pagina síncrona o asíncro-namente.

endRequestSe lanza una vez se ha finalizado un postback asíncrono y se devuel-ve el control al navegador.

MétodosTaskAdded Detiene la ejecución del postback en curso.TaskModified Libera los recursos en el cliente.

TaskNavigated Obtiene la instancia actual del objeto PageRequestManager.

Propiedades

OnContextChangedVariable booleana que indica si se está realizando un postback asín-crono.

Tabla 1. PageRequestManager: Eventos,métodos y propiedades

Figura 10. Ejemplo deUpdateProgress con

control de cancelación

Figura 11. Propiedades delcontrol Timer

dnm.asp.net.ajax<<

dotN

etM

anía

<<

32

controlador de este evento donde reali-zamos las actualizaciones necesarias sobrelos UpdatePanel y decidimos cómo actua-lizar los mismos:

1. Directamente en código de servi-dor mediante la propiedad Upda-te de los objetos UpdatePanel quese desea actualizar.

2. Incluyendo el control Timer den-tro de un UpdatePanel, de maneraque actúe como disparador delproceso de actualización asíncro-na automática.

3. Ubicando el control Timer fuera decualquier UpdatePanel y utilizandotriggers para enlazar cada UpdatePa-nel con el evento Tick del Timer, deforma que funcione como dispara-dor de actualización asíncrona.

¿Y no hay nada de serviciosWeb?

Hasta este momento, hemos vistocómo realizar las tareas necesarias paraactualizar nuestras aplicacionesASP.NET con las AJAX Extensions, yde manera sencilla hemos conseguidohacerlas más dinámicas. Sin embargo,falta una de las funcionalidades másimportantes incluidas en AJAX Libraryy es la integración con servicios Web: laposibilidad de llamar a código de servi-dor desde Javascript sin necesidad derealizar un postback.

Lo primero que hace falta es dispo-ner de un servicio Web que utilizar, ypuede ser cualquiera, como por ejem-plo, el mostrado en el fuente 5: el ser-vicio de ejemplo creado por la plantilla“Nuevo servicio Web de Visual Studio2005”. Para que un servicio Web se pue-da ejecutar desde Javascript a través deAJAX Library, ha de cumplir ciertosrequisitos:

1. El servicio ha de ser local aldominio de ejecución de la pági-na que lo ejecutará. Esto es debi-do a que el objeto XmlHTTPRequestno puede realizar peticionessobre URL remotas por motivosde seguridad.

2. El servicio Web ha de ser marcadocon el atributo [ScriptService].

3. En el fichero Web.config de la apli-cación tiene que existir una entra-da para que los ficheros .asmx seanmanejados por el controlador deAJAX Extensions; configuraciónpor defecto utilizando la nuevaplantilla de sitios Web.

4. Se ha de añadir una referencia alservicio en la página que lo vayaa utilizar. Esta referencia se aña-de al control ScriptManager, biena través de sus propiedades o biena través del código HTML, tal ycomo se muestra en el fuente 6.

Una vez se han cumplido todos estosrequisitos, es posible realizar una lla-

mada a los métodos del servicio Webdirectamente desde Javascript. Lanomenclatura a utilizar para llamar a losmétodos es espacionombre.clase.méto-do(parámetros); por tanto, para el ejem-plo de servicio mostrado anteriormen-te se debería realizar la llamada con Mis-Servicios.WebService.HelloWorld().Esta llamada al servicio Web se realizaa través de un proxy, mostrado en elfuente 7, que se genera en Javascript. Elcontrolador o handler incluido en elfichero Web.config para la extensión.asmx ha sido el responsable de generareste proxy; se encarga de monitorizar lasllamadas a este tipo de ficheros y deter-minar cuándo tiene que generar el códi-go Javascript para llamarlo. El códigogenerado se puede visualizar añadiendo

using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Web.Script.Services;

namespace MisServicios{

/// <summary>/// Summary description for WebService/// </summary>[WebService(Namespace = “http://tempuri.org/”)][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][ScriptService]public class WebService : System.Web.Services.WebService{

public WebService(){

//Uncomment the following line if using designed components //InitializeComponent();

}

[WebMethod]public string HelloWorld(){

return “Hello World”;}

}}

Fuente 5. Servicio Web habilitado para usarse desde cliente Javascript

<asp:ScriptManager ID=”ScriptManager1” runat=”server”><Services><asp:ServiceReference Path=”WebService.asmx” />

</Services></asp:ScriptManager>

Fuente 6.Referencia a un servicio Web en el control ScriptManager

dnm.asp.net.ajax<<

dotN

etM

anía

<<

33

el sufijo /js al final de un servicio Webque tenga las extensiones AJAX habili-tadas según los pasos comentados ante-riormente; éste es el código que se eje-cutará desde Javascript en el cliente.

Pero según parece, las peticiones aURL remotas no se pueden realizar y portanto ¿no se pueden utilizar serviciosWeb de terceros? La respuesta directa esque no, no se puede. Pero sí se puede rea-lizar un servicio puente o bridge en nues-tro servidor para que enlace con ese ser-vicio de terceros; este servicio sí puedeser utilizado desde nuestra interfaz deusuario Web con AJAX Extensions.Algunas veces, llamar a servicios Web opensar en separar la lógica de las páginasen servicios puede resultar tedioso, com-plicado o incluso imposible dada la varie-dad de funciones que se desean ejecutar.Para estos casos existe una versión máscómoda de utilizar que los servicios Web:los PageMethods. Estos métodos se com-portan de manera similar a los serviciosWeb, ya que es código de servidor quese puede ejecutar directamente desde

Javascript en cliente; la diferencia radicaen que estos métodos no pertenecen aservicios Web, sino a la propia página.aspx en que se desean utilizar, y por tan-to no hace falta añadirlos como referen-cia. Para crear y usar un PageMethod hayque realizar los siguientes pasos:

1. Crear el método en la página.aspx y marcarlo con los modifi-cadores de acceso public y static(en C#, claro).

2. Utilizar el método directamentedesde el cliente a través de la cla-se PageMethods con la sintaxis Page-Methods.NombreMétodo(parámetros).

Mucho más sencillo, ¿no?

ConclusionesExisten múltiples alternativas para

incluir AJAX en nuestras aplicacionesWeb, pero está claro que la presenta-da por Microsoft AJAX ASP.NETExtensions es una de las más sencillasde utilizar. Proporciona los elemen-

tos necesarios para realizar, sin mayoresfuerzo y complejidad, las tareas máscomunes de las aplicaciones Web asín-cronas. Aún queda mucho más por verde AJAX en el lado del cliente conMicrosoft AJAX Library; en el lado deservidor con AJAX Control Toolkit; ysobre las novedades inminentes deAJAX Futures.

Espero que estas líneas resulten deutilidad para que comencéis a utilizareste framework gratuito que dará esapequeña chispa que falta en las aplica-ciones Web desarrolladas con ASP.NET2.0, ¿o acaso pensabais que íbamos adejar de aprender?

Type.registerNamespace(‘MisServicios’);

MisServicios.WebService=function() {MisServicios.WebService.initializeBase(this);this._timeout = 0;this._userContext = null;this._succeeded = null;this._failed = null;

}MisServicios.WebService.prototype={HelloWorld:function(succeededCallback, failedCallback, userContext) {return this._invoke(MisServicios.WebService.get_path(), ‘HelloWorld’,false,{},succeededCallback,failedCallback,userContext); }}

MisServicios.WebService.registerClass(‘MisServicios.WebService’,Sys.Net.WebServiceProxy);MisServicios.WebService._staticInstance = new MisServicios.WebService();MisServicios.WebService.set_path = function(value) { MisServicios.WebService._staticInstance._path = value; }MisServicios.WebService.get_path = function() { return MisServicios.WebService._staticInstance._path; }MisServicios.WebService.set_timeout = function(value) { MisServicios.WebService._staticInstance._timeout = value; }MisServicios.WebService.get_timeout = function() { return MisServicios.WebService._staticInstance._timeout; }MisServicios.WebService.set_defaultUserContext = function(value) { MisServicios.WebService._staticInstance._userContext = value; }MisServicios.WebService.get_defaultUserContext = function() { return MisServicios.WebService._staticInstance._userContext; }MisServicios.WebService.set_defaultSucceededCallback = function(value) { MisServicios.WebService._staticInstance._succeeded = value; }MisServicios.WebService.get_defaultSucceededCallback = function() { return MisServicios.WebService._staticInstance._succeeded; }MisServicios.WebService.set_defaultFailedCallback = function(value) { MisServicios.WebService._staticInstance._failed = value; }MisServicios.WebService.get_defaultFailedCallback = function() { return MisServicios.WebService._staticInstance._failed; }MisServicios.WebService.set_path(“/AJAXEnabledWebSite1/WebService.asmx”);MisServicios.WebService.HelloWorld=

function(onSuccess,onFailed,userContext) {MisServicios.WebService._staticInstance.HelloWorld(onSuccess,onFailed,userContext); }

Fuente 7. Proxy Javascript para llamar a un servicio Web

Referencias

[1] Microsoft Atlas, http://atlas.asp.net.

[2] Scott Guthrie, http://weblogs.asp.net/scottgu.

[3] Javascript Object Notation (JSON),http://www.json.org.

[4] Nikhil Kothari, http://www.nikhilk.net.

En agosto de 1994 se editó un libro que inició uncambio en la forma de entender y trabajar en arqui-tectura de software, estableciendo unas bases que sehan ido asentando durante estos ya más de diez añostranscurridos desde su publicación. El título del libroes “Design Patterns: Elements of Reusable Object-Oriented Software” (traducido y publicado enespañol por la editorial Pearson en 2003), de losautores Erich Gamma, Richard Helm, Ralph Jon-son y John Vlissides. Este equipo de autores tam-bién es conocido como el “Gang of Four” o GoF,literalmente, “la banda de los cuatro”.

Puede afirmarse que este libro, basado en la tesisdoctoral de Erich Gamma, ha revolucionado laarquitectura de software y llevado el diseño orien-tado a objetos a un nivel más alto. Si bien es ciertoque, como la gran mayoría de inventores, el crea-dor real del concepto de patrones permaneció rela-tivamente en el olvido. La persona que hay detrásde los patrones de diseño es el arquitecto Chris-topher Alexander, que durante 1970 escribió doslibros, “A Pattern Language” y “A Timeless Wayof Building”, que además de ofrecer ejemplos des-cribió sus razonamientos para documentar los patro-nes. Desde entonces, el movimiento pro-patronesestuvo muy quieto hasta 1987, momento en el quevolvieron a resurgir, teniendo como resultado latesis doctoral de Erich Gamma (1991) y finalmen-te, la publicación del libro citado inicialmente, queinicio el fenómeno de los patrones de diseño queactualmente conocemos. Para que nos hagamos una

idea de la importancia de la labor de Alexander,podemos afirmar que ésta es similar a la de NoamChomsky en el área de los lenguajes computacio-nales, pero aplicada a la arquitectura de software(más información en http://es.wikipedia.org/wiki/Christopher_Alexander).

“El lenguaje de patrones brinda a todo el quelo utilice el poder de crear una infinita variedad deconstrucciones nuevas y únicas, de la misma formaque su lenguaje común le brinda el poder de crearuna infinita variedad de oraciones." ChristopherAlexander.

Patrones de diseño: ¿por qué?, ¿paraqué? y ¿cómo?

¿Por qué?

Seguramente os estaréis preguntando por quédeberíamos darle a este tema importancia o inclusonuestro tiempo, un bien tan escaso hoy en día, en elque aparecen nuevas tecnologías tan fascinantescomo complejas y casi de estudio requerido... en elque los proyectos se nos acumulan, se complican yrequieren que dediquemos horas extra, tanto en eltrabajo como fuera de él, para auto-formarnos ypoder resolver el problema que nos ha dejado “blo-queados” hoy al día siguiente… con el consabido yya asumido problema de la falta de tiempo (y en algu-nos casos, de sueño).

Introducción a los

Patrones de diseño

metodología

JJoosséé LLuuiiss LLaattoorrrree esarquitecto de softwareespecializado en .NET.

También es el fundadory coordinador del gru-

po de usuarios .NETde Barcelona

(wwwwww..BBccnnDDeevv..nneett) yactualmente trabaja

como consultor .NETen SSeerrtteecc SSoolluucciioonneess

IInnffoorrmmááttiiccaass.

¿Para qué inventar una solución si ésta ya existe? Básicamente,esa es la premisaque siguen los patrones de diseño y que tantos arquitectos han adoptado.Seguido os introducimos de lleno en ellos y os proponemos cambiar vuestropunto de vista en el a veces complejo mundo de la arquitectura de software.

José Luis Latorre

La respuesta la podríamos resumir en una simplefrase: “porque alguien ya ha resuelto tu problema”.Así de simple, así de fácil… Además, las solucionesestán escritas, catalogadas y clasificadas.

Básicamente, los patrones de diseño son el con-junto de experiencias de un gran número de desarro-lladores y arquitectos de software, clasificados segúnlos problemas más frecuentes en el diseño de softwa-re. Y además, nos encanta la reusabilidad, ¿no? Todosllevamos un gran vago dentro y nos encanta solucio-nar un problema o proponer una solución con elmenor esfuerzo posible. Y si luego de resolverlo vemosque encima es la solución más optima en flexibilidad,adaptabilidad y con el menor acoplamiento posible,mejor aún, ¿no?

Como resumen de lo dicho, he aquí otro párrafode Christopher Alexander, citado en el ya menciona-do libro del GoF, en la sección 1.1: “¿Qué es un patrónde diseño? Cada patrón describe un problema queocurre una y otra vez en nuestro entorno, así como lasolución a ese problema, de tal modo que se puedaaplicar esta solución un millón de veces, sin hacer lomismo dos veces.”

¿Para qué?

Bueno, si esto no os convence y sois de la opinión“bueno, vale, los patrones pueden ayudarme, pero¿para qué quiero aprenderlos si no me los van a valo-rar?”. Básicamente, la respuesta vuelve a ser una fra-se: “para no reinventar la rueda, para aprovechar poruna vía menos dura que la experiencia propia la expe-riencia de los demás…”.

Para proveer a nuestros clientes de soluciones pro-badas y consistentes, además de flexibles. Sí, en cier-to modo me repito, pero es importante tener esto cla-ro, ya que muchas veces quizás no nos vayan a apre-ciar el realizar un diseño de software adecuado, excep-to cuando tengamos que modificarlo nosotros mis-mos o algún compañero, en cuyo caso estaremoshaciéndonos un favor, así como a nuestros compañe-ros, dado que no saldrá la tan típica expresión “estoes un bodrio… quien haya hecho esto...“, cosa que,profesionalmente, nos conviene… También puedendecir “esto es realmente complejo, no lo entiendo”,lo cual también nos compensará, dado que solo conhacer la pregunta “¿te suena el concepto de patronesde diseño?” nos habremos posicionado como arqui-tectos de software.

Con la aplicación de los patrones, estaremos prove-yendo a nuestros diseños de software de un lenguajecomún que otros arquitectos podrán comprender ymediante el cual podremos dialogar con ellos. Tambiénnos mejorará como desarrolladores, o mejor dicho, comolos arquitectos de software que pretendemos ser.

Podría citar muchas otras razones de porqué uti-lizar patrones de diseño, pero todas se reducen a unamuy clara y simple, que nos sonará si hemos traba-jado algún tiempo con diseño orientado a objetos:evitar los errores (o dudas) más comunes de la POO(Programación Orientada a Objetos); la programaciónorientada a objetos está aún en pañales, y mi expe-riencia con otros profesionales me indica que no sele da la importancia que merece, tanto en centros deformación como en universidades, de las cuales lagente sale sin un conocimiento de la programación“real”, con mucha confusión sobre el desarrollo orien-tado a objetos, quedando éste muy borroso, y con lasensación –muy real– de que solo es aprendidomediante la experiencia; algo costoso y doloroso, enmuchos casos.

Para verlo algo más claro, ¿qué mejor que unejemplo?

Un error muy común, por ejemplo, es la “muer-te por herencia”. Si tenemos una aplicación que debeacceder a un objeto de un determinado tipo (el tipoes de una “clase base”), teniendo la arquitectura quese muestra en la figura 1, entonces el desarrolladortiene (si no ha declarado la clase base como privadaen la clase derivada) acceso completo a los métodosde la clase base, y la clase derivada debe asegurarse deimplementar todas las funcionalidades de la clase base.

Lo cual, plasmado en código, queda según semuestra en la figura 2 y el fuente 1.

Esto nos parece realmente correcto, pero en larealidad Murphy existe y sus leyes se cumplen…Podemos perder el control de la clase base, quedan-do ésta bajo el control de otro desarrollador quizásmenos comunicativo que nosotros y que “protege sutrabajo”, con lo que no tenemos opción o elecciónsobre la implementación de la clase base, pudiendotener destructores no virtuales, o métodos que no

dotN

etM

anía

<<

35

dnm.plataforma.net<<

Figura 1

dotN

etM

anía

<<

36

dnm.plataforma.net<<

han sido declarados como virtuales, ymiembros privados... Todo ello nosdetermina de una forma drástica y noshace imposible especializar un objetovía derivación.

Otra preocupación sobre la progra-mación “por herencia” es el crecimien-to de una estructura de herencia rígida,pudiendo aparecer problemas en lo queal principio parecía la solución ideal.Básicamente, las clases base pueden des-trozar una aplicación con tan solo cam-biar ligeramente su implementación(figura 3).

Para solucionar este problema,tenemos el patrón de diseño Façade

(fachada), que nos “proporciona unainterfaz unificada para un conjunto deinterfaces de un subsistema”, según ellibro “Patrones de diseño”. Diciéndo-lo de una forma más comprensible, nosindica que utilicemos la encapsulaciónpara implementar un wrapper (envol-torio) alrededor de otros objetos, algoque con la simple herencia no pode-mos hacer. Con ello tendríamos losiguiente (figura 4).

Figura 2

Public Class ClaseBasePublic Sub HazAlgo()Console.WriteLine(“HazAlgo”)

End SubEnd Class

Public Class ClaseDerivadaInherits ClaseBase

Public Sub HazAlgoMas()Console.WriteLine(“HazAlgoMas”)

End SubEnd Class

Module Module1Sub Main()Dim o_ClaseBase As New ClaseBaseDim o_ClaseDerivada As New

ClaseDerivada

o_ClaseDerivada.HazAlgo()o_ClaseDerivada.HazAlgoMas()

System.Console.ReadLine()End Sub

End Module

Fuente 1

Figura 3

Figura 4

NOTA

Los métodos virtuales son aque-llos que pueden ser redefinidosen una clase derivada, pero no esimprescindible hacerlo. Si unmétodo no se redefine, se utilizaráel de la clase base.

][

dotN

etM

anía

<<

37

dnm.plataforma.net<<

Esto, expresado en código, quedaríacomo se muestra en el fuente 2.

Es decir, no deberemos modificar laaplicación para que continúe funcionan-do; solamente deberíamos adaptar la cla-se externa que hace las veces de fachada,con lo que tendríamos una mejor soluciónque simplemente aplicando la herencia,obteniendo a la vez con ello un manteni-miento mucho menos costoso.

Como hemos podido ver, las ventajasde aplicar los patrones de diseño son cla-ramente evidentes, no solo en lo que res-pecta a la calidad del código o a su implí-cita reducción de costes, sino también encuanto a acceso, soporte, diseño, extensi-bilidad y flexibilidad.

Conceptos de los patrones dediseño

Es importante, antes de ver los dife-rentes patrones existentes y su clasifi-cación, analizar las característicascomunes entre ellos y los conceptosque comparten.

El más importante de todos es quelos patrones no son implementacionesde código para un problema concreto.No es de código de lo que tratan lospatrones, sino de conceptos e interac-ción entre ellos, proponiendo solucio-

nes conceptuales que pueden tener muydiversas formas de implementación;cada cual deberá adaptarlos a su pro-blema y arquitectura concretos.

Los patrones de diseño básicamente,soluciones conceptuales que tratan sobreel diseño e interacción entre objetos y pro-porcionan soluciones reutilizables pararesolver los problemas más comunes. Serepresentan normalmente mediante laayuda de un diagrama UML.

Existen unos principios funda-mentales de diseño, que son subya-centes a los patrones de diseño, sien-do el principio para la creación desoluciones flexibles:

• Programar para interfaces y nopara una implementación (obje-tos).

• Potenciar la composición de obje-tos frente la herencia de clases.

Derivados de éstos, tenemos otrosdos principios no menos importantes:

• Determinar qué es común y quées variable.

• Encapsular las secciones identifi-cadas como variables medianteuna interfaz común.

Por ejemplo, si definimos la interfazIPerro y una clase cPastorAleman que laimplemente (figura 5 y fuente 3).

Public Class FachadaPrivate mClaseBase As ClaseBase

Public Sub HazAlgo()mClaseBase.HazAlgo()

End SubEnd Class

Module Module1Sub Main()Dim o_ClaseBase As New ClaseBaseDim o_ClaseDerivada As New

ClaseDerivada

o_ClaseDerivada.HazAlgo()o_ClaseDerivada.HazAlgoMas()

‘Ejemplo con la FachadaDim o_Fachada As New Fachadao_Fachada.HazAlgo()System.Console.ReadLine()

End SubEnd Module

Fuente 2

Figura 5

Public Interface IPerroReadOnly Property Raza() As StringSub Ladra()Sub MenearCola()

End Interface

Public Class cPastorAlemanImplements IPerroPublic Sub Ladra() Implements IPerro.Ladra

System.Console.WriteLine(“Guau!”)End SubPublic Sub MenearCola() Implements IPerro.MenearCola

‘Meneamos la colaEnd SubPrivate m_sRaza As StringPublic ReadOnly Property Raza() As String Implements IPerro.Raza

GetReturn m_sRaza

End GetEnd PropertyPublic Sub New()

m_sRaza = “Pastor Alemán”End Sub

End Class

Fuente 3

NOTA

Cuando se habla de patronesde diseño, al mencionar “inter-faz” no nos referimos a la fir-ma de clases, técnicamentehablando, sino a un supertipo,que puede ser en su imple-mentación una interfaz o unaclase abstracta.

][

dotN

etM

anía

<<

38

dnm.plataforma.net<<

Esto sería programar para unaimplementación:

Dim Carla As cPastorAleman = New cPastorAleman

Carla.Ladra()

Declarar la variable Carla del tipocPastorAleman, una implementaciónconcreta de IPerro, nos fuerza a codi-ficar sobre una implementación con-creta.

Pero programar para una interfaz osupertipo, por ejemplo:

Dim Carla As IPerro = New cPastorAleman

Carla.Ladra()

Es mucho mejor, ya que sabemosque Carla es un pastor animal, peropodemos utilizar la referencia a IPe-rro polimórficamente, con lo cual enlugar de “fijar” en el código la instan-ciación de un subtipo, podríamos asig-nar la implementación concreta entiempo de ejecución, haciendo aúnmás flexible nuestro código. Es más,podemos añadir diferentes tipos deperro a nuestra aplicación y éstaseguirá trabajando con ellos sinningún cambio, mientras que de laotra forma, deberíamos programarcódigo para cada nueva raza.

Cabe destacar que los conceptos oprincipios que hemos visto, además deser las bases de los patrones de diseño,son las bases de un correcto diseñoorientado a objetos. Los patrones dediseño se consideran como la evoluciónde estos mismos conceptos, por lo quees muy importante entenderlos bien ytenerlos en mente.

Clasificación de los patronesde diseño

Hay tres tipos de patrones de diseño:• Creacionales: abstraen el proce-

so de creación de instancias deobjetos, ayudando a hacer unsistema que sea independientede los procesos de creación,composición y representaciónde los mismos.

• Estructurales: enfocan los proble-mas de composición, estructura-ción y herencia de clases y obje-tos, así como su uso para compo-ner estructuras de mayor tamaño.

• De comportamiento: son aquellospatrones que se centran en mejo-rar el modo en que las clases yobjetos interactúan y se comuni-can entre ellos, repartiendo su res-ponsabilidad.

Actualmente hay identificados 23patrones de diseño, que se listan en latabla 1. No entraremos en detalles aquí,ya que citarlos sin entrar en su “salsa”es como insultarlos; cada uno de ellosse merece un artículo entero para él, asíson de importantes y potentes…

¿Cómo y cuándo utilizarlos? (ycuándo no)

Aquí no se trata de reutilizar código,sino experiencia. Los patrones de diseñoson conceptos y organización de los mis-mos que se transfieren fácilmente a códi-go; pero lo que nos tiene que quedar cla-ro son los conceptos y no el código (ojo:también ayuda, pero uno sin lo otro notiene sentido). Si sólo aprendemos el códi-go estaremos aprendiendo solamente eltruco y no la técnica subyacente, que es loque realmente importa. Si aprendemoslos conceptos subyacentes, evolucionamoscomo arquitectos de software y aumenta-mos realmente nuestras armas de com-prensión y solventación de problemas.

Para saber usar los patrones dediseño hay que conocerlos, saber reco-nocerlos, entenderlos y comprendersus ventajas y beneficios, para luegoaprender a implementarlos. Un ejer-cicio muy bueno consiste en identifi-car los patrones de diseño en nuestrodía a día, tanto en .NET Frameworkcomo en la “vida real”. Por ejemplo,un patrón de diseño de tipo façade lopodemos hallar en nuestro reproduc-tor MP3, en el cual hay un wrapperque encapsula la complejidad internay nos proporciona los métodos play,stop, pause, etc. Otro muy buen ejer-cicio es tratar de encontrar estospatrones dentro de nuestro código;esto nos desvinculará de la compleji-dad de abstraer estos conceptos en un

entorno ya abstracto depor sí como son las líne-as de código.

Por último, tambiénhay que tener en cuentaque pese a ser unas estu-pendas herramientas, noson “la técnica” definitivani la solución a todo. Nohay que caer en la defini-ción de desarrollador pat-tern happy, que a todo loque toca intenta aplicarlecuanto más patrones,mejor. Hay momentos enlos que aplicar patrones ytambién los hay para nohacerlo.

ReferenciasRecomiendo sinceramente el libro

de referencia que inició este cambio enel campo de la arquitectura de softwa-re: “Patrones de diseño: elementos desoftware orientado a objetos reutiliza-ble”, de Erich Gamma, Richard Helm,Ralph Jonson y John Vlissides (Pear-son/Addison Wesley). Igualmente reco-miendo el libro “Head First Design Pat-terns”, de Elisabeth Freeman y EricFreeman (editorial O’Reilly), querecientemente descubrí mientras medocumentaba para este artículo y cuyaexposición de los patrones de diseño esrealmente magnífica.

Creacionales Estructurales De comportamiento

Factory Adapter Interpreter

Abstract Factory Bridge Template MethodBuilder Composite Chain of Responsability

Singleton Decorador Command

Facade Iterator

Flyweight MediatorProxy Memento

ObserverStateStrategyVisitor

Tabla 1.Patrones de diseño identificados actualmente

Para las organizaciones y usuarios individuales, laproblemática del correo basura no se ha presentadocomo un inconveniente de primera magnitud hastahace muy poco tiempo. Hasta hace poco, se ha veni-do considerando este correo solo como un incordio.En la actualidad, la proliferación del spam ha pro-vocado que sea la primera amenaza externa a la quese enfrenta cualquier administrador de sistemas. Másprobable y dañina que las intrusiones o los virus.

El riesgo implícito en el spam no se reduce a las“molestias” que causa a los usuarios. El spam es unaamenaza de primer orden que debe neutralizarse pordiversos motivos. El más inmediato de sus efectos nega-tivos es la pérdida de productividad que representa paralos usuarios, que deben pasar mucho tiempo de su jor-nada dedicados a purgar el buzón de mensajes espúre-os. Y los técnicos tampoco se libran. Además del tiem-po que deben dedicar a resolver las incidencias que estetipo de mensajes provoca, que no son pocas, está el con-sumo de recursos que lleva aparejado. Ancho de ban-da y tiempo de máquina malgastado inútilmente sonlos principales quebraderos de cabeza que los técnicostienen que afrontar como consecuencia directa del spam.Además, supone un riesgo para la seguridad comopotencial vector de infección de virus y la propagaciónde todo tipo de código malicioso. Los recursos de tiem-po, dinero y personal que se han de dedicar para con-trolarlo no dejan lugar para tomarlo como un simpleincordio.

Para conseguir sus objetivos, los spammers tienenque resolver principalmente dos problemas. Por unaparte, obtener un gran número de direcciones decorreo válidas y en activo para que sus envíos masi-vos proporcionen resultados. Por otra, conseguir quesus mensajes alcancen la bandeja de entrada de esosbuzones de correo. Respecto a esta última “pro-blemática” del spammer, las barreras anti-spam en losservidores de correo son cada vez más frecuentes ylos usuarios también están más concienciados y escar-mentados sobre los inconvenientes que les acarrea elcorreo basura, por lo que los filtros para evitar este

Técnicas de ofuscación de filtros de correo

El éxito del spam

seguridad

JJuuaann BBlláázzqquueezztiene una amplia

experiencia comoinstructor certificado

de los principalesfabricantes y como

colaborador habitualen publicaciones pro-fesionales del sector.

Cuenta con las certifi-caciones MCSE y

MCT de Microsoft,CNE y CNI de

Novell y CLP deLotus.Actualmenteejerce como arqui-

tecto de sistemas enAAllhhaammbbrraa--EEiiddooss.

Pocos son los usuarios que,manteniendo una cuenta de correo activa enInternet, no hayan experimentado en sus propias carnes el incordioconstante y diario de recibir multitud de mensajes con peregrinasofertas.Cuando no es el método definitivo para hacerse multimillonario,es la oferta de milagrosos fármacos de toda índole, cuando no otroscontenidos más procaces.Mensajes que parece imposible detener.

Juan Blázquez

Ranking del spam

A la cabeza de los países “productores” despam se sitúa Estados Unidos, que lanzael 23,2% del total de mensajes basura. Elsegundo puesto está ocupado por Chinacon un 20%, y a continuación va Coreadel Sur, que genera el 7,5%. El rankingeuropeo lo lidera Francia, como origendel 5,2% de este tipo de correo. España,por su parte, genera el 4,8%. ][

tipo de mensajes se establecen a diferen-tes niveles y van perfeccionando su cri-ba, y los spammers deben recurrir a diver-sas estratagemas para sortearlos, que seconocen como técnicas de ofuscación delos filtros de spam.

La mayoría de las técnicas de ofusca-ción de los filtros de spam se aprovechande la gran difusión actual de los mensa-jes cuyo contenido tiene formato HTMLy en la potencia que este lenguaje tiene.Mediante HTML se ocultan los conte-nidos de spam, intentando que pasen desa-percibidos a los motores que inspeccio-nan el correo. Muchas de las herramientas anti-spamtoman la decisión de marcar un mensaje como correobasura en función de las características de este tipo decorrespondencia, como es la presencia de palabras típi-cas que aparecen en estos mensajes. Las técnicas deofuscación intentan reducir la probabilidad de que losmensajes sean marcados como spam enmascarando estascaracterísticas. Entre las técnicas más habituales deofuscación se pueden destacar las siguientes:

Agujero negroEsta estratagema, la más simple, consiste en colocar

caracteres blancos, espacios, entre los caracteres que for-man las palabras que habitualmente son identificadascomo parte de los mensajes de spam. Resulta ya una téc-nica muy común y fácilmente detectable por los actua-les filtros de correo basura. Se sigue utilizando de mane-ra perfeccionada recurriendo a otras tretas, como susti-tuir el espacio en blanco por otro carácter, como un pun-to, guión bajo, etc., que permita mantener la legibilidadde esas palabras. Otra forma más elaborada de utilizaresta técnica es utilizar el código “&nbsp;”, espacio enblanco en el lenguaje HTML, e indicar que el tamaño

del carácter es cero. Por ejemplo, los mensajes que uti-lizan esta técnica no incluyen directamente la palabra“VIAGRA”. En su lugar aparecerá “V_I_A_G_R_A”,“V.I.A.G.R.A.” o alguna variación similar, de forma queel patrón que intenta localizar el filtro de correo cam-bia, el mensaje llega su destino y el usuario percibe per-fectamente la oferta de este fármaco.

Juego de númerosConsiste en indicar en el cuerpo del mensaje los

caracteres numéricos que identifican a los caracteres, nolos caracteres como tal. Es decir, consiste en escribir elmensaje con los valores numéricos asociados a los carac-teres ASCII correspondientes. Con esta técnica, en lugarde componer el mensaje con la palabra “Viagra”, se intro-duce el código “&#86; &#105; &#97; &#103; &#114; &#97”.Para que un filtro sea eficaz contra esta técnica, debereconocer la presencia de código HTML, decodificar-lo y aplicar el patrón de identificación que corresponda.Para complicar su detección, los mensajes construidoscon esta técnica suelen combinar su construcción con latécnica del agujero negro.

Tinta invisibleEsta técnica manipula fuentes y colores de fondo

para mostrar solo el texto que interesa visualizar al lec-tor. Es decir, el mensaje se compone conteniendo textoanodino que se entremezcla con las palabras que se quie-re mostrar al usuario y que normalmente se asocian amensajes basura. Este texto inocuo impide que los fil-tros anti-spam lo identifiquen como correo basura y elardid se encuentra en que este texto señuelo está for-mateado de manera que al visualizar el mensaje no semuestra en pantalla. Supongamos, por ejemplo, el tex-to “Había una vez un barquito chiquitito INTERESAN-TE OFERTA DE V_I_A_G_R_A!”. El texto “Había una vezun barquito chiquitito” se formatea, mediante códigoHTML, para que sea texto blanco sobre fondo blanco.“¡INTERESANTE OFERTA DE V_I_A_G_R_A!” se formatea

dotN

etM

anía

<<

41

dnm.seguridad<<

Figura 1. Ejemplo de código fuente de mensajecompuesto para descargar contenidos

automáticamente desde un servidor externo

Los spammers deben recurrir a diversas estrategemas para sortear las contramedidas quelimitan sus campañas, lo que se conoce como técnicas de ofuscación de los filtros de spam

dotN

etM

anía

<<

42

dnm.seguridad<<

normalmente. Cuandoel usuario visualiza elmensaje, el texto blan-co sobre fondo blancopasa desapercibido parael lector, mientras queel resto de texto semuestra normalmente.Esta técnica solo esdetectable por filtrosanti-spam sofisticados,capaces de identificarcódigo HTML y veri-ficar la presencia decolores de texto similaral color del fondo. Esta argucia, combinada con otras,como juego de números o agujero negro, hacen muydifícil la detección de estos mensajes spam. Un mensajecompuesto con esta técnica tiene un aspecto parecido alsiguiente.

<Body bgcolor=white>

INTERESANTE OFERTA DE V_I_A_G_R_A!

<font color=white> Habia una vez un barquito

chiquitito</font></body>

Rebanadas y cubitos

Los mensajes construidos con esta técnica crean tablascon letras adyacentes en vertical, de tal forma que la com-binación de las distintas columnas de la tabla provocaque, al visualizarse, en las filas aparezca el texto del men-saje, que lógicamente contiene palabras que son carac-terísticas del correo spam y reconocibles por cualquierfiltro. Los filtros tienen muy complicado detectar losmensajes construidos con esta técnica, ya que los carac-teres incluidos en cada celda no tienen un significadoasociado habitualmente a las palabras típicas de spam.Los filtros que son capaces de detectar estos mensajes sebasan en la reconstrucción de las tablas cuando realizanla inspección del contenido del mensaje para detectar laspalabras patrón, o más sencillamente, intentan detectarla presencia de las etiquetas <TD> </TD> muchas veces ola existencia de tablas complejas. Un ejemplo de estaconstrucción se muestra a continuación, en donde cadacolumna es una tabla independiente.

El código HTML para construir este tipo de men-saje sería similar a:

<table border=0 cellpadding=0 cellspacing=0>

<tr valing=top>

<td><font face=Verdana>V<br>G<br></font></td>

<td><font face=Verdana>I<br>R<br></font></td>

<td><font face=Verdana>A<br>A<br></font></td>

<td><font face=Verdana>G<br>T<br></font></td>

<td><font face=Verdana>R<br>I<br></font></td>

<td><font face=Verdana>A<br>S<br></font></td>

<td><font face=Verdana>&nsbp;<br>s</font></td>

</tr>

</table>

Descarga automática de contenidos

Esta técnica trata de confundir a los filtros anti-spam incluyendo en los mensajes únicamente enla-ces a sitios Web en donde se muestra el contenidoque se quiere dar al lector del mensaje. Es decir, elmensaje solo contiene alguna frase inocua y un vín-culo a sitio o página Web, que es donde realmentese muestra el texto del mensaje. El vínculo puededispararse por la intervención del usuario, que deforma voluntaria siga el vínculo incrustado, pero lohabitual es que se haga automáticamente, inclu-yendo una secuencia de comandos, de tal forma queal abrir el mensaje para lectura o en pre-visualiza-ción directamente se enlace con el servidor y semuestre el contenido del mensaje. Esta técnica seutiliza con profusión por la dificultad que tienenlos filtros para detectarla; reduce considerablementela complejidad de los mensajes construidos con otrastécnicas de ofuscación, permite incluir contenidosmás elaborados y espectaculares y da la posibilidadde enredar al usuario para que acceda a diferentessitios. Es una técnica similar a la utilizada para mos-trar publicidad y banners cuando se visitan sitiosWeb. Para combatir esta técnica suele recurrirse aprogramas ajenos a los filtros anti-spam, instaladosen el ordenador de usuario, que bloquean la des-carga automática de contenidos sin la intervencióndel usuario.

V I A G R A

G R A T I S

La mayoría de las técnicas de ofuscación de spam se aprovechan de la gran difusión actual de los mensajes cuyo contenido tiene formato HTML y de la potencia que este lenguaje tiene

Adjuntos

En esta artimaña, los spammers escon-den el contenido en un archivo gráficoque anexan al mensaje. El texto que seincluye en el cuerpo del mensaje no reve-la ninguna característica del correo spamy es al visualizar el anexo cuando se mues-tra al lector el verdadero contenido de esecorreo. Suelen utilizarse formatos gráfi-cos comúnmente utilizados, tipo GIF oBMP, para evitar la capacidad de los fil-tros de inspeccionar archivos anexos ycomprimidos. También es frecuente uti-lizar esta técnica disfrazando los mensa-jes como informes de fallo en la entrega,NDR. La defensa contra este tipo de men-sajes escapa a la capacidad de los progra-mas de filtrado y la única manera eficazde evitarlos es recomendar al usuario queelimine los mensajes con anexos gráficosde remitentes que desconozca.

Hay que destacar que el empleo deestas técnicas por parte de los spammersno es malo porque burlen los filtros anti-spam y consigan su objetivo. Estas técni-cas llevan implícito un riesgo manifiestoañadido de sobrecarga de los servidoresde correo que los reciben. Si estos men-sajes fueran escritos de manera conven-cional, su tamaño no sobrepasaría unospocos bytes. Al ser compuestos con estastécnicas, su tamaño se puede incremen-tar hasta en un 2200%. Este aumento des-mesurado del tamaño de los mensajes inci-de directamente en los tiempos emplea-dos por los usuarios para descargarlos delos servidores y en el tiempo que los ser-vidores de intercambio de correo tardanen realizar su transmisión.

Las técnicas de ofuscación comenta-das son ampliamente conocidas desdehace tiempo y los filtros anti-spam moder-nos son capaces de detectarlas y marcarconvenientemente los mensajes que lasutilizan para su composición. Sin embar-go, las distintas variaciones y conjuga-ción de ellas dificultan la detección que

realizan estos programasde contramedida y provo-ca que no sean capaces deconseguir un 100% de efi-cacia. Estas circunstanciasconducen a que algunosresponsables de correopoco avezados o poco con-cienciados del problema ysu solución instalen losprogramas anti-spam máspor obligación que porconvicción y que los resul-tados obtenidos dejen unposo de frustración ante la

imposibilidad de erradicar el spam a pesarde los recursos dedicados. Este es un sen-timiento habitual cuando las medidasanti-spam solo contemplan la instalacióny configuración del programa. La reduc-ción del nivel de spam es compleja y soloes posible entendiendo este objetivocomo una estrategia global que abarcadistintas herramientas y procedimientos,en donde la instalación de programas defiltrado y la definición de reglas de recha-zo es solo una parte de la solución.

ConclusiónEn resumidas cuentas, el spam

resulta hoy por hoy una amenaza deprimera magnitud que no puede des-cuidarse. Conocer las distintas técni-cas que los spammers pueden utilizarayuda a comprender el problema yhacer que los filtros anti-spam resul-ten más eficaces.

dotN

etM

anía

<<

43

dnm.seguridad<<

Figura 2. Ejemplo real de ofuscación de palabras típicasde spam y verificación de la dirección de correo.

Según los análisis y estudios de SSppaammhhaauuss, organización internacio-nal dedicada a combatir el correo basura, el 64% del correo electróni-co que llega a los usuarios es spam. Lo curioso de estos análisis es queel 80% de los 55.000 millones de estos mensajes que circulan por lared los originan tan solo 10 personas. Este lamentable ranking lo enca-beza un ucraniano, seguido de un ruso, para encontrar en tercera posi-ción a un estadounidense de origen ruso. El cuadro de honor lo com-pletan otros ciudadanos rusos, un israelí, un canadiense, un norteame-ricano y un hongkonés.

En Estados Unidos y la Unión Europea esta práctica está prohibida,lo que no ocurre en otros países. Estos piratas se aprovechan de la deja-dez de las autoridades y la debilidad de las leyes de Rusia, China y losparaísos fiscales para cambiar con mucha frecuencia de red y seguir man-teniendo un negocio que a toda luces tiene que ser rentable, habida cuen-ta de los inconvenientes de todo tipo que conlleva esta actividad. Decada millón de correos, solo reciben 15 respuestas y los piratas obtienenun porcentaje variable de cada venta o suscripción que se consigue poreste vía. La principal temática de estos mensajes es la venta de fármacos,seguida de productos financieros y pornografía.

Una rentabilidad que se diversifica. La última variante del spam sedenomina sspplloogg. Una modalidad de los populares blogs personales. Estossitios contienen texto falso, diseñados expresamente para contener publi-cidad y promoción de otros sitios Web. La finalidad de esta práctica esconseguir ganar posiciones en los buscadores.

Lejos queda ya el primer mensaje de spam enviado en 1978, comoalgo inocente y anecdótico.

El conceptoLa sobrecarga de operadores es la asignación

de más de una función a un operador particular,con la implicación de la que la operación llevadaa cabo puede variar dependiendo de los tipos dedatos (operandos) involucrados. No la podemosconsiderar un paradigma de programación, aun-que sí una herramienta a la hora de crear códigode fácil lectura. Mediante la sobrecarga de opera-dores le indicamos al compilador qué conductadebe emplear un operador ante la presencia deuna expresión en la que interactúen nuestros tiposy dicho operador. Esto es debido a que para elcompilador una sobrecarga de operador no es másque una función que debe cumplir varias reglaspara ser considerada como tal, las cuales veremosmás adelante. Esencialmente, la sobrecarga deoperadores nos permitirá implementar clases yestructuras a la altura de los tipos intrínsecos dela plataforma .NET.

La necesidadCon la llegada de .NET y Visual Basic .NET se

sucedieron muchos cambios para bien. A la hora deprogramar, se introdujo en este lenguaje la progra-mación orientada a objetos, pero aún hubo cosas quese quedaron en el teclado del equipo de desarrollopor cuestiones de tiempo, por lo que era necesariohacer uso de métodos “alternativos”, y aún así había

sus inconvenientes, como en el caso de SqlString.Pero eso es cosa del pasado; con la llegada de VisualBasic 2005, Microsoft ha preparado un paquete paratodos los gustos.

Comenzando…Una vez tenido claro el concepto de sobrecarga

de operadores, veamos cómo implementar esta carac-terística en Visual Basic 2005. La declaración de unoperador es muy similar a la de un procedimiento(Sub) o función (Function), salvo por la utilización denuevas palabras reservadas. La sintaxis es la siguien-te (el código en cursiva es opcional):

Public Overloads Shared Shadows Widening | _

Narrowing Operator SimboloDeOperador _

(ByVal operando1 As Type, _

ByVal operando2 As Type) As Type

Return resultado

End Operator

De un vistazo podemos ver tres nuevas palabrasreservadas: Widening, Narrowing y Operator. Las dosprimeras las veremos más adelante, en la definiciónde operadores de conversión. La palabra Operatorobviamente está en el sitio que le correspondería aSub o a Function, ya que esta palabra reservada cali-fica al método como un procedimiento de operador(operator procedure).

Visual Basic 2005 Sobrecarga de operadores

fundamentos

HHoorraacciioo NNuuññeezzHHeerrnnáánnddeezz

tiene una experienciade 2 años trabajando

en la plataforma .NET,ha obtenido la prime-ra estrella del progra-ma desarrollador cin-

co estrellas 2005 ypublicado varios artí-culos en el sitio de ElGuille. Puede ver su

blog en hhttttpp::////eellbbllooggddee--hhoorraacciioo..bbllooggssppoott..ccoomm

En el número 9 de esta revista se incluyó un artículo acerca de cómo llevar acabo la sobrecarga de operadores en C#. Por aquellos tiempos, la sobrecargade operadores estaba vetada para los programadores de Visual Basic .NET,debido a que el equipo de desarrollo del lenguaje no pudo incluirla por razonesde tiempo.Afortunadamente, con la llegada de Visual Studio 2005 ya podemoscontar con esta funcionalidad.

Horacio Nuñez Hernández

El símbolo de operador no es más que eso: un sím-bolo, que puede ser uno de los siguientes:

• Unarios:+, -, Not, IsTrue, IsFalse, CType

• Binarios:+, -, *, /, \, &, Like, Mod, And, Or, Xor, ^

, <<, >>, =, <>, >, <, >=, <=

La lista anterior está dividida en dos grupos. Elprimero reúne a los operadores unarios, que son losoperadores que reciben un solo parámetro (de ahí queel segundo parámetro esté en cursiva); la segunda lis-ta contempla los operadores binarios, los cuales lógi-camente trabajan con dos parámetros.

En los procedimientos de operador no está per-mitido utilizar Exit, por lo que usaremos Returnpara salir del procedimiento y devolver un valor.El tipo de retorno puede ser cualquiera, aunque sitenemos Option Strict en Off y no especificamosnada, el valor de retorno será asumido como Object,con las consecuencias que esto acarrea. El tipo delos operandos es muy importante; al menos uno delos operandos debe ser del tipo para el que imple-mentamos el operador, y lógicamente en los casosde operadores unarios el único operador debe serdel tipo en cuestión. La forma en que pasemos losoperandos debe de ser por valor (ByVal), ya que porreferencia (ByRef) no está permitido; como tampo-co Optional o ParamArray. El efecto de Overloads yShadows es el de toda la vida.

Supongamos que estamos diseñando una libreríacon propósitos matemáticos, y queremos implemen-tar una clase para representar fracciones no demasia-do avanzada. Pasados unos minutos, la implementa-ción quedaría tal como se muestra en el fuente 1.

Lo único que echamos en falta es algo que nospermita utilizar la clase como si se tratara de un Inte-ger, así que implementaremos un operador para lamultiplicación (fuente 2).

Utilizamos Overloads para enfatizar que hemossobrecargado el mismo procedimiento de operadormás de una vez. La primera sobrecarga recibe dosoperandos del tipo en cuestión; en cambio, las sobre-cargas restantes reciben un Integer y un tipo Fraccion,alternando el orden de los parámetros en la declara-ción, ya que si suprimiéramos la última sobrecarga eintentáramos algo como:

Class Consumidor

Shared Sub Main()

Dim fraccion1 As New Fraccion(4, 2)

Console.WriteLine(6 * fraccion1)

End Sub

End Class

Recibiríamos un error por parte del compilador(Overload resolution failed because no accessible ‘*’can be called…), debido a que no se podría encontraruna sobrecarga del operador con esa firma, ni siquierahaciendo una conversión implícita. Por esta razón, casisiempre que definamos un procedimiento de operador

dotN

etM

anía

<<

45

dnm.inicio.fundamentos<<

Class FraccionPrivate inumerador As Integer = 1Private idenominador As Integer = 1Public Property Numerador() As IntegerGetReturn Me.inumerador

End GetSet(ByVal value As Integer)Me.inumerador = value

End SetEnd PropertyPublic Property Denominador() As IntegerGetReturn Me.idenominador

End GetSet(ByVal value As Integer)If value = 0 ThenThrow New Exception(_“El denominador no puede ser cero”)

ElseMe.idenominador = value

End IfEnd Set

End PropertySub New(ByVal numerador As Integer, _

ByVal denominador As Integer)Me.Numerador = numeradorMe.Denominador = denominador

End SubPublic Overrides Function ToString() As StringReturn String.Format(“{0}/{1}”, Me.Numerador, _

Me.Denominador)End Function

End Class

Fuente 1

Public Overloads Shared Operator *(_ByVal operando1 As Fraccion, _ByVal operando2 As Fraccion) As Fraccion

Return New Fraccion(operando1.Numerador * _operando2.Numerador, _operando1.Denominador * operando2.Denominador)

End Operator

Public Overloads Shared Operator *(_ByVal operando1 As Fraccion, _ByVal operando2 As Integer) As Fraccion

Return New Fraccion(operando1.Numerador * _operando2,operando1.Denominador)

End Operator

Public Overloads Shared Operator *(_ByVal operando1 As Integer, _ByVal operando2 As Fraccion) As Fraccion

Return New Fraccion(operando1 * operando2.Numerador,_operando2.Denominador)

End Operator

Fuente 2

dotN

etM

anía

<<

46

dnm.inicio.fundamentos<<

que interactúe con algún otro tipo de datosdeberemos definir dos sobrecargas, inter-cambiando la posición de los argumentos.

Afortunadamente, el compiladorrealiza muchas cosas por nosotros. Esposible que el lector piense que habráque definir una sobrecarga para cadatipo de datos; por suerte, esto no esasí. El compilador siempre intentará,o mejor dicho verificará, si es posibleefectuar una conversión implícita. Enel mensaje que acompaña al errorantes mencionado podremos ver unalista de intentos de conversión falli-dos, lo que nos permite agilizar eltiempo de implementación, ya que notendremos que implementar unasobrecarga que habilite la suma conun tipo Short o Byte, como en el códi-go siguiente:

Class Consumidor

Shared Sub Main()

Dim tbyte as Byte = 255

Dim fraccion1 As New Fraccion(4, 2)

Console.WriteLine(tbyte * fraccion1)

End Sub

End Class

Si ya tenemos implementada unasobrecarga del operador *, indirecta-mente también habremos implementa-do el operador *=, ya que internamen-te será el procedimiento que hemossobrecargado el que usará el compila-dor. La tabla 1 muestra una lista de lassobrecargas indirectas.

Después de estas explicaciones, ellector ya deberá estár listo para definirpor sí solo los operadores +, - y / parael tipo Fraccion.

Pasamos ahora a los operadores queutilizamos en las intrucciones condi-cionales, los llamados operadores lógi-cos y relacionales. Como es lógico (val-ga la redundancia), vamos a extender lausabilidad del tipo Fraccion para quepodamos comparar instancias de esasclases y demás, por lo que codificare-mos los métodos que se presentan en elfuente 3.

Por si no lo he mencionado, algu-nos operadores deben ser implementa-dos en parejas, siendo necesario imple-mentar el operador > si hemos imple-mentado < y viceversa, de lo contrarioel compilador emitiría un error:

• = y <>• > y <• >= y <=• IsTrue e IsFalse

Esto tiene muchas ventajas, al esti-lo de las conversiones implícitas lle-vadas a cabo por el compilador, ya quesolo tendremos que codificar un ope-rador y devolver el resultado contra-rio en la sobrecarga del operador conel que forme pareja. Un ejemplo deesto se muestra en el fuente 3. Solohemos escrito la lógica de > y =, mien-tras que <> y < niegan el resultado de

la expresión inversa. Esto tiene su“pero”: es necesario que los procedi-mientos devuelvan un valor booleanopara poder negarlos, y los operadoresrelacionales pueden devolver cual-quier valor, si bien es cierto que suuso más común es en instruccionescondicionales.

IsTrue, IsFalseLos operadores IsTrue e IsFalse

no pueden ser llamados explícitamen-te desde nuestro código; son utiliza-dos implícitamente por el compilador.Su función es definir cuándo unaexpresión es verdadera o es falsa, sitenemos pensado utilizar nuestra cla-se o estructura en instrucciones For,If, Else If y While, o en una cláusulaWhen. Es necesario definir un opera-dor que convierta nuestro tipo en Boo-lean, y una de las maneras de hacerloes mediante la sobrecarga del opera-dor IsTrue. Las otras dos vías alterna-tivas son mediante operadores de con-versión. El código del fuente 4 ilustrala función de IsTrue e IsFalse en ins-trucciones donde se espera un valorbooleano.

En el código del fuente 4 hemosdefinido tres sobrecargas: IsTrue,IsFalse y Not. En la primera verifica-mos antes que nada si el operandohace referencia a un objeto; en caso

Operador(es)sobrecargado(s)

directamente

Operador sobrecargado

indirectamente

^ ^=

* *=

/ /=

\ \=

+ +=

- -=

<< <<=

>> >>=

& &=

And e IsFalse AndAlso

Or e IsTrue OrElse

Mod No existe aún en VB ☺

Public Shared Operator >(ByVal operando1 As Fraccion, _ByVal operando2 As Fraccion) As Boolean

Return operando1.Numerador \ operando1.Denominador > _operando2.Numerador \ operando2.Denominador

End Operator

Public Shared Operator <(ByVal operando1 As Fraccion, _ByVal operando2 As Fraccion) As Boolean

Return Not operando1 > operando2End Operator

Public Shared Operator =(ByVal operando1 As Fraccion, _ByVal operando2 As Fraccion) As Boolean

Return operando1.Numerador \ operando1.Denominador = _operando2.Numerador \ operando2.Denominador

End Operator

Public Shared Operator <>(ByVal operando1 As Fraccion, _ByVal operando2 As Fraccion) As Boolean

Return Not operando1 = operando2End Operator

Fuente 3

Tabla 1. Lista de sobrecargas indirectas

dotN

etM

anía

<<

47

dnm.inicio.fundamentos<<

de no ser así devolvemos False. En caso de hacerreferencia a un objeto, el valor a devolver dependedel valor de la variable Activado. IsFalse, como eslógico, devuelve lo contrario de IsTrue, por lo quepodemos aprovecharnos de esto para escribir uncódigo más fácil de leer, recurriendo a Not. Perosucede que Not tiene que ser sobrecargado paranuestro tipo de datos. Nada más fácil de hacer: sim-plemente devolvemos lo contrario a IsTrue, que afin de cuentas es lo mismo que debe hacer IsFalse,pero ya son tres operadores que podemos usar ennuestro código. La definición de IsTrue e IsFalseserá requerida si necesitamos emplear los operado-res AndAlso y OrElse, siendo necesario definir IsTruey Or para sobrecargar indirectamente OrElse, eIsFalse y And en el caso de AndAlso. El único tipode datos intrínseco de .NET que soporta OrElse yAndAlso es el tipo Boolean.

CType,el operador de conversión

Ha llegado la hora de hablar del operador de con-versión CType, mediante el que podemos establecer laconversión de nuestra clase o estructura a cualquier otrotipo de datos. Existen dos modos de hacer una conver-sión: implícita y explícita. La primera es una conversióndonde el tipo de datos destino puede manejar sin pro-blemas el tipo de datos origen; la segunda es todo lo con-trario, ya que es posible que se produzca una excepcióny no se lleve a cabo la operación. Un ejemplo sencillo deconversión implícita sería convertir un tipo Integer a untipo Long; ello siempre es completamente posible, ya queel rango de un Integer está contenido dentro del rangode un Long. Ahora bien, si intentáramos lo contrario esposible que la conversión no se llevase a cabo, ya que elentero largo podría no encontrarse en el rango soporta-do por Integer. A la hora de codificar los operadores de

Class CronometroPrivate Activado As Boolean

Public Shared Operator IsTrue(ByVal operando1 As Cronometro) As BooleanIf operando1 Is Nothing Then

Return FalseElse

Return operando1.ActivadoEnd If

End Operator

Public Shared Operator IsFalse(ByVal operando1 As Cronometro) As BooleanReturn Not operando1

End Operator

Public Shared Operator Not(ByVal operando1 As Cronometro) As BooleanIf operando1 Then Return False Else Return True

End OperatorEnd Class

Fuente 4

Class MP3Private mpath As System.IO.FileStream

Sub New(ByVal FilePath As System.IO.FileStream)

‘comprobamos si es un fichero mp3 con la estructura correcta‘...Me.mpath = FilePath

End Sub

Public Shared Widening Operator CType(ByVal operando As MP3) As System.IO.FileStreamReturn operando.mpath

End Operator

Public Shared Narrowing Operator CType(ByVal operando As System.IO.FileStream) As MP3Return New MP3(operando)

End OperatorEnd Class

Fuente 5

dotN

etM

anía

<<

48

dnm.inicio.fundamentos<<

conversión, estableceremos una conversión implícita(segura) como Widening y una conversión explícita (inse-gura) como Narrowing. De esto pudiéramos sacar la con-clusión:

1. La relación de Integer a Long es Widening.2. La relación de Long a Integer es Narrowing.

Si la relación de conversión está calificada comoNarrowing y Option Strict es On, debemos hacer unaconversión explícita mediante CType; de lo contrario,recibiríamos un error. Muchas veces en lugar de usarCType utilizamos CStr o CInt; esto también es válido paralos tipos definidos por nosotros, debido a que para elcompilador CStr(variable) es equivalente a CType(varia-

ble, String).A la hora de codificar un operador de conver-

sión hay ciertas cosas que cambian con respecto alos demás operadores. Al principio del artículocomenté que los operadores unarios debían recibirun único parámetro del tipo que estamos definien-do; en el caso del operador de conversión esto setorna más flexible.

En el fuente 5 se muestra una conversión Narrowingdel tipo FileStream hacia el tipo que definimos; la mar-camos como Narrowing ya que se puede producir unaexcepción debido al hecho de que el fichero no tenga elformato válido. Pero lo interesante de esta conversiónes que permite obtener de un tipo de datos (cuya imple-mentación desconocemos) un objeto del tipo de datosque definimos.

Otra función interesante del operador CType guar-da mucha relación con el operador IsTrue. El lectorrecordará que mencionamos que para convertir untipo de datos a Boolean había tres formas: una de ellases IsTrue; las otras dos son mediante CType. El com-pilador busca una manera de representar nuestro tipode forma booleana en el siguiente orden:

1. Una conversión Widening que dé como resultadoBoolean.

2. La presencia del operador IsTrue.3. Una conversión Narrowing que dé como resulta-

do Boolean.

Sobre la herencia

Supongamos que en vez de decla-rar Fraccion como una estructura lahemos definido como una clase, paraposteriormente definir a partir de ellaotra clase que maneje números reales,por ejemplo FraccionEx::

Class FraccionExInherits Fraccion

End Class

Demasiado sencillo para ser cierto; si intentára-mos multiplicar dos objetos FraccionEx para asignarel resultado a un tercero:

Class ConsumidorShared Sub Main()

Dim una As New FraccionExDim dos As New FraccionExDim tres As FraccionEx = una * dosConsole.Read()

End SubEnd Class

Nos encontraríamos con un error. Esto se debe aque el compilador utilizará el operador definido en laclase base y devolverá un objeto del tipo base. No esposible establecer operadores de conversión entrebase-derivada y viceversa, por lo que tendremos quedefinir otra implementación del operador:

Class FraccionExInherits FraccionPublic Shared Operator *(_

ByVal operando1 As FraccionEx, _ByVal operando2 As FraccionEx) As FraccionEx

'...Return New FraccionEx

End OperatorEnd Class

Finalizando...

La sobrecarga de operadores es un recurso lingüís-tico potente, del que es importante hacer un uso ade-cuado. No sería correcto ni recomendable que el ope-rador > devolviera la diferencia entre dos números.Otra recomendación a tener en cuenta es que si el com-portamiento de un operador no guarda ninguna rela-ción con el comportamiento que asume ante los tiposintrínsecos, entonces no merece la pena sobrecargar-lo. Espero que este artículo les haya ayudado a ampliarsus conocimientos sobre la plataforma .NET en gene-ral y Visual Basic 2005 en particular.

La sobrecarga de operadores es un recursolingüístico potente, del que es importante hacer un uso adecuado

❑ Deseo suscribirme a dotNetManía por un año (11 números) por un precio de 65,00€ IVA incluido y recibir gratuitamentepróximo cuaderno técnico que publique Netalia.

❑ 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)

Suscríbase y llévese el próximo Cuaderno

Técnico gratis

Oferta válida para España hasta el 28 de febrero de 2007 o hasta agotar existencias

❑ Nº20 (8,50€) ❑ Nº21 (6,50€) ❑ Nº22 (6,50€) ❑ 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€)

dotN

etM

anía

<<

50

La idea de formar un grupo de usuarios para los pro-gramadores de .NET de Galicia me llevaba un añorondando la cabeza, pero hasta finales del 2006 no seconvirtió en una realidad.

El 9 de octubre acudí como asistente a un TallerMSDN sobre el ciclo de vida de las aplicaciones conTeam System en La Coruña en el que aproveché undescanso para hablar con Unai Zorrilla (ponente deltaller) y Marco Amoedo (que acudía como asistente)sobre la idea de crear un grupo de usuarios; a ambosles pareció bien. Al acabar el evento comentamos laidea a los asistentes y ya apareció algún interesado.

Nada más salir del evento me puse manos a laobra: escribí un correo a la gente que conocía que erade Galicia y a MSDN (en concreto a Alfonso Rodrí-guez y a David Carmona). En apenas una semanaya éramos seis personas interesadas, Unai Zorrilla,Marco Amoedo, Iván González, José ManuelAlarcón, Álvaro Rodríguez y yo, naturalmente.

También me puse en contacto con otros grupos deusuarios de España para saber qué pasos debía seguirpara la formación del grupo. Todos coincidían en trespuntos: contactar con MSDN, tener una Web y unlocal para los eventos. El primero ya lo teníamos, losiguiente fue comprar un dominio y Pablo Peláez nosproporcionó el hosting para la Web. Nos quedaba elúltimo punto y más difícil de conseguir. Para ello nos

pusimos en contacto con Eduardo Quintás que nosconsiguió un aula en la Universidad de La Coruña yposteriormente lo fichamos para el grupo. De nuestrologo se encargó Francisco Javier Carbajosa (de Ono-baNet, el grupo de usuarios de Huelva).

Hemos decidido hacer los eventos los viernes porla tarde, de 17:00 a 20:00, en el Edificio Xoana Cap-deville de la Universidad de La Coruña, aunque nodescartamos hacer alguno en cualquier otra ciudadde Galicia. Nuestra intención era empezar en diciem-bre de 2006, con una charla impartida por BrunoCapuano sobre Microsoft Robotics Studio, pero porproblemas con el local para no pudo celebrarse.

Organizamos nuestro primer evento para el pasa-do 19 de enero. En él tuvimos de invitado a MiguelJiménez (MVP C#), con su espectacular charla “C#3.0” que duró aproximadamente dos horas, en las quenos empapó de las novedades de C# 3.0 y cómo cadauna de ellas son necesarias para la creación de LINQ.Tuvimos una audiencia de 9 personas, que esperamosir incrementando en los próximos eventos.

El siguiente evento confirmado será el próximo2 de marzo, en el cual contaremos con la presenciade Chema Alonso (MVP Windows Security) con sucharla “Algunas técnicas de hacking en aplicacionesWeb” Aquí tenéis la descripción que nos ha propor-cionado Chema:

.NUGG

.Net User Group Galicia

Un user group es una asociación en lacual gente de una misma ciudad oregión se une para compartir cono-cimientos sobre una tecnología, ennuestro caso .NET. Para ello hace-mos reuniones periódicas sobrediferentes temas, en las que todo elmundo está invitado a participar.

comunidad.net

“Durante 2 años he ido realizando conferenciassobre técnicas de hacking para atacar aplicaciones Web.Estas técnicas son las que yo utilizo para realizar lostests de intrusión en las empresas. En esta sesión voya realizar, con alguna pizca de humor, un análisis dealgunas de ellas, viendo algunos aspectos en detallede cómo especializar ataques de SQL Injection, XSS,RFI o WebTrojan. Anímate a venir y sabrás más dela sesión”.

En los próximos días publicaremos los datos deeste evento tanto en nuestra Web como en la deMicrosoft, que nos proporciona apoyo logístico des-de la página de eventos de MSDN.

Desde aquí aprovechamos para invitarte a que, siestás en Galicia, te acerques a alguno de nuestros even-tos, así como a la participación en nuestras iniciati-vas. Además, si quieres dar una charla al grupo o tie-nes alguna iniciativa que quieras llevar adelante, con-tacta con nosotros con nosotros en el siguiente mail:[email protected].

Para estar al tanto de las noticias del grupo regís-trate en nuestra web: www.nugg.es.

Por último, quiero agradecer a todas aquellaspersonas que han participado para que esto hayasido posible. A Alfonso Rodríguez por su apoyo yproporcionarnos la logística para los eventos, aPablo Peláez por el hosting, a Krasis por propor-cionarnos el servidor del correo, a Francisco JavierCarbajosa por diseñarnos el logo, a todos los gru-pos que nos han dados sus consejos, a EduardoQuintás por proporcionarnos el local, a MiguelJiménez por inaugurar el grupo, a Chema Alonsoque será nuestro próximo ponente y en especial aPaco Marín por proporcionarnos este espacio paradarnos a conocer. Gracias a todos.

dotN

etM

anía

<<

51

dnm.comunidad.net<<

..NNUUGGGG• ubicación: Galicia• fecha de fundación: octubre 2006• fundador: Eugenio Estrada• miembros: 20• página web: www.nugg.es• email de contacto: [email protected]

Eugenio EstradaFundador de .Net User Group Galicia

Evento presentación WPF BcnDev

eventos.eventos.eventos

BcnDev ha celebrado el evento de presentación de WPF, presentan-do teórica y prácticamente lo que podemos afirmar es una verdadera evo-lución para las interfaces de usuario, como lo fue la invención del códicepara el rollo de papiro… con WPF e XPS como papiro de nuestra era,solo que ahora éste es digital, vectorial, en 3D y lo podemos manejar conel mando de la Wii ☺.

La presentación fue bastante completa, con una introducción a losconceptos, ventajas y beneficios de WPF. Luego tuvimos una muy inte-resante sesión teórico-práctica en la cual pudimos ver de forma evolutivael desarrollo de aplicaciones basadas en WPF, culminando con el desa-rrollo del “BcnDevMediaCube” el cual, como guinda, manejamos con elmando de la Wii. Una nota de humor la aporta que, en la noche anterior,uno de los ponentes por poco acaba lesionándose por el énfasis en el mane-jo del wiimote. La televisión, se salvó.

El evento ha sido un éxito en asistencia (40 personas) y en el interésdemostrado por esta creciente comunidad, siendo ya 123 desarrolladoresasociados a la misma. Para más información, consultar http://www.bcndev.net.

Han actuado como ponentes José Luis Cubero, Toni Recio y unservidor.

José Luis Latorre

Lo mejor, el público BcnDeveloper y, al fondo, los ponentes

Foto

graf

ía:D

avid

Zar

doya

Mediante esta clase podremos crear un formula-rio de inserción de texto, pudiendo formateardicho texto con diferentes propiedades como lafuente, el tamaño, alineación, color, negrita, etc.Según vayamos escribiendo el texto y aplicando

el formato, la clase de código .NET va creandoel código HTML resultante, que podremos alma-cenar en un campo de una base de datos para pos-teriormente mostrarlo en una Web.

La clase está disponible en código abierto paraVisual Studio .NET 2005. Simplemente con escri-bir las siguientes líneas de código podremos dis-frutar de toda su funcionalidad:

A veces la ejecución de una página se hace muycostosa debido a la lógica que aplica o simplemen-te a que los elementos gráficos que va a mostrar sondemasiado pesados. Los navegadores suelen dejar lapantalla en blanco o mostrar pequeños trozos segúnse va liberando el búfer de la memoria. Esta formade procesar las peticiones al servidor suele dar malaimpresión e incluso llega a desesperar a algunos usua-rios, propiciando que den una y otra vez al botón derefrescar la página. Para minimizar este impactonegativo, este mes le recomendamos para sus desa-rrollos: BusyBoxDotNet.

BusyBoxDotNet es un control Web deASP.NET 2.0 diseñado para dotar a sus páginas deuna precarga que se inicia en el momento que elusuario manda una petición al servidor y finalizacuando la descarga de los datos ha concluido; es decir,desde el evento OnClick de una petición hasta el even-to OnLoad de la página.

A partir de que se incorpore este control a unapágina, el usuario que acceda a ella tendrá un ele-

mento de referencia a la hora de saber que la pági-na sigue su normal funcionamiento. Ya no desespe-rará pensando en si se ha perdido la conexión o lapágina ha fallado.

Este componente es compatible con los princi-pales navegadores: Internet Explorer, Firefox/Mozi-lla, Opera, Netscape Navigator. Su instalación norequiere de mucha implementación. Ofrece multi-tud de propiedades que pueden personalizarse, algu-nas de las cuales son:

• Texto a mostrar.• Tipo de letra.• Color de fondo, bordes.• Grado de opacidad.• Imagen GIF a mostrar.• URL al hacer clic en la precarga.

BusyBoxDotNet

RichText to HTML

Laboratorio.netLorenzo Ponte

LLoorreennzzoo PPoonnttee esredactor de ddoottNNeett--

MMaannííaa. Es arquitecto desistemas y aplicaciones.NET. Experto en datawarehousing y businessintelligence, marketing

intelligence y CRManalítico.Actualmente

es consultor de laempresa MMaattcchhmmiinndd y

webmaster decclliikkeeaarr..ccoomm

• Nombre BusyBoxDotNet

• Autor Mark Wagner

• Web http://busyboxdotnet.qsh.eu

• Categoría Utilidades

• Precio Gratis

• Valoración 2/5

Ficha técnica

• Nombre RichText to HTML

• Fabricante George H. Slaterpryce III

• Web http://www.codeproject.com/vb/net/RTFToHTML.asp

• Categoría Utilidades

• Precio Gratis

• Valoración 2/5

Ficha técnica

Private Sub btnBar_Click(ByVal sender as object, _e as System.EventArgs) Handles btnBar.Click

Dim r2h As New RTFtoHTMLr2h.rtf = rtbFoo.rtfMessageBox.Show(r2h.html)

End Sub

Mucha de la información que se recibe y envíaentre empresas se archiva en documentos PDF, quepresentan algunas dificultades a la hora de ser trata-dos por aplicaciones de documentación. PDFRaste-rizer.NET es un componente pensado para renderi-zar documentos PDF. ¿Qué quiere decir esto? Queeste componente proporciona una serie de utilidadesque nos permitirán manejar un poco mejor la infor-mación almacenada en esos archivos.

A continuación se explican algunas de sus princi-pales utilidades:

Conversión de documentos PDF a archivos en for-mato de imagen,como BMP,GIF,PNG,etc.

El procedimiento para convertir un documentoen una imagen pasa por crear un bitmap asociado aldocumento, aplicarle una escala válida para la reso-lución que vayamos a utilizar, invocar el objeto grá-fico alojado en la página y guardar dicho bitmap usan-do el formato de imagen GDI+.

Mostrar documentos PDF en WinForms

Si lo que queremos es mostrar un documento PDFen una aplicación hecha con Windows Forms, bastarácon aplicar las siguientes líneas de código; deberemosutilizar Control.Paint para mostrar el resultado.

Programar la impresión de documentos PDF

Controlar la forma en la que vamos a imprimir undocumento PDF puede ser una utilidad bastante intere-sante en nuestra aplicación de documentación. PDFRas-terizer.NET nos da la posibilidad de especificar todos losparámetros de impresión posibles. A continuación se mues-tra en unas cuantas líneas de código cómo implementaresta posibilidad. Observe que para lanzar la ejecución seutiliza el evento PrintDocument.PrintPage, y para comen-zar la impresión el evento PrintDocument.Print.

dotN

etM

anía

<<

53

dnm.laboratorio.net<<

PDFRasterizer.NET

• Nombre PDFRasterizer.NET

• Fabricante Tall Components

• Web http://www.tallcomponents.com

• Categoría Utilidades

• Precio desde 746 Euros

• Valoración 4/5

Ficha técnica

using ( FileStream file = new FileStream( "test.pdf", FileMode.Open, FileAccess.Read ) )

{// abrir un documento pdfDocument document=new Document(new BinaryReader(file));

// obtener la primera páginaPage page = document.Pages[0];

// calcular la escala a mostrarfloat dpi = 300;float scale = dpi / 72f;

using ( Bitmap bitmap = new Bitmap( (int) ( scale * page.Width ), (int) ( scale * page.Height)))

{// convertir a gráficoGraphics graphics = Graphics.FromImage( bitmap );

// aplicar la escalagraphics.ScaleTransform( scale, scale );

// renderizar el gráficopage.Draw( graphics );

// guardar el gráfico en formato BMPbitmap.Save( "test.bmp", ImageFormat.Bmp );

}}

private void viewerPanel_Paint( object sender, System.Windows.Forms.PaintEventArgs e)

{e.Graphics.Clear( Color.White );if ( null != page ){

page.Draw( e.Graphics );e.Graphics.DrawRectangle( new Pen(Color.Gray),0, 0, (float) page.Width,

(float) page.Height );}

}

// Este método es un miembro que deriva de System.Windows.Forms.Formvoid Print(){if ( null == document ) return;// Obtener las páginas seleccionadasselectedPages = pagesList.SelectedIndices.GetEnumerator();selectedPages.Reset();

// Movernos hasta la primera de las páginas seleccionadasif ( selectedPages.MoveNext() ){// Crear documento de impresión con el mismo nombre que el documento PDFPrintDocument printDocument = new PrintDocument();printDocument.DocumentName = document.Title;// Permitir especificar los parámetros a través del cuadro de diálogoPageSetupDialog setupDialog = new PageSetupDialog();setupDialog.Document = printDocument;if ( DialogResult.OK == setupDialog.ShowDialog() ){

printDocument.DefaultPageSettings = setupDialog.PageSettings;printDocument.PrinterSettings = setupDialog.PrinterSettings;

// Imprimir el documentoprintDocument.PrintPage += new PrintPageEventHandler( printPage );printDocument.Print();}

}}

El remitente de este mensaje incluyó también unaserie de consideraciones para animar aún más eldebate. Muchas de ellas están obsoletas, debido ala rápida evolución de la tecnología AJAX. Hoypor hoy, a punto de ver la luz la versión 1.0 deASP.NET AJAX Extensions, no existen demasia-das diferencias entre métodos de páginas y servi-cios Web.

Los métodos de páginas (en code behind) ya nose ejecutan en el ciclo vital de la página, no exis-te un viewstate que se envíe (y se devuelva), y nopuede accederse a controles de servidor. Simple-mente, la página actúa como un envoltorio (vir-tual) para el código del servicio Web.

Así que, ¿deberíamos optar por métodos depágina o por servicios Web?

En términos de rendimiento es prácticamentelo mismo. La implementación interna es tambiénsimilar y en algunos puntos coinciden plenamen-te. Pero, veamos algunas ligeras diferencias.

En primer lugar, un método de página esaccedido a través de la URL de página, mien-tras que el servicio Web es accedido mediantesu URL pública. Esto significa que puedes reu-tilizar más fácilmente la misma lógica en múl-

tiples páginas. Si necesitas llamar al mismométodo desde distintas páginas se necesita esemétodo en todas y cada una de ellas. Si optaspor el servicio Web, todo lo que tienes que haceres usar el Javascript adecuado para llamar a laURL del servicio Web.

Sin embargo, desde una perspectiva de apli-caciones reales, esto puede ser un falso problema.No se recomienda que pongas el código real a eje-cutar en la clase code behind. En su lugar, almace-nas ese código dentro de la lógica de unas libreríasy llamas a esas clases desde dentro de la página.En este caso, el método de la página es simple-mente una fachada, justo como el envoltorioASMX.

¿Qué hacer entonces? Mi conclusión es que,con la última implementación, los métodos depágina y los servicios Web son prácticamente lomismo, desde el punto de vista del comporta-miento y el rendimiento. Dicho esto, me gustaríallamar la atención en un aspecto de los serviciosWeb utilizados en el contexto de las aplicacionesAJAX.

Un servicio Web es una pieza de código aso-ciada a una URL pública. Cualquiera puede cono-

Asíncrono es la clave

Dino Esposito

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)

Problema: estamos migrando una aplicación muy grande desde COM+ a las nuevas tecnologíasASP.NET 2.0,AJAX y SQL Server 2005. Estamos debatiendo sobre si utilizar [WebMethod] en elcódigo de soporte, o utilizarlo en servicios Web (ficheros *.asmx). ¿Podría mostrarnos cuál es lamejor aproximación y por qué? ¿Y qué hay del rendimiento y del ciclo de vida en ejecución? ¿Exis-ten otras alternativas o posibilidades?

todonet@qa

Las operaciones asíncronas suministran un mejor uso de los recursos del sistema y de los sub-procesos en particular. En algunos casos, cuando están implicadas operaciones remotas, puedeincluso convertirse en un paralelismo auténtico, con una máquina (servidor) procesando y otra(cliente) esperando o realizando otras tareas. En esta sección vamos a abordar la programaciónasíncrona desde tres perspectivas:ASP.NET AJAX,ADO.NET y código genérico administrado.

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

cer la URL y utilizarla. Normalmente, un servicioWeb coloca un fichero WSDL en alguna parte porrazones de interoperabilidad. Este fichero no es estric-tamente requerido para un servicio que vaya a ser uti-lizado solo desde código AJAX. Así, el formato de lasolicitud usada para la llamada a esos servicios puedeser fácilmente deducido. ¿Cómo evitar usos no auto-rizados? Simplemente, no puedes.

Si optas por los servicios Web, cualquiera desdeel exterior puede llamar y ejecutar tu código, te gus-te o no. No hay una capa de seguridad preventiva, conautenticación y autorización. No puedes poner tucódigo más crítico en un servicio Web, porque seríacomo ponerlo a merced de cualquiera. Deberías limi-tarte a exponer cierto conjunto funcional de interfazde usuario, por ejemplo, métodos de consulta sim-ples, o que no devuelvan información crítica.

¿Son más seguros los métodos de página? Es lomismo. Llegados a este punto, la elección de un méto-do u otro es una cuestión de preferencias. El quid dela cuestión, sin embargo, es muy distinto: ¿dóndedeberías ubicar tu código crítico que va a ser llama-do desde el cliente vía Javascript?

En general, creo que UpdatePanel es la mejoropción de todas. Usar este control es como hacer

un postback normal, con el viewstate para protegerparcialmente contra ataques un solo clic. El uso deUpdatePanel plantea los mismos riesgos de seguri-dad a que nos enfrentamos en aplicaciones clásicasASP.NET. Si se requiere autenticación y autoriza-ción, éstas deben suministrarse. Desde luego queutilizar UpdatePanel resulta más costoso que la sim-ple llamada a un método de un servicio Web, ométodo de página. Por ejemplo, el objeto ViewSta-te es enviado al servidor en su totalidad, para quesea procesado y devuelto al cliente listo para pro-cesar nuevas peticiones. La cantidad de informa-ción que viaja es significativamente menor que enlas aplicaciones ASP.NET normales, pero –aún así–también es mayor que con un servicio Web o méto-do de página.

¿Quieres utilizar servicios Web, pero trabajar dela forma más segura posible? En esa situación, debesimplementar cierta seguridad en el código de cadamétodo accesible. El tipo depende de ti principal-mente, pero algunos ejemplos podrían ser la com-probación de alguna cookie de autenticación con sutiempo de expiración establecido, o quizás la com-probación de las direcciones IP para filtrar usuariosdesconocidos.

dotN

etM

anía

<<

55

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

dnm.todonet@qa<<

Me gustaría llamar a parte de mi código de forma asíncrona. Pero todos los ejemplos que veo mues-tran la llamada a métodos de objetos que aparentemente soportan el patrón asíncrono de forma nati-va. Por ejemplo, sabría cómo hacer una petición Web asíncrona o ejecutar un comando ADO.NET dela misma forma, pero ¿qué pasa si quiero llamar a mi propio código de forma asíncrona?

.NET Framework incluye todo tipo de herra-mientas que puedas necesitar para llamar a tu códi-go de forma asíncrona. Además, algunas clasesincluyen de forma nativa métodos que implemen-tan el patrón asíncrono en el contexto operativodel objeto. Por ejemplo, la clase WebRequest. Estaclase suministra un par de métodos para conec-tarse a una URL remota a obtener una respuesta.Estos métodos son BeginGetResponse y EndGetRes-ponse. Primero se llama al método BeginXXX paracomenzar la operación. Lo que hagas a continua-ción es función del tipo particular de patrón asín-crono en el que estés interesado. Puedes esperar aque el estado del objeto sea apto para recuperarun resultado, o puedes interrumpir el procesomediante un objeto de sincronización para que elflujo de ejecución detenga su espera de resultados.Finalmente, puedes registrar una función que serállamada automáticamente cuando los resultadosestén disponibles.

En cualquier caso, para recuperar el valor de retor-no de la operación asíncrona tienes que llamar al méto-do EndXXX. Cuando llamas a éste método EndXXX, lepasas el ticket que obtuviste como valor de retornodel método Begin. En .NET, ese ticket toma la formade un objeto que implementa la interfaz IAsyncResult.Vea un ejemplo en el fuente 1.

Hacer una llamada a una URL remota es algo paralo que .NET suministra soporte nativo. ¿Y si, en lugarde eso, tenemos nuestra propia lógica de negocio yqueremos llamar a sus métodos de forma asíncrona?¿Se puede? Por supuesto. Veamos un ejemplo.

El truco está en utilizar un par de ejecutores gené-ricos de código, tales como BeginInvoke y EndInvoke.Ambos están definidos en el objeto delegate. Así queel primer paso es crear un delegado (especie de pun-tero a función orientado a objetos), cuya firma coin-cida con la del método a invocar de forma asíncrona.Supongamos que el método es similar al del fuente 2.El delegado toma la forma del fuente 3.

dotN

etM

anía

<<

56

dnm.todonet@qa<<T

odot

Net.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

En mi capa de acceso a datos .NET pienso utilizar comandos ADO.NET asíncronos. Pero mepregunto qué podría suceder si se lanza una excepción durante la ejecución del comando. ¿Serécapaz de capturar la excepción, y cuándo/dónde?

Ejecutar un comando ADO.NET de forma asíncro-na significa que el código no tiene que bloquearsehasta que los resultados del comando estén listos ydescargados en el cliente. Con comandos asíncronospuedes comenzar la transacción con la base de datosy proceder con el siguiente paso. Cuando los resul-tados están disponibles –y probablemente de formaparalela– sincronizas, actualizas la interfaz de usua-rio y listo.

Para configurar ADO.NET de forma asíncrona, hayque añadir la asignación async=true en la cadena de cone-xión y utilizar pares de métodos Begin/End para ejecu-tar las sentencias. Por ejemplo, se puede utilizar Begi-nExecuteReader/EndExecuteReader para obtener un obje-to reader de forma asíncrona. ¿Qué pasa si ocurre unerror durante la operación? Date cuenta de que los erro-res pueden suceder en cualquier punto durante la eje-cución de un comando. Por lo tanto, las excepcionespueden lanzarse en cualquier punto. Por ejemplo, si

ADO.NET detecta un error antes de abrir la conexión,entonces lanzará la excepción apropiada desde el méto-do Begin. Esto incluye situaciones en las que se obtie-nen parámetros inválidos, falta información necesaria(como no haber establecido la conexión activa para elcomando), o hay problemas de conectividad, tales comouna caída del servidor.

Si todo es correcto, cuando comienza el comando,la siguiente parada donde puede detectarse y notifi-carse el error es en el método End. Por supuesto,ADO.NET detecta el error en el momento exacto enque sucede, pero en medio de una operación asíncro-na no tiene forma de comunicar este hecho al usuario.Por tanto, una excepción originada en el lado del ser-vidor es almacenada por ADO.NET y notificada a losusuarios en el método End. En resumen, tu capa deacceso a datos debería manejar posibles excepcionesen ambos métodos (Begin y End), y resolver la excep-ción adecuadamente en cada caso.

El código que actúa como un disparador de la ope-ración asíncrona puede ser similar al del fuente 4.

BeginInvoke y EndInvoke juegan exactamente el mis-mo papel que las parejas de métodos Begin/End en otrosescenarios. Pueden utilizarse tanto en aplicaciones Webcomo Windows.

public void DoTheAsyncTask(){

// Hacer algo aquíThread.Sleep(5000);...

}

protected delegate void AsyncTaskDelegate();

AsyncTaskDelegate dlgt;dlgt = new AsyncTaskDelegate(DoTheAsyncTask);IAsyncResult result = dlgt.BeginInvoke(callback, state);

...

dlgt.EndInvoke(ar);

req = WebRequest.Create(url);IAsyncResult ticket =

BeginGetResponse( callback, state);

...

string text;using (WebResponse response = req.EndGetResponse(ar)){

StreamReader reader;using (reader = new

StreamReader(response.GetResponseStream())) {

text = reader.ReadToEnd();}

// Procesar datos...

}

Fuente 1

Fuente 2

Fuente 3

Fuente 4

Traducido al castellano por Marino Posadas

Inside Microsoft SQL Server 2005:T-SQL Querying Itzik Ben-Gan, Lubor Kollar,Dejan Sarka (Solid Quality Learning)

Editorial: Microsoft PressPáginas: 632Publicado: abril, 2006ISBN: 0735623139Idioma: inglés

Continuando con nuestra intención de aconsejar sobre libros que cubran cualquier aspec-to del ciclo de desarrollo, comenzamos hoy por esta obra de 3 miembros destacados deSolid Quality Learning: Itzik Ben-Gan, Lubor Kollar y Dejan Sarka. El primero yahabía tenido una presencia editorial importante, pero esta obra es de esas “rara avis” enlas que todos los lectores se ponen de acuerdo: 5 estrellas de media (máxima puntuación)en las valoraciones de sus compradores en Amazon.

Y es que no solo se aprende SQL a raudales, sino que se ilustran cosas que uno no sos-pechaba siquiera que se pudiesen hacer con el lenguaje SQL. Se trata de una referenciapráctica, tanto para desarrolladores como para administradores, que ofrece un nivel muyavanzado de técnicas de consulta, adornado con muchísimos ejemplos para cada técnicaexplicada y bases de datos de ejemplo.

Programming .NET Components Juval Lowy

Editorial: O’ReillyPáginas: 624Publicado: 2007ISBN: 0596102070Idioma: inglés

Y cerramos esta revisión con otra obra de cinco estrellas, al menos en su acogida popular, yde recentísima aparición. Juval Lowy, MVP de C# y conocido ponente de los principaleseventos de Microsoft, comienza el año con la publicación de esta pequeña maravilla, que nose conforma con la mera descripción de lo prometido en su título: resulta de incalculable valorpara comprender el auténtico sentido de muchos aspectos críticos en la creación de .NET.

Utilizando el lenguaje C#, Lowy lleva .NET Framework 2.0 a otra dimensión. No solo expli-ca la arquitectura y plantea y resuelve los problemas, sino que se anticipa a las dificultades decada escenario, evitando al usuario las penurias del descubrimiento de muchos errores que seproducen en la programación avanzada, en parte, gracias al acceso directo y comunicaciónpermanente que mantiene con los equipos de desarrollo en Redmond.

biblioteca.net

nove

dad

es •Visual Studio 2005 Team System

Jean-Luc David;Tony Loton; Erik Gunvaldson; Christopher Bowen;Noah Coad;Darren Jefford.Editorial: Anaya Multimedia /Wrox. Pág.: 784. Publicado: diciembre, 2006. ISBN: 978-84-415-2118-6

• Visual Basic 2005Bill Evjen, Rockford Lhotka, Billy Hollis y otros. Editorial: Anaya Multimedia /Wrox.

Pág.: 1.184. Publicado: enero, 2007. ISBN: 978-84-415-2106-3

dotN

etM

anía

<<

58

desván¿Qué son los “identicones”?

noticias.noticias.noticias

Son pequeños glyphso iconos, generadosmediante un algorit-mo criptográfico(SHA) con ciertasvariantes, y que per-mite asociar a cada dirección IP una imagen única, al obje-to de ayudar al reconocimiento visual de presencia de usua-rios, lugares, objetos o cualquier “identidad” informática.

El invento es obra de Don Park, pero Jeff Atwood yJohn Galloway lo han traducido directamente a .NET 2.0,habiéndose servido del código de Don Park, escrito en Javay optimizado por éstos. El algoritmo produce resultados úni-cos (gráficos distintos), si bien el autor reconoce que está tra-bajando en alguna solución rápida al problema de las IP diná-micas. ¿Será ese el nuevo carné de identidad gráfica en lared? De momento, el autor ha puesto a disposición públicael código en C# para aquellos que se animen a analizarlo.Disponible en www.codinghorror.com/blog/files/Identicon-sam-ple-vs-2005.zip.

Marino Posadas

¿Qué hace el padre de WebSphere en Microsoft?Esa es la pregunta que se hacen los redacto-res de ZDNet, respecto al reciente fichaje deDonald Ferguson, el padre de WebSphere(ver http://www-03.ibm.com/developerworks/blogs/page/donferguson?entry=software_in_the_next_five),que pasa a Microsoft como Chief Technology Offi-

cer (CTO), junto a Ray Ozzie, para dirigir los esfuerzos dedesarrollo de la suite Office.

Pero no es el único: el CEO de Ask.com(el buscador antes denominado Ask Jeeves), Ste-ve Berkowitz, tras pensárselo un par de sema-nas, también aceptó la propuesta de Gates yBallmer. Su visión de una nueva Microsoft, yde la tecnología, la expone en una entrevista on-

line realizada para el diario Seattle Times(http://seattletimes.nwsource.com/html/businesstechno-logy/2003535280_btberkowitzqa22.html).

Fix My VistaNoticias, trucos, parches y foros relacionados con el siste-ma operativo. Del autor de un sitio previo, llamadowww.FixMyXP.com, nace con el mismo espíritu que el anterior:mantener al lector a la última de lo que pasa en torno al siste-ma. Visitas en www.FixMyVista.com.

TopFree.net: Más que una utilidad, este mes quere-mos hacer referencia a un “sitio de utilidades gratui-tas”: TopFree.net. A pesar de su gratuidad, el con-junto de utilidades disponibles es de alta calidad, yofrece una posibilidad para buscar utilidades gratui-tas por criterios, de forma que puede ejercer de “dic-cionario de utilidades gratuitas”. Solo hay que recor-dar su dirección: www.topfreeware.net.

e-Book Compiler:Concluimos hoy conuna utilidad pensadapara autores: e-Book Compiler. Un software larga-mente premiado, que permite a los autores crear suspropios e-books de una forma sencilla y guiada (losprimeros usos son gratuitos). Descargas enhttp://www.ebookcompiler.com.

uti l idades del mes

sitios recomendados

Un gráfico entero en un solo fotón

Lo más de lo más en almace-namiento óptico

Por sorprendente que parez-ca, aunque la Física no deja de sor-prendernos nunca, éste es el resul-

tado obtenido por un equipo de físicos de la Universidadde Rochester, que han sido capaces de codificar primero, yrecuperar después, en un solo fotón, una imagen que nece-sitaría de un conjunto de datos con las técnicas informáti-cas actuales. El gráfico adjunto (las iniciales de la universi-dad), fue codificado por John Howell (jefe del equipo deinvestigación) y posteriormente recuperado, lo que abre elcamino al almacenamiento masivo de información en mediosópticos. “El problema hasta ahora”, comenta Ryan Cama-cho, firmante principal del artículo publicado en el presti-gioso Physical Review Letters, “era que podíamos almace-nar gran cantidad de información, pero la mayor parte deella se perdía en el intento de recuperación”. Howell siguetrabajando en esta idea, ahora para conseguir aumentar eltiempo válido de almacenamiento. Para una explicación másdetallada, vea el artículo en http://www.sciencedaily.com/rele-ases/2007/01/070119094254.htm.