dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic...

60
dedicada a los profesionales de la plataforma .NET Laboratorio www.dotnetmania.com entrevista Arturo Toledo Product Manager de WPF y Silverlight Microsoft Corporation dotNetManía El modelo de proveedores ASP.NET 2.0 nº 40 septiembre 2007 6,50 Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System Controles personalizados en WPF. Un scroll circular El motor de reglas de Windows Workflow Foundation Microsoft Solutions Framework (1) Comprimir con .NET Infragistics NetAdvantage for WPF TodotNet@QA Fallos poco conocidos en ASP.NET Comunidad .NET CatDotNet

Transcript of dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic...

Page 1: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dedicada a los profesionales de la plataforma .NET

Laboratorio

www.

dotne

tman

ia.co

m

entrevistaArturo ToledoProduct Manager de WPF y SilverlightMicrosoft Corporation

dotNetManíaEl modelo de proveedoresASP.NET 2.0

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

Controles personalizados en WPF. Un scroll circularEl motor de reglas de Windows Workflow FoundationMicrosoft Solutions Framework (1)Comprimir con .NET

Infragistics NetAdvantage for WPF

TodotNet@QAFallos poco conocidos en ASP.NET

Comunidad .NETCatDotNet

Page 2: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 3: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Bienvenido al número 40, de septiembrede 2007, de dotNetManía.

La notificación de la fecha de lanzamien-to de Visual Studio 2008, SQL Server 2008y Windows Server 2008 ha sido la noticiamás relevante de este verano, en el que tra-dicionalmente se suele atravesar una sequíainformativa. El marco elegido para esteanuncio fue la Worldwide Partner Confe-rence en Denver. Esta vez los partners hansido los protagonistas y no se habló tan-to de avances tecnológicos como de nue-vas oportunidades de negocio para ellos.Supongo, aunque lo mismo es muchosuponer, que también hay que tranquili-zar a este importante colectivo después deanunciar que Microsoft también venderáservicios para el año que viene. KevinTurner, jefe de operaciones de Microsoft,anunció que 2008 será para ellos, no unaño bueno, sino un año histórico... en ven-tas. Pienso que será un año histórico tam-bién por los avances tecnológicos que sepresentan, que son fruto —es cierto— dela inversión de miles de millones de dóla-res. Inversión que lícitamente se preten-de recuperar; como el propio Turner dijo“Estrategia sin ejecución es alucinación.Y nosotros no queremos alucinar, quere-mos traducir esto en dinero”. Sin pañoscalientes ☺.

La otra noticia importante es la publi-cación de la Beta 2 de Visual Studio 2008con licencia “go live”, que nos permite empe-zar ya con proyectos en producción.

Arturo Toledo, uno de los geren-tes de producto para WPF y para Sil-verlight, que se incorporó a MicrosoftCorp. de la mano de Forest Key, es unarquitecto de edificios que ejerce comoarquitecto de software, un diseñador quenunca usó un Mac, en marketing, pero téc-

nico... Este hombre de contrastes es elentrevistado de este mes. El diseño se estáimponiendo como parte esencial del desa-rrollo de aplicaciones, así que no podía-mos dejar pasar esta oportunidad de char-lar con Arturo a su paso por Madrid conocasión del Re-MIX 2007.

El grupo Weboo publica el artículo“Controles personalizados en WPF. Unscroll circular”, después del gran éxitoobtenido con su libro “Windows Presen-tation Foundation”, de la serie CuadernosTécnicos de dotNetManía —felicitadosincluso desde Microsoft Corp.—.

Hablando de WPF, este mes evalua-mos Infragistics NetAdvantage forWPF, una de las primeras librerías comer-ciales que aparecen con soporte para estatecnología.

El artículo de portada de este mes es“El modelo de proveedores de ASP.NET2.0”, de José Manuel Alarcón, en el quese investiga el modelo de proveedores de.NET, uno de los conceptos fundamenta-les sobre los que se sustenta ASP.NET 2.0.

Unai Zorrilla, viejo conocido de nues-tros lectores, publica este mes “El motorde reglas de Windows Workflow Foun-dation”, sobre los mecanismos y reglas quepueden variar el comportamiento de nues-tros flujos de trabajo.

Consulte la página 56, donde encon-trará una lista completa de cursos onlinegratuitos publicados recientemente porMicrosoft Ibérica. No piense que por gra-tuitos son poca cosa; han trabajado en ellosalgunos de los mejores autores hispanohablantes. Entre ellos, los mencionadosen esta editorial.

Espero que haya vuelto de vacacionescon buen humor y vea este número conbuenos ojos.

dotN

etM

anía

<<

3

2008, año histórico...

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 40 • Septiembre 2007Precio: 6,50 €

EditorPaco Marín ([email protected])

Redactor jefeMarino Posadas([email protected])

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

RedacciónDino Esposito, Guillermo 'Guille' Som, JoséManuel Alarcón, Luis Miguel Blanco y MiguelKatrib (Grupo Weboo)

Empresas Colaboradoras

Alhambra-Eidos

Plain Concepts

Raona

Solid Quality Learning

Además colaboran en este númeroAntonio Quirós, Joan Llopart, MiguelJiménez y Unai Zorrilla

Corresponsal para América LatinaPablo Tilotta

IlustracionesMascota (Clico): Yamil HernándezPortada: Javier Roldán

FotografíaRoberto Mariscal

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

Edición, suscripciones y publicidad.netalia

c/ Robledal, 13528529 Rivas-Vaciamadrid (Madrid)

www.dotnetmania.com

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

ImprimeGráficas MARTE

ISSN1698-5451

Depósito LegalM-3.075-2004

dotNetManíadotNetManía

Paco Marín

Page 4: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

sumario 40Ingeniería de producto versus ingeniería de proceso 10-11

Para poner al lector no habitual en antece dentes, diré que este artículo forma parte de unconjunto que trata de reflexionar sobre los distintos elementos que podemos interpretar comosignos de que una compañía que desarrolla software posee el necesario grado de madurez comopara terminar sus proyectos con éxito.

Entrevista a Arturo Toledo 12-15En ocasión de celebrarse en Madrid el ReMIX los pasados 4 y 5 de junio, tuvimos laoportunidad de tener entre nosotros a Arturo Toledo, Technical Product Manager en MicrosoftCorporation, que gentilmente accedió a concedernos una entrevista.

Eventos: III Summit de Solid Quality Mentors 16

Controles personalizados en WPF. Un scroll circular 18-24En este artículo se muestra cómo desarrollar controles personalizados en aquellos casos en losque el propósito de la personalización va más allá de los cambios de apariencia, o defuncionalidad, que pueden obtenerse combinando controles predefinidos de WPF.

El modelo de proveedores de ASP.NET 2.0 25-33Este artículo investiga el modelo de proveedores de .NET, uno de los conceptos fundamentalessobre los que se sustenta ASP.NET 2.0. Estudiaremos cómo funciona la arquitectura deproveedores y su importancia, y conoceremos la forma de crear nuestros propios proveedorespersonalizados.

El motor de reglas de Windows Workflow Foundation 34-38Cuando hablamos de procesos de negocio, indudablemente en algún momento tendremos quehablar de los mecanismos y reglas que puedan variar el comportamiento de los mismos y/o elflujo de nuestros procesos.

Microsoft Solutions Framework (I) 40-42En esta serie de tres artículos se quiere dar una visión global sobre las herramientas que en estecampo nos ofrece Microsoft y que suelen ser desconocidas incluso para los propios interesados. Elobjetivo no es tanto dar un completo repaso a estas metodologías como conocer las bases yelementos más interesantes para su aplicación en el trabajo diario.

Comprimir con .NET El compresor que lo comprima... puede usar la versión 2.0 o la 3.0 43-47

Si queremos comprimir (o descomprimir) ficheros con .NET Framework 2.0 sin usar libreríasexternas, podemos usar las dos clases que se definen en el espacio de nombres System.IO.Compression: DeflateStream y GZipStream. Por otra parte, en la versión 3.0 de .NETexisten clases que nos permiten crear ficheros del tipo ZIP. En este artículo veremos cómo usarlas clases que las dos versiones de .NET nos ofrecen para realizar las tareas de compresión.

dnm.todotnet.qa 48-50Fallos poco conocidos en ASP.NET

dnm.laboratorio.net 51-53Infragistics NetAdvantage for WPF

dnm.comunidad.net 54-56CatDotNet. Grupo de usuarios .NET de Catalunya Central

dnm.biblioteca.net 57Microsoft Windows Communication Foundation Step by StepLearning WCF: A Hands-on Guide

dnm.desvan 58

Page 5: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 6: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Microsoft® Visual Stu-dio® 2008 es un nuevoavance en línea con lavisión de Microsoft sobrelos clientes inteligentes,que permitirá a los desarrolladores crear de manera rápidaaplicaciones conectadas que ofrezcan experiencias de usuariode la más alta calidad. Con Visual Studio 2008, las organiza-ciones podrán capturar y analizar la información de la mane-ra más rápida posible, lo que les permitirá tomar decisionesde negocio efectivas. Visual Studio 2008 permite a las orga-nizaciones de cualquier tamaño crear de manera rápida apli-caciones más seguras, gestionables y fiables que aprovechentodas las ventajas de Windows Vista y 2007 Office System.

Visual Studio 2008 ofrece avances significativos alre-dedor de tres pilares fundamentales:

• Mejorar la productividad del desarrollador.• Gestionar el ciclo de vida de las aplicaciones.• Emplear las tecnologías más recientes.

Visual Studio 2008 ofrecerá nuevas experiencias deusuario que giran alrededor de estos tres pilares en sieteáreas de tecnología diferentes:

Desarrollo de clientes inteligentesVisual Studio 2008 brinda nuevas vías para que los desarro-lladores creen clientes inteligentes ofreciendo un conjuntocompleto de herramientas y librerías que simplifican la inte-gración de clientes inteligentes con aplicaciones Web nue-vas o ya existentes, y que permiten gestionar localmente encaché los datos en casos de escenarios desconectados.

Desarrollo de aplicaciones para OfficeVisual Studio Tools for Office (VSTO) está totalmenteintegrado dentro de Visual Studio 2008 Profesional y supe-riores. Visual Studio permite a los desarrolladores perso-nalizar varias aplicaciones de Office, como Outlook oPowerPoint, para mejorar la productividad del usuario ysimplificar el despliegue.

Desarrollo de aplicaciones para VistaLos desarrolladores podrán aprovechar las nuevas tecnologíasde la plataforma y ofrecer aplicaciones más atractivas a susclientes, incorporando sin esfuerzo las nuevas característicasde Windows Presentation Foundation tanto en aplicacionesWindows Forms existentes como en las nuevas aplicaciones.

Gestión de datos más productiva

La introducción de lasConsultas integradas en

los lenguajes (Language Integrated Query, LINQ) y devarias otras mejoras en el acceso a datos permitirá a losdesarrolladores trabajar con datos utilizando un enfo-que programático consistente, acceder a datos a travésde nuevas superficies de diseño y utilizar las nuevas cla-ses incorporadas a .NET Framework pensando en elpatrón de diseño ocasionalmente conectado.

Experiencia de desarrollo mejoradaVisual Studio 2008 brinda de manera generalizada unamejor experiencia de desarrollo a través de la combina-ción de mejoras significativas en la calidad del producto,cambios en la forma en que las superficies de diseño máspopulares comunican los errores al usuario y la simplifi-cación de la capacidad del usuario para adoptar de formaseparada el marco de trabajo y las herramientas.

Soporte para nuevas experiencias WebSobre la infraestructura robusta, segura y escalable de IIS,los desarrolladores podrán de manera sencilla crear apli-caciones Web eficientes e interactivas. La integración sinfisuras y el modelo de programación familiar de ASP.NETAJAX permitirá una ejecución eficiente del lado del clien-te para ofrecer a los usuarios finales una interfaz Web conuna mejor respuesta.

Mejor gestión del ciclo de vida de las aplicacionesLa gestión del ciclo de vida de las aplicaciones (Applica-tion Lifecycle Management, ALM) ofrece un gran soporteno solo para administrar de manera eficiente todo el ciclode vida de las aplicaciones, sino además para gestionar lainteracción crítica con los usuarios finales y el personalde TI encargado de una aplicación corporativa.

Estos avances fundamentales en la tecnología permi-tirán a los desarrolladores crear rápidamente aplicacionesconectadas que ofrecerán las experiencias de usuario másricas y de mayor calidad, con independencia de la com-plejidad del proyecto o el tamaño de la organización.

Para más información sobre Visual Studio 2008 y des-cargar la Beta 2, visite http://msdn.microsoft.com/vstudio. do

tNet

Man

ía<<

6

noticiasnoticias

noticias

noticias

noticias

Visual Studio 2008 Beta 2A finales de julio, Microsoft liberó al público la versión Beta 2 de lo que será Visual Studio 2008, anteriormenteconocido como “Orcas”. Esta versión incluye prácticamente todas las características que tendrá la versióndefinitiva del producto, e incluye una licencia “go live” que permite a los desarrolladores poner en producciónaplicaciones creadas con la herramienta. Por su importancia, resumimos aquí el documento de descripcióndel producto que ha publicado el fabricante.

Page 7: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 8: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

8

dnm.directo.noticias<<

Windows Server 2008, Visual Studio2008 y SQL Server 2008 ya tienen fechade lanzamiento

Nueva versión MZ-Tools 6.0para Visual Studio .NET consoporte para VS 2008

Carlos Quintero (Visual DeveloperMVP) ha liberado la versión 6.0 de MZ-Tools para Visual Studio .NET. MZ-Tools es un add-in o complemento paraincrementar la productividad trabajandocon Visual Studio que ofrece más de 40características adicionales en el entornode desarrollo. Esta versión no añade nue-vas funcionalidades, pero unifica en unasola el soporte para todas las versiones deVisual Studio: 2002, 2003, 2005 y 2008(“Orcas”). La Web (en español), es:http://www.mztools.com/v6/mztools6_sp.aspx.

Final de la Imagine Cup 2007Del 3 al 10 de agosto se desarrolló con

gran éxito en Seúl (Corea del Sur) la fase finalde la Imagine Cup 2007. En ella tomaronparte 344 estudiantes, agrupados en 112 equi-pos que representaban a 59 países, para lucharpor diferentes premios en nueve categorías.Los equipos ganadores en la categoría prin-cipal (Diseño de software) representaban aTailandia (1º lugar), Corea del Sur (2º) y Jamai-ca (3º). España estuvo dignamente represen-tada en esta fase final por el equipo Sc@ut dela Universidad de Granada.

Durante el acto de clausura se anun-ció que la fase final de la Imagine Cup 2008se celebrará en París (Francia) y su temacentral será “Imagina un mundo en el quela tecnología hace posible un entorno sos-tenible”.

Speaker Idol en TechEd Developers 2007

Ahora puedes de -mos trar tus dotes como

ponente y podrás ser unaestrella durante las presentaciones

del año que viene. El mejor presenta-dor ganará un pase para asistir como speakeral TechEd Developers 2008 y la oportunidadde presentar una sesión técnica. Solo tendrásque enviar un vídeo corto (3 minutos) reali-zando una presentación para empezar a cami-nar por la senda del éxito. La fecha límite parael envío es el 5 de octubre. Preséntalo en:http://www.microsoft.com/Europe/teched-develo-pers/speakeridol.aspx.

ILOG anunció el pasado mes de julio ladisponibilidad de ILOG Diagrammerfor .NET®, el primer kit de herramien-tas gráficas diseñado para crear diagramassofisticados y visualmente ricos para la pla-taforma .NET. Con ILOG Diagrammerfor .NET, los desarrolladores podrán con-figurar e integrar rápida y fácilmente sofis-ticados diagramas y pantallas de cuadrosde mando en sus aplicaciones WindowsForms y Web Forms. Se trata también delprimer producto de diagramación .NETque soporta la creación sencilla de inter-faces Web utilizando los controles AJAXASP .NET 2.0 recientemente introduci-dos por Microsoft.

ILOG Diagrammer for .NET estápensado especialmente para representardiagramas y pantallas de cuadros de man-do, lo que incluye redes, procesos, flujos,organigramas y diagramas UML (UnifiedModeling Language), así como control desupervisión y adquisición de datos (SCA-DA), control de procesos y pantallas decuadros de mandos. Este kit de herra-mientas ha sido diseñado de principio afin para entornos .NET.

ILOG Diagrammer for .NET secomercializa junto a tres completasherramientas de edición gráfica paraaquellos desarrolladores que deseanconstruir herramientas de modelado: elEditor de Diagramas de Clase UML, elEditor de notación Business ProcessModeling (BPMN) y el Editor genéri-co de Diagramas.

Estas aplicaciones se distribuyen concódigo fuente (C#) documentado y hansido diseñadas para su personalizacióno ampliación de acuerdo a las necesida-des del usuario final.

Más información http://www.ilog.com/products/diagrammernet.

ILOG lanza la plataforma gráfica Diagrammer for .NET

Kevin Turner, jefede operaciones deMicrosoft Corp.,anunció en laWorldwide PartnerConference cele-brada en Denver lafecha de lanza-miento para losproductos Visual

Studio 2008, SQL Server 2008 y Win-dows Server 2008. Dicho lanzamien-to tendrá lugar el 27 de febrero de2008 en Los Ángeles, y será el pisto-letazo de salida para otros cientos deeventos a nivel mundial en lo que será,según palabras del propio Turner, “el

lanzamiento más importante de lacompañía en un día”. Aunque el lanzamiento final será unifica-do, el estado actual del desarrollo de cadaproducto no es el mismo: el que va másadelantado es Windows Server 2008 delque se espera la versión RTM para fina-les de año, posiblemente noviembre; lesigue Visual Studio 2008, cuya versiónRTM es esperada para finales de este añotambién, o quizá para principios del 2008;y, por último, SQL Server 2008, del querecientemente ha publicado la versiónCTP de julio, pero aún se desconoce unafecha fiable para el lanzamiento de suRTM; incluso no se sabe si será antes del27 de febrero.

Page 9: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 10: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

casi todos los signos analizados han teni-do más que ver con elementos cercanos a lo que podemos denomi-nar ingeniería de proceso, es decir, aquello que estudia cómo nosorganizamos para hacer las cosas. En cambio, en esta entrega habla-remos sobre la ingeniería de producto, es decir, aquello que tieneque ver con las técnicas de producción que empleamos para lograrliberar la solución que el cliente nos demanda.

Sobre la ingeniería de producto podríamos manifestar conclu-siones en principio contradictorias y a veces hasta claramente opues-tas. Me explico. Por un lado, podemos afirmar que el ciclo de cons-trucción y vida del software está hoy bastante definido y estandari-zado. De ello se ocupan fundamentalmente UML y los modelos quede él se han derivado (MDA, etc.). Desde este punto de vista, pode-mos decir que, desde la educción de requisitos hasta el manteni-miento evolutivo del producto, UML nos dice cómo tenemos queactuar y qué técnicas debemos emplear para representar de una mane-ra formalmente correcta las soluciones que hemos de construir paranuestro cliente. Pero, lamentablemente, por otro lado tengo que afir-mar que a pesar de la existencia de estos modelos, aún no son lo sufi-cientemente explícitos como para que podamos afirmar sin génerode dudas que dada la representación formal de un sistema, por ejem-plo a través del modelo de clases, los casos de uso u otras técnicas,de dicha representación se derivará como un efecto de su causa elsoftware final que el cliente desea.

Sólo tenemos que pensar lo que sucede en otros entornos deingeniería; por ejemplo, en el diseño de piezas, elementos mecáni-cos, etc., o incluso en el más conocido a nivel popular de la arqui-tectura. Todos sabemos que una vivienda se representa de un modoformalmente correcto a través de los diferentes planos de la misma,de la memoria de calidades y de otros elementos que no solo sonmuy descriptivos del producto final sino que, además, están tan popu-larmente difundidos que su interpretación no genera polémica. Deforma independiente a estos instrumentos, tenemos otros más eru-ditos y menos comprensibles para el común de los mortales; temas

Ingeniería de producto versusingeniería de proceso

<<Hasta el momento,

Antonio Quirós escolaborador habitual

de ddotNetManía. Co-fundador de las revis-

tas clippeRManía, FOX-Manía y Algoritmo.

Actualmente es direc-tor de operaciones en

Alhambra-Eidos.

Para poner al lector nohabitual en antece -dentes, diré que esteartículo forma parte deun conjunto que tratade reflexionar sobre losdistintos elementos quepodemos interpretarcomo signos de que unacompañía que desarrollasoftware posee elnecesario grado demadurez como paraterminar sus proyectoscon éxito.

opinión

Antonio Quirós

Page 11: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

como la resistencia de materiales, la cargasoportada por una estructura, etc. son ele-mentos más técnicos, pero que aportanmenos en el hecho trascendental de queel que compra una vivienda y el que laconstruye tengan un lenguaje común conel que ponerse de acuerdo.

Lo malo de la industria del softwarees que su ingeniería de producto cubre sólola parte erudita y técnica, pero ha avanza-do muy poco en la parte de ese lenguajecomún entre cliente y desarrollador delque acabamos de hablar. Es decir, quetenemos herramientas que nos permitenhacer el cálculo de estructuras, pero notenemos planos con los que nuestros clien-tes sepan evaluar la casa que en el futuroles entregaremos.

Por todo esto, creo que en el ámbitode la ingeniería de producto nos queda unamplio camino por recorrer. Sé que estopuede parecer demasiado heterodoxo, perono creo que el paradigma actual sea sos-tenible en un futuro donde la simplicidadse valora cada vez más en cuanto a cómose presentan las relaciones entre usuariosy suministradores. La complejidad técni-ca habremos de reservarla para el diseñotécnico del producto, algo interno que nor-malmente deberá permanecer opaco paralos usuarios del mismo, pero en la capareal que el cliente valora y necesita debe-remos dar grandes pasos para simplificarlos envarados sistemas actuales, que pocoaportan al proceso de entendimiento sinotal vez oscuridad y complejidad.

En este orden de cosas, deberíamoshablar del prototipado como una de lastendencias que podría acercar al usuarionuestra enrevesada ingeniería de produc-to; sin embargo, éste no me parece el cami-no más adecuado. Prototipar es caro y cos-toso en tiempo; una vez elaborado el pro-totipo, prácticamente tendremos más deun cincuenta por ciento de la capa de pre-sentación de nuestra aplicación desarro-llada. Esto no parece asumible, máximecuando para realizar de forma sensata estacapa habremos de haber confeccionadoantes una parte relevante del diseño téc-nico; es decir, que habremos tenido quepasar previamente por largas reunionescon los usuarios, escribir tediosas actas yrealizar complejos diseños de clases. O loque es lo mismo, que para presentarle a

nuestro usuario el piso piloto hemos teni-do que construir prácticamente toda laestructura del edificio. Cuando lo quevamos a hacer es una urbanización con 500viviendas iguales esto sirve, pero cuandolo que estamos es haciendo software amedida para nuestro cliente, y el prototi-po lo único que supone es un elemento devalidación contractual, parece que la uti-lidad es desproporcionadamente baja res-pecto al coste de la inversión a realizar.

A estos problemas añadiría otro deenorme relevancia. Se trata de que tam-poco tengamos un lenguaje formal rigu-roso para la representación de los requi-sitos de usuario. Solemos emplear paradicha representación nuestro lenguaje con-vencional y éste, como todos sabemos, esbastante confuso y polisémico, de formaque difícilmente nos servirá para repre-sentar con claridad elementos que tienenque ser exactos. De esta forma, las fichasde requisitos se convierten en literaturaque rara vez es leída con afán validador pornuestros usuarios y que, por tanto, arro-jan como consecuencia que la aplicacióndesarrollada muchas veces no trabaja de laforma exacta con que nuestro clientedemandaba que lo hiciera.

Bien, los problemas están sentados.No quiero exacerbarlos y, desde luego, megustaría romper una lanza por UML y loque está suponiendo de estandarización yfacilidad para la construcción automáticade software basada en sus bien definidastécnicas para la construcción de software.No es en esta parte de la ingeniería de pro-ducto donde quiero catalogar las defi-ciencias, sino más bien en la que sirve parainteractuar con los usuarios; es decir, conla que representa los requisitos de éstos y

es capaz de convertirlos en especificacio-nes claras, entendibles y, por tanto, vali-dables. Locos estaríamos si pensáramosque un usuario nos va a validar un mode-lo de clases. Como mucho, lo hará con uncaso de uso, y para ello lo único que habráhecho será leer contenidos, nada pareci-do a lo que hacemos cuando vemos el pla-no de la casa que hemos encargado y lamemoria de calidades de la misma.

Llegados aquí, deberíamos afirmar queel signo de madurez de cualquier empre-sa que desarrolla software es, respecto a laingeniería de producto, conocer y usarUML para el diseño técnico y conocer laslimitaciones que la educción de requisitosy la representación de los mismos poseen,de forma que se pongan sobre el tablerode la relación con el usuario las mejoresprácticas históricas para garantizar que larepresentación formal de esos requisitosse realiza de forma comprensible. En unoscasos esto se logrará a través de la realiza-ción de prototipos; en otros, fomentandola formación de los usuarios para garanti-zar que su visión del proceso sea más rea-lista; en otros, mejorando la capacidad rela-cional de nuestros analistas; en otros, desa-rrollando iterativamente de forma que losusuarios vayan viendo poco a poco losresultados del software que nos ha encar-gado; y, seguramente, un largo etcétera deprácticas acumuladas que cada equipotendrá.

Lo importante es no quedarnos emba-rrancados en el conflicto; es decir, endefender ciegamente que la aplicación hacelo que el usuario nos dijo que hiciera, cuan-do no hemos sido capaces de representarcon claridad para nuestro cliente aquelloque le proponíamos.

dotN

etM

anía

<<

11

dnm.opinión<<

Lo malo de la industria del software es que su inge-niería de producto cubre sólo la parte erudita y técni-ca, pero ha avanzado muy poco en la parte de ese len-guaje común entre cliente y desarrollador

Page 12: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Miguel Jiménez

Miguel Jiménez es MVP de Visual

C# y responsable deformación para ilitia

Technologies.Coordina el Madrid.NET User Group

y es líder de INETA en España([email protected])

http://geeks.ms/blogs/mjimenez

FotografíaRoberto Mariscal

entrevista

entrevista a Arturo ToledoEn ocasión de celebrarse en Madrid el ReMIX los pasados 4 y 5 dejunio, tuvimos la oportunidad de tener entre nosotros a ArturoToledo, Technical Product Manager en Microsoft Corporation, quegentilmente accedió a concedernos una entrevista.

Page 13: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Arturo, es un placer tenerte entrenosotros. En primer lugar, ¿cuál estu rol en Microsoft Corp.?

El título de lo que hago es muy,muy largo, así que lo voy a resumir:soy uno de los gerentes de productopara WPF y para Silverlight, me espe-cializo —dentro del equipo de mar-keting— en la elaboración de los con-tenidos técnicos. Tal vez, de las per-sonas de marketing, soy la personaque más tiempo pasa delante del orde-nador con las herramientas. Creotutoriales, entrenamientos y materia-les para sitios Web, como por ejem-plo los vídeos que se pueden ver en elsitio de Expression. Con el tiempoespero dedicar aún más tiempo a laparte técnica, pero siempre desde elpunto de vista de marketing.

Una de las cosas más curiosas de tuperfil es que ¡has estudiado arqui-tectura! ¿Cómo alguien que viene dela arquitectura de edificios acabacomo arquitecto de software?

La historia es muy larga. Desdepequeño programaba en Basic. Mi padretrabajaba en IBM y me llevaba a su tra-bajo, y yo acababa dibujando en las tar-jetas perforadas, como premonición deesta mezcla actual de diseño y progra-mación. Yo estaba seguro de llegar a serprogramador o ingeniero, pero cuandollegó la época de la preparación para la

Universidad hice una maqueta de unacasa, y pensé que lo que realmente megustaba era el diseño. Me gustaba más

que la programación, a la que veía máscomo una herramienta que como mediode expresión. Comencé arquitectura, peroal salir empecé a utilizar herramientas dediseño como 3D Studio Max, Director,Photoshop, etc., y acabé con un trabajomás de diseñador que el propio de arqui-tecto (yo creo que la gente espera a unarquitecto más maduro). En el diseño

interactivo encontré más libertad y crea-tividad, y más negocio también, y volví alos inicios de mi infancia.

¿Desde cuándo llevas en Microsoft?¿Empezaste directamente en el equi-po de Expression?

Hace dos años. En el 2003, cuandoMicrosoft anunció Longhorn y yo vique incluía Avalon, con cosas de ani-mación, vectores, sonido, vídeo, etc.,pensé “esto es algo que quiero hacer”.Les empecé a seguir en los foros y ahíes donde conocí a Forest Key, al queyo veo como el padre fundador delentendimiento con los diseñadores,quien empezó a traer a diseñadores, agente de mi perfil.

Dentro de la gama Expression tenéiscinco productos: Blend, Web, Desig-ner, Media y Media Encoder. Hemospasado de 0 productos a 5 en un año;sin embargo, el mercado al que lle-ga cada producto ya está ocupadopor otros productos (Flash, AdobePhotoshop…). ¿Qué perfil de per-sonas crees que empezarán a usarlos productos Expression o migraránde los programas existentes?

dotN

etM

anía

<<

13

dnm.directo.entrevista<<

Miguel Jiménez y Arturo Toledo en un momento de la entrevista

Aprovecho para invitar a la gente para que se meta en los foros de discusión o que nos envíenemails pidiéndonos lo que quieren, porque ahora mismo el equipo de desarrollo está empezando

a trabajar sobre la versión 2, y se está haciendo la lista de requisitos

Page 14: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

14

dnm.directo.entrevista<<

Nosotros no creemos que esas per-sonas tengan que dejar de usar sus plata-formas. Nosotros tenemos millones dedesarrolladores que usan exitosamente laplataforma .NET y que nos han trans-mitido la necesidad de expresar su crea-tividad tanto en aplicaciones Web comode escritorio. Por eso, Microsoft ha cre-ado estas herramientas para un nuevo seg-mento, el de diseñadores, para que éstospuedan trabajar con los desarrolladorescreando experiencias conjuntas. Estasherramientas están dedicadas a los diseña-dores que estén buscando estas cosas: cre-atividad, lo que ya estamos buscando conWPF y Silverlight, permitiendo a losdesarrolladores hacer cosas muy innova-doras; y negocio, porque con Expression,Microsoft está dando a los desarrollado-res la llave para que entren en un nuevomercado: el mundo de Microsoft; todasesas empresas de desarrollo de aplicacio-nes Microsoft querrán hacer cosas “cool”,y hoy en día la mayoría no tienen diseña-dores para hacerlo.

Es cierto que posiblemente no sea másque acercar el mundo del diseño almundo del desarrollo; pero es indu-dable que hay una lucha, que posible-mente acabe ganando Microsoft, quees Silverlight vs. Flash. Me gustaría vertu visión de Silverlight como plug-inde contenido interactivo y Flash comoplug-in de contenido interactivo en laWeb, ¿qué aporta Silverlight en rela-ción a Flash?

Desde el punto de vista del diseñador,usar Silverlight me va a permitir trabajarcon desarrolladores. Cuando era diseña-dor independiente yo contrataba desa-rrolladores para que me hicieran el códi-go en ActionScript u otro lenguaje y mecostaba mucho encontrarlos, porque losdesarrolladores que trabajan para laempresa, que hacen desarrollos muyrobustos, no suelen usar estos lenguajes.Ahora con Silverlight, si tuviera mi agen-cia de diseño, no tendría problemas, por-que Silverlight soporta los lenguajes.NET (más de 30 en la actualidad, ni sabíaque fueran tantos).

Esta es una de las cosas que veo inte-resantes, y la otra es el soporte de vídeode Silverlight: es vídeo de alta calidady en un formato estándar, el códec VC-1, lo que permitirá gracias a la expan-sión de la banda ancha en todo el mun-do acceder a contenidos de alta defini-ción en streaming y reproducirlo encualquier sitio; ahora puedo hablarle aun Mac con Windows Media Video.

Hablando de Mac, seguro que tú tam-bién has tenido esa relación de amor yodio que algunos hemos tenido…

Pues la respuesta es no. Yo no habíausado un Mac en mi vida, hasta hace unpar de meses. La razón es muy sencilla:como mi padre trabajaba en IBM en ladécada de los 80, yo el Mac siempre lo vicomo algo poco interesante. Bueno, has-ta ahora que ha regresado Steve Jobs ylos ha hecho muy atractivos. Además, enarquitectura, Autocad o 3D Studio Maxeran más fuertes en PC.

Una de las cosas que más me sor-prendió cuando estuve en el MIX y

me regalaron una caja con algunasversiones de Expression es que almeter uno de los discos en un Mac¡funcionaba! ¿Qué versiones de losproductos habéis desarrollado paraMac?

Expression Media. Es el único quefunciona en Mac. Es un producto quese adquirió no hace mucho a unaempresa inglesa. Era un producto condiez años de existencia, muy popular,bien establecido tanto en la comuni-dad de PC como de Mac y sobre todode gente dedicada a la fotografía, aun-que hoy lo estamos llevando más alláde las fotos, con audio, vídeo e imáge-nes. Queríamos seguir apoyando a esacomunidad que ha usado ese produc-to por años en su Mac.

¿Y el resto de herramientas se va adesarrollar para Mac?

Hasta ahora no hay planes de eso,pero siempre estamos analizando loque dicen nuestros clientes.

Una de las cosas que está pasandoúltimamente es que se ha puesto demoda esto de la Web interactiva:Ajax, Flash, Silverlight…, un montónde cosas para desarrollar contenidointeractivo. Pero hay uno de estosdinosaurios de la tecnología al quele hemos visto morir muchas veces,pero siempre resucita: Javascript, unlenguaje odioso, un lenguaje parahacer prototipos y que, sin embar-go, se ha extendido hasta límitesinsospechables. Me gustaría saberqué soporte dan las herramientas deExpression para que sean los pro-pios diseñadores y no los desarro-lladores los que interactúen con ser-vicios Ajax o con otros servicios Webdirectamente desde el lado deldiseño.

Ahora mismo, la única herramien-ta de la suite Expression que te puededar un cierto apoyo para Javascript esExpression Web. Puedes escribir tucódigo en Javascript y en ExpressionWeb tienes tu codificación por colores;

Page 15: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

15

dnm.directo.entrevista<<

pero es limitado, por ejemplo, no tene-mos Intellisense…

Pero Blend sí tiene Intellisense paraJavascript…

Blend solo tiene editor de códigopara XAML, pero no puedes progra-mar en Javascript o en C#. Cualquiercosa de este tipo, de lógica de negocio,tienes que hacerla con Visual Studio.Hablando de Visual Studio, se está tra-bajando mucho para soportar Javascriptmejor que nunca, como tú decías es elmonstruo que vive y muere.

En cuestión de componentes Ajax,en Expression Web versión 2 estamospensando en reforzarlo para que pue-das arrastrar y soltar controles Ajax sinnecesidad de programar.

¿Hablas ya de la versión 2?Sí, de hecho aprovecho para invitar a

la gente para que se meta en los foros dediscusión o que nos envíen emails pidién-donos lo que quieren, porque ahora mis-mo el equipo de desarrollo está empe-zando a trabajar sobre la versión 2, y seestá haciendo la lista de requisitos. Pre-cisamente uno de ellos es esta integracióncon Ajax, pero también estamos buscan-do una mejor integración con Silverlight,soporte para PHP, etc. Ahora es elmomento para que tus lectores aprove-chen para decir “quiero más PHP”, “quie-ro más Silverlight”, etc.

Es la primera vez que vienes aEspaña, ¿qué te ha parecido elREMIX?

De todos los eventos REMIX(habré ido a 6 con éste), éste es en elque he visto más gente y he visto elescenario más atractivo: es como un tea-tro antiguo que genera una atmósferamuy divertida, sobre todo para losdiseñadores1. No sé si será por el idio-ma, pero en Milán o Estocolmo, porejemplo, no hubo tanta conexión encuestión de comunicación. Aquí ha

habido mucha oportunidad de conocera la gente. Yo creo que va muy a la parde España, de cómo es la gente, es muyparecido a Méjico, no pensé encontraresto en un país europeo.

Si hay algo más que quieras decir alos lectores…

Únicamente invitarles a que usenExpression, que usen WPF y Silver-

light. Pero sobre todo me interesa verqué hacen los diseñadores junto conlos desarrolladores españoles. Ya hevisto esta mañana tres demos que nohabía visto en mi vida, que mostróDavid Carmona (por ejemplo, la delos barquitos está buenísima). Estoyseguro que un año, para los siguientesMIX y REMIX, vamos a tener muchí-simos más ejemplos.

1 Como el lector sabrá, el REMIX al que Arturo alude se celebró en el Círculo de Bellas Artes de Madrid.

Page 16: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Del 18 al 22 de junio se celebró en su centro de Regusla tercera edición del evento anual que Solid QualityMentors (antes, Solid Quality Learning) organizaantes del verano, y que estuvo enfocado en las 3 áre-as principales de trabajo de la empresa: División Rela-cional (centrada en SQL Server), División BI (BusinessIntelligence) y División de Desarrollo (.NET 2.0 y 3.0).

Este año se batieron todos los records anterioresde asistencia (unas 75 personas), siendo los horariosen sesiones de mañana y tarde, y estando el lunes dedi-cado a tres seminarios (gratuitos para los asistentes)centrados, respectivamente, en tres de los temas mássolicitados por los desarrolladores: Optimización yCasos de Éxito del motor rela-cional SQL Server 2005, Busi-ness Intelligence en SQL Ser-ver 2005 y Performance Point2007, y Novedades de .NETFramework 3.0 (WPF, WCF yWWF), Windows Vista y Offi-ce 2007 para el desarrollo deaplicaciones.

El elenco de ponentes esta-ba formado —en su mayorparte— por mentores españo-les y latinoamericanos de lacompañía: desde el propioCEO, Fernando Guerrero,hasta mentores bien conoci-dos, como Antonio Soto,Miguel Egea, Eladio Rincón,Guillermo Som (el Guille),Jesús López (SQLRanger),Francisco González, CarlosSacristán, Rubén Garrigós yMarino Posadas, por parteespañola, y Daniel Seara,Adolfo Wiernik y JavierLoria, venidos de Latinoamé-rica con ocasión del evento.Pero se contó además conabundante presencia externa ala compañía, destacando entreella a Salvador Ramos (MVPSQL Server), representantes

de Quest Software, que mostraron las estrategiasde la empresa para la optimización de bases de datos(basadas en su paquete de aplicaciones), David Sal-gado de Microsoft Ibérica, quién charló sobre lasúltimas novedades de AJAX y colaboró en otra delas ponencias sobre novedades del desarrollo paraWindows Server 2008, así como Emilio Iborra yThierry Reinard, de AMI2. Incluso los asistentestuvieron —dado el carácter tan especial e interac-tivo de estos eventos— un papel fundamental, comofue el caso de Daniel Matey, quien aportó nume-rosas experiencias personales de primera mano enWindows Server 2008.

III Summit de Solid Quality Mentors

eventos

<<

event

os

Fernando, ¿cuál es el objetivo de esteSummit?. Conseguir un mayor nivelde contacto con nuestros clientes y que—quienes aún no lo son— vean cuáles la forma que tenemos de abordar losproblemas en Solid Quality Mentors:asesorando siempre de forma personalcada problema personal. Debido a esto,nuestro abordaje de las necesidadesempresariales es único, con un backgroundavalado por nuestra amplia experienciay trabajos para las principales empresasdel sector en todo el mundo, incluyen-do la propia Microsoft (EE.UU), y porla riqueza de posibilidades que un con-junto de mentores distribuido a nivelmundial puede ofrecer. Hay pocasempresas capaces de hacer una oferta deesa naturaleza.

¿Qué es lo que hace al SQM Summitdiferente de los demás eventos priva-dos?. Justamente, eso, el grado de inte-racción que el asistente tiene con nues-tros mentores. Muchos vienen a propo-nernos sus dudas, sus preguntas acercade la estrategia que están siguiendo enun desarrollo, a saber la conveniencia deuna migración, o a que les demos una

visión tecnológica con los pies en la tie-rra de qué pueden aportar las tecnologí-as emergentes para sus empresas. Y todoel mundo vuelve con una respuesta ade-cuada a sus necesidades. Creo que esa esla gran diferencia, incluso con respectoa otros eventos de más calado, como elTech-Ed, por ejemplo.

¿Cuáles han sido los resultados y quéprevisiones tienes respecto al futurode este evento?. Bueno, tú lo has visto:casi 80 asistentes, un gran número deempresas relevantes del sector que noshan visitado, docenas de entrevistas indi-viduales —aparte las charlas— para expli-caciones personalizadas, un libro resu-men con algunas de las charlas más sig-nificativas y colaboraciones externas degran valor. Creo que éste es el camino aseguir y esperamos que así lo reconoz-can nuestros clientes en próximas edi-ciones, en las que seguiremos mejoran-do. De momento, preparamos una giradespués del verano, justamente para aten-der necesidades de clientes que no pudie-ron estar con nosotros en Madrid. Enbreve publicaremos los detalles en nues-tro sitio Web (www.solidq.com).

Hablamos con Fernando Guerrero

Page 17: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 18: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Quien haya implementado controles personali-zados en Windows Forms estará familiarizadocon la clase System.Windows.Forms.Control y conmétodos como OnPaint y OnLayout, que permi-ten indicar las instrucciones de cómo se dibujay se ubica espacialmente un control. En Win-dows Forms, junto con la apariencia personali-zada del nuevo control hay que definir tambiénla reacción de éste a los eventos de hardware(clics de ratón, acciones de teclado, etc.) y a loseventos que se disparan cuando cambie el valorde propiedades del control (PropertyChanged).De hecho, los controles Windows Forms no vie-nen a ser más que envoltorios de las ventanasde Windows para los que los eventos están aso-ciados a un único control, de modo que si se tie-ne un control dentro de otro, los eventos queocurran en el control más interno no se propa-gan al control contenedor.

Si para alguna aplicación de Windows Formsusted se ha empeñado en pulir el acabado de algúncontrol personalizado, seguramente habrá tenidoque recurrir a un conjunto de técnicas adiciona-les, como estar sintonizando valores con el tipoenumerado ControlStyles para mejorar lacalidad o el rendimiento del control.

Por otro lado, en las aplica-ciones Web los controles perso-nalizados tienen como base prin-cipal la clase System.Web.UI.Con-trol. Por la propia naturaleza de la

arquitectura Web, estos controles deben tener unaparte ejecutando del lado del cliente y otra del ladodel servidor, por lo que en este caso el control seimplementa en dos universos diferentes: del ladodel servidor se tiene un objeto de un tipo herede-ro de Control (implementado en cualquier lenguaje.NET) que es el que representa la lógica funcio-nal del control, mientras que del lado del clientese tiene un HTML (puede que con algún códigoJavascript embebido) que es generado en el servi-dor por la acción de la redefinición personalizadadel método OnRender. Este HTML representa laparte visual e interactiva del control y los eventosen este entorno viajan entre el cliente y el servi-dor mediante los mecanismos de postback y call-back. La calidad visual y el rendimiento del con-

Controles personalizados en WPF.

Un scroll circular

plataforma.net

Miguel Katrib es doctor yprofesor jefe de progra-

mación del departamentode Ciencia de la Compu-tación de la Universidadde La Habana. Miguel eslíder del grupo WEBOO,dedicado a la orientacióna objetos y la programa-ción en la Web. Es entu-

siasta de .NET y redactorde dotNetManía.

Mario del Valle, IskanderSierra y Yamil Hernándezson instructores de pro-gramación en C# de la

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

del departamento deCiencia de la Computa-

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

lladores del grupoWEBOO dedicados a la

tecnología .NET.

En este artículo se muestra cómo desarrollar controles personaliza-dos en aquellos casos en los que el propósito de la personalización vamás allá de los cambios de apariencia, o de funcionalidad, que puedenobtenerse combinando controles predefinidos de WPF.

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

Page 19: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

trol en el lado del cliente dependentambién de cada navegador.

Precisamente una de las bondadesde WPF es combinar las cualidades deambos mundos (Web y escritorio) enuna arquitectura que aprovecha mejorlos recursos de .NET y las nuevas capa-cidades del hardware. WPF fue cons-truido sobre los sólidos cimientos deDirectX y las tarjetas gráficas, de modoque la calidad de la visualización y surendimiento dejen de ser una preocu-pación.

Los controles de WPF se definen apartir de un tipo .NET heredero de Sys-tem.Windows.Controls.Control siguien-do el patrón Modelo Vista Controlador(MVC), que de algún modo subyace enel mundo Web, y que separa la lógicafuncional del control de su apariencia einterfaz visual. Esto se apoya funda-mentalmente en la inclusión de una pro-piedad Template en la clase Control (figu-ra 1). A través de esta propiedad Templa-te se indica el código XAML que des-cribe la interfaz visual e interactiva delcontrol.

En WPF, los cambios visuales deri-vados de modificaciones a los valoresde las propiedades de un control se pue-

den manejar con los Trigger. Con losRoutedEvent se tratan los eventos queresponden a ocurrencias del hardware,que ahora con este nuevo mecanismode WPF se propagan a todos los nive-les de contención de los controles queestén ubicados en un formulario.

En una entrega anterior de dotNet-Manía [1] vimos cómo con WPF se pue-de definir un panel personalizado paraespecificar una forma particular de des-plegar los elementos en un panel. En esteartículo vamos a ver cómo se puede defi-nir también un control personalizado, queademás de su forma de visualizarse tendrásu propia funcionalidad de interacción.

¿Realmente necesito un con-trol personalizado?

La interfaz visual de los controlesde WPF está definida en una plantilla(objeto de tipo ControlTemplate) querepresenta el árbol visual, posiblemen-te especificado declarativamente enXAML. Con ello, si lo que caracterizaal aparente control personalizado es unanueva apariencia, podemos obtenerdicho efecto cambiando su interfaz

visual, es decir definiendo una nuevaplantilla y asociándola a la propiedadTemplate del control. Intente por ejem-plo personalizar la apariencia de con-troles predefinidos como Button o Com-boBox.1

Cambiar la apariencia visual es la cau-sa fundamental que exige tener que escri-bir controles personalizados en muchasaplicaciones Windows Forms, pero aho-ra en WPF esto se puede lograr solo concambiar la plantilla asociada al control.Sin embargo, es posible que el propósi-to de personalización requiera tambiénde alguna nueva funcionalidad que no estédisponible para algún control en parti-cular, y entonces un cambio en la planti-lla no bastaría. Puede ser que incluso paraalgunas situaciones de este tipo baste concombinar varios controles en uno que loscontenga y que sea este contenedor quiendefina la lógica de interacción entre suspartes. Por ejemplo, si se quiere hacer un

dotN

etM

anía

<<

19

dnm.plataforma.net<<

Figura 1. Relación datos-apariencia en un control WPF

1 Puede ver más sobre las plantillas de controles en el Cuaderno Técnico No 7 de dotNetManía [3]2 Esto es solo un supuesto, porque realmente controles como éste también están disponibles en WPF.

Cambiar la aparienciavisual es la causa funda-mental que exige tenerque escribir controles

personalizados enmuchas aplicaciones

Windows Forms, peroahora en WPF esto sepuede lograr solo con

cambiar la plantilla asociada al control

Page 20: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

20

dnm.plataforma.net<<

control que permita seleccionar la ruta deubicación de un archivo2, tal control pue-de ser construido combinando un Text-Box, que permita escribir la ruta, y unbotón que despliegue un diálogo de selec-ción de carpetas. Para casos como éstos,en Windows Forms hemos tenido losUserControl, que también siguen tenien-do presencia en WPF, y que ahora ademástienen como ventaja las formas en que sepropagan los RoutedEvent[2, 3].

De modo que aún no queda claro sinecesitamos definir un nuevo tipo decontrol, razón por la cual antes de selec-cionar la opción “File” | “New” | “Pro-ject” | “Windows/WPF ControlLibrary” debemos repasar primero loscontroles existentes y los posibles tiposbase de lo que es ahora en WPF unaenriquecida jerarquía de controles (figu-ra 2), no vaya a ser que nos pongamosa reinventar la rueda.

Tipos derivados de Control

Ahora además de la clase raíz Con-trol se tienen otros tres tipos derivadosque sirven de base para definir nuevoscontroles:

• ContentControl, que representa alos controles que muestran uncontenido simple en su interior.

Ejemplos de este tipo son Buttony Label.

• ItemsControl, que es el controlbase de todos aquellos controlesque muestran una lista de conte-nidos. Ejemplos de este tipo sonListBox o ComboBox.

• TextBoxBase, que es la base de loscontroles que tienen entrada detexto, como son los casos de Text-Box y RichTextBox.

A su vez, ContentControl se divideen otros tres grandes grupos: los con-troles que además de un contenido tie-nen un encabezamiento (HeaderedCon-tentControl), como el GroupBox o elExpander; los que actúan como unbotón (ButtonBase), entre los cualesestán Button, ToggleButton y CheckBox;y los que usted desee implementar porcomposición de otros controles (User-Control).

Por otra parte, el tipo ItemsControlsirve de base a otros dos grupos más:los controles de selección (Selector),como el ListBox y el ComboBox, y los Hea-deredItemsControl, que son controlesde lista con una suerte de encabeza-miento, por ejemplo los elementos demenú (MenuItem), los nodos del TreeView(TreeViewItem) y el ToolBar.

En el espacio de nombres System.Windows.Controls.Primitives se puedenencontrar algunos de los tipos de con-troles más útiles que sirven de base paradefinir otros controles. Ahí están Button-Base y TextBoxBase, pero también seencuentran otros como RangeBase, que esla base de los controles de selección denúmeros en un rango (el Slider y elScrollBar son dos de los más significati-vos herederos de RangeBase).

Figura 3. Scroll circular

Figura 2. Jerarquía básica de controles WPF

Fronteras de los valores mínimo y máximounidas en un mismo punto del scroll circular

Page 21: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

21

dnm.plataforma.net<<

El scroll circular

Supongamos que quisiéramos unasuerte de “scroll circular”, es decir, uncontrol que como el ScrollBar y el Sli-der nos sirva para seleccionar un valordentro de un rango, pero que además ten-ga la característica de que cuando la pro-piedad Value del control alcance el valormáximo (Maximum) del rango, entonces elcontrol “dé la vuelta”, es decir, tome elvalor mínimo (Minimum). Adicionalmen-te, es deseable que el área dentro del con-trol que representa la porción del conte-nido visible de la información asociada alscroll (segmento de color azul en la figu-ra 3) también pueda cruzar la fronteraentre el valor máximo y mínimo.

Los controles como el Slider y elScrollBar no parecen cumplir con talescaracterísticas, pero ¿por qué no?

Si inspeccionamos las propiedades,métodos, eventos y comandos del con-trol ScrollBar, no parece haber limi-tantes para obtener lo que deseamos.Aparentemente, es posible crear unaplantilla para asociarle a un ScrollBar yobtener un scroll como el de la figura 3,de modo que el valor del rango en elque varía el ScrollBar sirva para calcu-lar el ángulo de rotación del cilindroazul que representa al viewport delScrollBar. El estilo con la plantilla dellistado 1 nos da este efecto.

El primer enlace (Binding) que seindica en el código a continuación (yque aparece resaltado en negrita en elListado 1) enlaza la propiedad View-

portSize del ScrollBar con la propiedadSweepAngle del tubo azul (que representala amplitud de lo que se muestra conrespecto del total):

<Style x:Key=”Scroll3D” TargetType=”{x:Type ScrollBar}”>

<Setter Property=”Template”>

<Setter.Value>

<ControlTemplate TargetType=”{x:Type ScrollBar}”>

<Grid Background=”Red” Height=”{TemplateBinding ActualWidth}”>

<this:TorusBuilder BubbleSegments=”30” SweepAngle=”360”

BubbleRadius=”0.25”/>

<this:TorusBuilder BubbleSegments=”30”

BubbleRadius=”0.23” Name=”InnerTube”>

<SweepAngle>

<Binding Path=”ViewportSize”

RelativeSource=”{RelativeSource TemplatedParent}”>

<Binding.Converter>

<this:ValueToAngleConverter/>

</Binding.Converter>

</Binding>

</SweepAngle>

</this:ArcTubeBuilder>

<Viewport3D>

<Viewport3D.Camera>

<PerspectiveCamera Position=”16,0,0” LookDirection=”-1,0,0”

FieldOfView=”45” UpDirection=”0,0,1”/>

</Viewport3D.Camera>

<ModelVisual3D>

<ModelVisual3D.Content>

<Model3DGroup>

<AmbientLight Color=”#8888”/>

<DirectionalLight Color=”AliceBlue” Direction=”-1,1,-1”/>

</Model3DGroup>

</ModelVisual3D.Content>

</ModelVisual3D>

<ModelVisual3D>

<ModelVisual3D.Content>

<Model3DGroup>

<GeometryModel3D Geometry=”{Binding Path=Geometry,

ElementName=InnerTube}”>

<GeometryModel3D.Material>

<MaterialGroup>

<DiffuseMaterial>

<DiffuseMaterial.Brush>

<LinearGradientBrush EndPoint=”0,0.5”

SpreadMethod=”Reflect”>

<GradientStop Color=”Blue” Offset=”0”/>

<GradientStop Color=”SkyBlue” Offset=”1”/>

</LinearGradientBrush>

</DiffuseMaterial.Brush>

</DiffuseMaterial>

<EmissiveMaterial>

<EmissiveMaterial.Brush>

<LinearGradientBrush EndPoint=”0,0.5”

SpreadMethod=”Reflect” Opacity=”0.5”>

<GradientStop Color=”Blue” Offset=”0”/>

<GradientStop Color=”Blue” Offset=”1”/>

</LinearGradientBrush>

</EmissiveMaterial.Brush>

</EmissiveMaterial>

<SweepAngle><Binding Path=”ViewportSize”

RelativeSource=”{RelativeSource

TemplatedParent}”>

<Binding.Converter><this:ValueToAngleConverter/>

</Binding.Converter>

</Binding></SweepAngle>

Listado 1. Estilo del scroll circular 3D (continúa...)

Page 22: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

22

dnm.plataforma.net<<

Más adelante en el listado 1 apare-ce un segundo Binding (segmento decódigo que se ha replicado a conti-nuación) que enlaza la propiedad Valuedel ScrollBar con la propiedad Anglede la rotación de este tubo respecto delcentro del entorno tridimensional(Viewport3D):

Note que para lograr esta represen-tación visual se ha utilizado la clase Torus-Builder, que se encarga de generar la geo-metría tridimensional (GeometryModel3D)del tubo circular (torus) que representa alscroll circular. Por limitaciones de espa-cio, el código completo de esta clase nose incluye aquí, pero el lector lo puededescargar del sitio Web de dotNetManía.También se ha incluido un convertidor(AngleToValueConverter) para convertirel valor del control que está entre los valo-res Minimum y Maximum en un ángulo entre0 y 360.

Si ahora desde el código de la apli-cación se cambiase el valor de la pro-piedad Value del ScrollBar, como resul-tado se observará que el tubo azul semueve a la posición apropiada. Peroesto no nos basta, porque si se quiereque este scroll tenga una funcionalidadsimilar a la de un scroll clásico, el “tuboazul” de la figura debería poderse moveral arrastrar el ratón sobre él (figura 4).Para ello no es suficiente con cambiarla plantilla del control.

Se requiere de una nueva definiciónde la interacción con el ratón diferen-te a la que tiene el tipo ScrollBar. ¿Sig-nifica esto que entonces sí es necesariodefinir un nuevo tipo de control? Comose verá en la sección siguiente, WPF nodeja de sorprendernos con la organiza-

</MaterialGroup>

</GeometryModel3D.Material>

<GeometryModel3D.BackMaterial>

<DiffuseMaterial>

<DiffuseMaterial.Brush>

<LinearGradientBrush EndPoint=”0,0.5”

SpreadMethod=”Reflect”>

<GradientStop Color=”Blue” Offset=”0”/>

<GradientStop Color=”SkyBlue” Offset=”1”/>

</LinearGradientBrush>

</DiffuseMaterial.Brush>

</DiffuseMaterial>

</GeometryModel3D.BackMaterial>

<GeometryModel3D.Transform>

<RotateTransform3D>

<RotateTransform3D.Rotation>

<AxisAngleRotation3D Axis=”0,0,1”/>

<Angle>

<Binding Path=”Value”

RelativeSource=”{RelativeSource

TemplatedParent}”>

<Binding.Converter>

<this:ValueToAngleConverter/>

</Binding.Converter>

</Binding>

</Angle>

</RotateTransform3D.Rotation>

</RotateTransform3D>

</GeometryModel3D.Transform>

</GeometryModel3D>

<GeometryModel3D Geometry=”{Binding Path=Geometry,

ElementName=Tube}”>

<GeometryModel3D.Material>

<DiffuseMaterial Brush=”#6FFF”/>

</GeometryModel3D.Material>

<GeometryModel3D.BackMaterial>

<DiffuseMaterial Brush=”#6FFF”/>

</GeometryModel3D.BackMaterial>

</GeometryModel3D>

<Model3DGroup.Transform>

<RotateTransform3D>

<RotateTransform3D.Rotation>

<AxisAngleRotation3D Axis=”0,1,0” Angle=”30”/>

</RotateTransform3D.Rotation>

</RotateTransform3D>

</Model3DGroup.Transform>

</Model3DGroup>

</ModelVisual3D.Content>

</ModelVisual3D>

</Viewport3D>

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

(...continuación) Listado 1. Estilo del scroll circular 3D

<Angle><Binding Path=”Value”

RelativeSource=”{RelativeSource

TemplatedParent}”><Binding.Converter>

<this:ValueToAngleConverter/></Binding.Converter>

</Binding></Angle>

Page 23: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

23

dnm.plataforma.net<<

ción de los elementos que brinda paraconformar una interfaz de usuario.

Controles primitivos y elementos frontera

System.Windows.Controls.Primitives

es el espacio de nombres de los elemen-tos y controles primitivos de WPF. Aquíestán algunos tipos conocidos que son úti-les como ButtonBase o RangeBase que sir-ven de base para otros controles, perotambién hay otros tipos que se usan comoelementos “frontera”3 entre los estilosvisuales y los propios controles. Por ejem-plo, controles como ScrollBar y Sliderse apoyan en uno de estos elementos lla-mado Track. Un Track se compone de dosRepeatButton ubicados en los extremos4

del control y un Thumbpara moverse entreellos. Son todos estos elementos que com-ponen el Track los que se ocupan de lalógica de interacción con el control através del ratón. De hecho, el propioScrollBar está definido como control pri-mitivo, también detro de System.Win-dows.Controls.Primitives.

Siguiendo esta misma lógica, paralograr interactuar con el ratón y nues-tro scroll circular lo que realmente senecesita es implementar una nueva pri-

mitiva que juegue el rol del anteriortrack. Tal funcionalidad sí hay queimplementarla en código .NET. El lis-tado 2 muestra una implementación enC# de este nuevo elemento que hemosdenominado CircleTrack.

Note que CircleTrack no heredade Control sino de Decorator. Los con-troles en WPF son, sobre todo, aque-llos elementos a los cuales se les debepoder asociar una plantilla visual, peroéste no es el objetivo con el que esta-mos definiendo CircleTrack. Lo quese quiere es un elemento que reaccio-ne ante el efecto de hacer un movi-miento circular con el ratón, lo cualpuede ser aprovechado por otros con-

Figura 4. Scroll tradicional y scroll circular

public class CircleTrack : Decorator {bool dragging = false;protected override void OnMouseDown(MouseButtonEventArgs e) {dragging = true;base.OnMouseDown(e);

}

protected override void OnMouseMove(MouseEventArgs e) {if (dragging){Point mousePos = e.GetPosition(e.Source as IInputElement);Point middle = new Point(ActualWidth / 2.0, ActualHeight / 2.0);double angle = 180 * Math.Atan2(middle.Y - mousePos.Y, mousePos.X –

middle.X) / Math.PI;Angle = (angle + 360) % 360;

}base.OnMouseMove(e);

}

protected override void OnMouseUp(MouseButtonEventArgs e) {dragging = false;base.OnMouseUp(e);

}

public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(“Angle”, typeof(double), typeof(CircleTrack));

public double Angle {get { return (double)GetValue(AngleProperty); }set { SetValue(AngleProperty, value); }

}}

Listado 2. Implementación de CircleTrack

3 El término frontera es una metáfora. En inglés se le llaman «PART elements». Son elementos que se usan en la definición de un Template con laintención de imponer determinada funcionalidad a un control; pero a diferencia del resto de la plantilla, ellos no se definen en XAML, sino quetienen que ser definidos en un lenguaje del CLR. Estos elementos pueden ser controles o no, pero no están asociados a ninguna jerarquía.

4 Los extremos indican visualmente los valores máximo y mínimo que se pueden alcanzar desplazando el scroll.

Page 24: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

24

dnm.plataforma.net<<

troles como el caso de nuestro Scroll-Bar para cambiar el tubo azul de posi-ción. Como lo que se desea es que estafuncionalidad se aplique a los elemen-tos que se pongan en la plantilla delcontrol, es conveniente hacer que Cir-cleTrack actúe como Decorator, que esuno de los tipos de WPF que se pue-den emplear para agregar fácilmentenuevas funcionalidades, como es elcaso de reaccionar ante el movimien-to circular de arrastrar el ratón. Comoen WPF la cualidad de enrutamientohace que los eventos se propaguen a

todos los elementos que contengan alelemento que recibe directamente laacción original, entonces al arrastrarcon el ratón un elemento ubicado enel interior del CircleTrack (en nuestrocaso el Viewport3D) podremos hacerque éste reaccione a tales eventos gra-cias a la propagación.

Lo que hay que hacer ahora esincorporar en el listado 1 el nuevo deco-rador CircleTrack, para que el View-port3d quede contenido dentro de éste,como se muestra en el listado 3. Conello habremos combinado la apariencia

circular con la capacidad de reaccionaral arrastre del ratón.

Observaciones finalesPor simplicidad y por las limita-

ciones de espacio solo se ha imple-mentado en el CircleTrack el soportea la reacción del scroll ante los even-tos del ratón. Como el lector debesaber, un ScrollBar es algo más queesto. En una implementación másacabada debe agregarse tambiénsoporte para comandos de desplaza-miento corto y largo (los equivalen-tes a LineDown, LineUp, Pagedown, PageUpde un scroll horizontal o vertical).También se podría encapsular mejoraún la conversión del valor en ángu-lo y viceversa para simplificar la defi-nición de los estilos visuales.

Finalmente, es importante hacernotar que el ScrollBar tiene comandos ypropiedades como la propiedad Track,que devuelve el control Trackque éste uti-liza. Sin embargo, tal propiedad carecede sentido cuando el ScrollBar esté fun-cionando como scroll circular, por lo quecon una pretensión más profesional habríaque pensar si en lugar de lograr nuestroobjetivo con las plantillas y el CircleTrackcorrespondería también implementarotro control, digamos un tal CircleScrollque herede de RangeBase, y que al teneruna interfaz de código más simple lo hagamás cómodo y apropiado respecto alograr los efectos de circularidad que aquíse han mostrado.

Esperamos que con estos razona-mientos el lector tenga una suficiente can-tidad de preguntas con las que practicarsu comprensión de estas ideas.

<Style x:Key=”Scroll3D” TargetType=”{x:Type ScrollBar}”>

<Setter Property=”Template”>

<Setter.Value>

<ControlTemplate TargetType=”{x:Type ScrollBar}”>

<Grid Background=”Red” Height=”{TemplateBinding ActualWidth}”>

<this:ArcTubeBuilder .../>

<this:ArcTubeBuilder ...> ... </this:ArcTubeBuilder>

<this:CircleTrack>

<Angle>

<Binding Path=”Value” Path=”TwoWay”

RelativeSource=”{RelativeSource TemplatedParent}”>

<Binding.Converter>

<this:ValueToAngleConverter/>

</Binding.Converter>

</Binding>

</Angle>

<Viewport3D>

...

</Viewport3D>

</this:CircleTrack>

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Listado 3. Adición del decorador CircleTrack

ReferenciasKatrib Miguel, del Valle Mario, Sierra Iskander, Hernández Yamil, “Cómo definir nuestros propios paneles personalizados enWPF”, dotNetManía nº 35, marzo 2007

Som Guillermo, “El enrutador que los enrute…”, dotNetManía nº. 34, febrero 2007

Del Valle Mario, Sierra Iskander, Hernández Yamil, Katrib Miguel, “Windows Presentation Foundation”, dotNetManía, Cua-derno Técnico nº 7, marzo 2007

[1]

[2]

[3]

Page 25: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

25

ASP.NET 2.0 es un entorno de desarrollo de apli-caciones Web extenso y complejo en sus entresijos.A pesar de que dispone de multitud de característi-cas que nos ahorran muchas horas de trabajo, éstasno siempre se adaptarán a nuestras necesidades. Porejemplo, desde la versión 1.0 del producto dispone-mos de tres formas de almacenar el estado de sesiónde nuestras aplicaciones. Por defecto, éste se alma-cena en el mismo proceso de ejecución de ASP.NET,pero con un simple cambio en el archivo de confi-guración Web.config podemos conseguir que lasvariables de sesión se persistan en un servidor cen-tral de estado o en una base de datos de SQL Ser-ver. Con estas tres opciones tenemos para el 95% delos casos habituales. Pero, ¿qué pasa si necesitamosalmacenar la información en otro lugar, como porejemplo una base de datos Oracle? ¿Y si aún usandouno de los tres almacenamientos anteriores quere-mos cambiar su comportamiento en ciertas circuns-tancias? En ASP.NET 1.x tendríamos muy difícilcambiar cualquiera de estas cosas. No nos quedaríamás remedio que “trucar” la plataforma y escribirpartes enteras de ésta de nuevo para poder sustituir-las de modo no-nativo.

En ASP.NET 2.0 han aparecido muchas nuevasAPI que nos facilitan las tareas más comunes, comola gestión de la seguridad a través de Membership yRoles, el almacenamiento de preferencias con Pro-files, el registro de eventos de aplicaciones con WebE-vents, y multitud de cuestiones más. Cuando en algu-na charla o curso enseño los fundamentos de Mem-bership y Roles, algo de uso muy habitual, los oyen-

tes suelen quedar encantados con las posibilidadesque éstas ofrecen. Sin embargo, siempre hay alguienque de repente cae en la cuenta de lo mucho que tuvoque trabajar para conseguir algo similar en ASP.NET1.x, y la pregunta lógica no tarda en aparecer: “Si usoMembership y Roles, ¿qué pasa con la inversión quehe hecho para desarrollar mi propio método? ¿Cómopuedo usar mi propia base de datos de usuarios queya había creado y aprovechar las facilidades de la nue-va API?”. Se trata de una pregunta lógica y relacio-nada directamente con el modelo de proveedores.Al final de este artículo estaremos en disposición decontestarla.

El patrón de diseño de proveedoresUn proveedor es un componente de software queproporciona la implementación de una interfaz están-dar y que aísla a un servicio del medio de almacena-miento u obtención de datos que utiliza para supropósito. En lenguaje llano, se trata de un compo-nente intermedio que separa una funcionalidad dellugar donde almacenamos su información. El fun-cionamiento de un servicio que sigue el modelo deproveedores se puede modificar simplemente cam-biando de manera externa (por configuración) el pro-veedor que éste utiliza por debajo. Es decir, el pro-veedor se sitúa entre la API final que usa el progra-mador y el medio de almacenamiento empleado. Deeste modo, aunque se cambie el proveedor no hayque tocar el código y el programa pasa a funcionar

plataforma.net

José Manuel AlarcónAguín es redactor de ddot-

NetManía. Es ingenieroindustrial y especialista en

consultoría de empresa.Ha escrito varios libros, y

ha publicado más de tres-cientos artículos sobreinformática e ingeniería

en revistas especializadas.Es MVP de ASP.NET,

MCTS, MCPD, MCT ytutor de campusMVP.

Visite su blog enwww.jasoft.org

José Manuel Alarcón

El modelo de proveedores de

ASP.NET 2.0Este artículo investiga el modelo de proveedores de .NET, uno de los concep-tos fundamentales sobre los que se sustenta ASP.NET 2.0. Estudiaremos cómofunciona la arquitectura de proveedores y su importancia, y conoceremos la for-ma de crear nuestros propios proveedores personalizados.

Page 26: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

26

de una forma diferente sin que sea per-ceptible para el programador.

Por ejemplo, en la API de seguridadRoles podemos hacer que los perfiles alos que pertenecen nuestros usuarios selean desde una base de datos SQL Ser-ver en donde previamente los habremosalmacenado, o bien que se compruebencontra el Directorio Activo de nuestraorganización. Para ello no tendremos quetocar el código de la aplicación ni recom-pilarla. Lo único que se debe hacer escambiar un ajuste en Web.config para queesta API haga uso de un proveedor dife-rente en cada caso. Dicho proveedor secargará de forma transparente para noso-tros por el motor de tiempo de ejecuciónde .NET, y funcionará “de tapadillo”,dando el soporte a las funciones de la API.

El esquema de la figura 1 muestra demanera clara el concepto. Cada una delas API representadas en la parte supe-rior de la figura dispone de uno o másproveedores nativos (capa del medio)que utilizan su correspondiente mediode almacenamiento (capa inferior). Losservicios representados en la figura sonsolo unos pocos de los disponibles real-mente. Casi toda funcionalidad deASP.NET 2.0 que tenga que ver conalmacenar un estado o mover un datoestá implementada usando este modelo.Enseguida veremos qué servicios tene-mos disponibles de esta manera.

En definitiva, los objetivos que se per-siguen con el modelo de proveedores son:• Aislar tanto nuestro código como el

de ASP.NET de la implementacióny funcionamiento concreto de lamayor parte de las API de alto niveldisponibles.

• Hacer que el almacenamiento sea fle-xible para adaptarlo a nuestras nece-sidades, y extensible para poder usarotros medios de persistencia alterna-tivos. Tiene a todo el mundo conten-to: si nos sirve la implementación pordefecto de una API, simplemente lausamos. Si no se nos adapta, podemoscambiarla o crear una propia.

• Que sea muy fácil crear nuestros pro-pios proveedores, proporcionando

un sistema de clases base bien docu-mentado que nos den parte del tra-bajo ya hecho.

• Permite separar de manera sencilla laslabores de desarrollo para trabajo enequipo: mientras unos trabajan en laaplicación en sí con proveedores pordefecto, otros pueden trabajar en para-lelo en la implementación concretaque se necesite de una característica.

Tipos de proveedores y proveedores disponiblesASP.NET 2.0 ofrece soporte para elmodelo de proveedores en todos losservicios ilustrados en la figura 2. Cadauno de estos servicios dispone de almenos un proveedor nativo integradoen la plataforma, si bien todos ellospermiten la creación de proveedoresadicionales que nos permiten adaptarsu funcionamiento a nuestras necesi-dades. También se puede escribir códi-go que en lugar de crear un nuevo pro-veedor se limite a modificar el com-portamiento existente de cualquiera delos nativos.

En la tabla 1 se pueden ver los pro-veedores nativos disponibles para cadauno de los servicios. Los que tienen unasterisco al final son los proveedorespor defecto que se usan en el servicio,

si no los modificamos mediante con-figuración. Tanto la API para notifi-cación de eventos Web como la de pro-tección y cifrado de secciones de con-figuración carecen de un proveedorpor defecto (ninguno tiene un asteris-co en la tabla), ya que en ambos casoses necesario establecerlos manual-mente tocando la configuración si que-remos usarlos.

El funcionamiento de los proveedores

Para ver mejor los entresijos delfuncionamiento de los proveedores, yantes de meternos de verdad en harina

Figura 1

Figura 2

Page 27: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

27

construyendo uno propio, fijémonos encómo están implementados los prove-edores de Membership de la platafor-ma (figura 3).

Como podemos observar, tenemosuna clase llamada MembershipProviderque hereda de la clase base abstractaBaseProvider. Esta clase a su vez es tam-bién abstracta, de modo que no es éstala que define el funcionamiento del pro-veedor, sino que se usa como plantillade lo que debe implementar un prove-edor de este subsistema Membership.Es entonces cuando aparecen los pro-veedores concretos que se van a utili-zar. Así, el proveedor SqlMembership-Provider hereda de MembershipProvidery sobrescribe la mayor parte de losmétodos de éste para crear una imple-mentación concreta de la funcionalidadrequerida. Todo ello forma una jerar-quía que va de lo más general a lo con-creto. La clase BaseProvider forma loscimientos de todos los proveedores, y

cada subsistema o API concreto definesu clase abstracta adaptada a sus nece-sidades, de la cual heredan los provee-dores concretos que se van a utilizar.

La definición en C# de la clase Base-Provider es la siguiente:

Solo define el nombre del proveedor,su descripción y un método de inicializa-ción que es lo verdaderamente impor-tante. Al estar declarados los métodoscomo virtuales, las clases que heredan deésta, como MembershipProvider o los pro-veedores finales, tienen la opción deimplementarlos para recoger desde laconfiguración los parámetros de perso-nalización que sean necesarios.

public class ProviderBase{public virtual string Name {get;}public virtual string Description {get;}public virtual void Initialize (string name,

NameValueCollection attributes);}

Figura 3

Servicio Proveedores nativos disponibles

Usuarios (Membership) System.Web.Security.SqlMembershipProvider *

System.Web.Security.ActiveDirectoryMembershipProvider

Roles (Role) System.Web.Security.SqlRoleProvider *

System.Web.Security.AuthorizationStoreRoleProvider

System.Web.Security.WindowsTokenRoleProvider

Navegación (SiteMap) System.Web.XmlSiteMapProvider *

Perfiles de usuario (Profile) System.Web.Profile.SqlProfileProvider *

Estado de sesión (Session) System.Web.SessionState.InProcSessionStateStore *

System.Web.SessionState.OutOfProcSessionStateStore

System.Web.SessionState.SqlSessionStateStore

Eventos Web System.Web.Management.EventLogWebEventProvider

System.Web.Management.SimpleMailWebEventProvider

System.Web.Management.TemplatedMailWebEventProvider

System.Web.Management.SqlWebEventProvider

System.Web.Management.TraceWebEventProvider

System.Web.Management.WmiWebEventProvider

Personalización de Webparts System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider *

Protección de la configuración System.Configuration.DPAPIProtectedConfigurationProvider

System.Configuration.RSAProtectedConfigurationProvider

Tabla 1. Proveedores nativos disponibles en ASP.NET 2.0

Page 28: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

28

Por ejemplo, si escribimos enWeb.config la definición siguiente parael proveedor SqlMembershipProvider:

Durante la llamada que la API rea-liza automáticamente al método Initia-lize de la clase SqlMembershipProvider,el código recupera todos los atributosespecificados dentro de la colección attri-butes que se le pasa como segundo pará-metro. Así se ajustan diversas propieda-des y se personaliza el comportamientodel proveedor desde la configuración.Luego lo veremos. Dado que BasePro-vider proporciona su propia imple-mentación también del método de ini-cialización, suele ser conveniente lla-marlo desde el nuestro. Además, la cla-se intermedia (en este caso Membership-Provider), aunque es abstracta, gene-ralmente proporciona algunos servicioscomunes ya construidos. Por ejemplo,en el caso que nos ocupa el cifrado delas claves para almacenarlas de formasegura no hace falta que lo implemen-temos, pues disponemos de un métodoEncodePassword que se encarga de ellopor nosotros. Aunque, claro está, notenemos porqué usarlo.

Solo crearemos clases propiasderivadas de ProviderBase si necesi-tamos definir un modelo de provee-dores para un servicio nuevo creadodesde cero por nosotros, pero no paraun servicio existente. En este caso,para definir un proveedor propio

heredaremos de la clase derivada deProviderBase que se haya definidopara el servicio que nos interesa per-

sonalizar. En el caso de Membershipserá de MembershipProvider, pero enel caso de la API de protección de laconfiguración sería ProtectedConfi-gurationProvider, y de forma análo-ga en los demás casos.

En la figura 4 se muestra la jerar-quía de clases de proveedores que vie-nen con ASP.NET 2.0. No vamos a

analizar el código de ninguna de estasimplementaciones. No nos llegaríauna docena de artículos como éste.Aprenderemos creando un nuevo pro-veedor propio. No obstante el lectorinteresado puede encontrar el códigofuente completo de todos los provee-dores nativos de ASP.NET en lasiguiente URL:

http://download.microsoft.com/download/a/b/3/ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkit-Samples.msi

Microsoft los liberó hace unosmeses para facilitar su estudio y fomen-tar el uso del modelo de proveedoresen aplicaciones propias. Son dignos depararse a estudiarlos. Se aprendemucho.

Proveedores de mapas de sitiosVeamos ahora un ejemplo de cómo cre-ar un proveedor propio para personali-zar el comportamiento de un subsiste-ma de ASP.NET 2.0. El caso típico que

<system.web><membership><providers><add name=”AspNetSqlMembershipProvider”

type=”System.Web.Security.SqlMembershipProvider,System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”

connectionStringName=”LocalSqlServer” enablePasswordRetrieval=”false” enablePasswordReset=”true” requiresQuestionAndAnswer=”true” applicationName=”/” requiresUniqueEmail=”false” passwordFormat=”Hashed” maxInvalidPasswordAttempts=”5” minRequiredPasswordLength=”7” minRequiredNonalphanumericCharacters=”1” passwordAttemptWindow=”10” passwordStrengthRegularExpression=”” />

</providers></membership></system.web>

Figura 4

Page 29: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

29

se suele encontrar por Internet es el quecrea un proveedor propio de Mem-bership y/o Roles. El lector interesadoen ver un ejemplo sencillo de éstos(mucho menos complejo que el de losproveedores nativos antes menciona-dos) puede descargar desde CodePlexlos “proveedores simples de Altairis”:

http://www.codeplex.com/Wiki/View.aspx?ProjectName=AltairisWebProviders

Dado que hay muchos ejemplos deeste estilo por ahí, intentaremos ser unpoco más originales y hacer algo dife-rente a lo habitual y que ilustre otrotipo de proveedor menos típico. Unacuestión interesante nueva enASP.NET 2.0 son los controles denavegación. Éstos (menús, árboles yrutas) están enlazados a datos y bebeninformación de un control fuente dedatos llamado SiteMapDataSource. Bas-ta con arrastrar sobre un formularioWeb un control SiteMapDataSource yun control de navegación como un<asp:Menu> para tener implementada ensegundos la navegación de un sitio oaplicación.

Estos controles SiteMapDataSourceobtienen la información jerárquica denavegación a partir de un determinadoproveedor de estructura de sitio. Si nosfijamos en la figura 4, veremos que elúnico proveedor nativo disponible parala navegación por un sitio es el XmlSite-MapProvider. Éste es un proveedor espe-

cializado en leer archivos XML que con-tienen información sobre la estructurade páginas que queremos utilizar para lanavegación. El archivo que se utiliza pordefecto se llama Web.sitemap, si bien esposible definir diversos archivos XMLdiferentes para navegaciones parcialescon sólo añadir nuevos proveedores deeste tipo.

La estructura de uno de estos archi-vos de navegación es análoga a ésta:

Como podemos imaginar es un tan-to tedioso de construir, sobre todo por-que Visual Studio no nos proporcionaningún tipo de editor para facilitarnosla tarea.

Creación de un proveedorpersonalizado

En muchas ocasiones, sobre todoen aplicaciones sencillas, nos resultaríade mucha más utilidad poder generarde forma automática la estructura delsitio directamente a partir de los archi-vos y carpetas que éste contiene. Así,bastaría con arrastrar un control y vercómo obtenemos la navegación “de lanada”, con enlaces para ir a las dife-rentes páginas y carpetas del sitio.

Eso es precisamente lo que vamosa construir. Nuestro proveedor per-sonalizado se llamará FSSiteMapProvi-der (de File System SiteMap Provider),y no necesitará archivo alguno para

trabajar, ya que recorrerá la estructu-ra de contenidos de la carpeta que leindiquemos dentro de nuestro pro-yecto, y generará automáticamenteuna jerarquía de navegación gemela.Nos resultará de mucha utilidad a lahora de crear la navegación de aplica-ciones de tamaño pequeño o media-no. Es extraño que Microsoft no hayaincluido algo así de serie en ASP.NET.

Lo primero que debemos hacer esañadir una nueva clase a nuestra carpe-ta App_Code. Le llamaremos igual que elproveedor, FSSiteMapProvider:

Al heredar de StaticSiteMapProvi-der deberemos redefinir dos métodosabstractos que es indispensable crear yque ya nos genera Visual Studio pornosotros. El primero de ellos se llamaBuildSiteMap y sirve, como su propionombre indica, para construir el mapadel sitio a partir del medio de persisten-cia elegido, en este caso una carpeta deldisco duro. El motor de tiempo de eje-cución de ASP.NET llama automática-mente a este método cuando necesitagenerar un mapa del sitio.

El listado 1 muestra el código paraeste método en nuestro ejemplo (elcódigo completo está disponible paradescarga en la Web de dotNetManía).Este código es bastante sencillo, ya quese ha dividido por claridad en métodosauxiliares que hacen el trabajo “de fon-do”. Esto nos permitirá además enten-der mejor lo que está pasando.

He definido para la clase una seriede variables privadas que se usan paraalmacenar estados internos necesarios

<?xml version="1.0" encoding="utf-8" ?><siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

<siteMapNode title="" url="" description="foo" roles="*" ><siteMapNode title="Inicio" url="~/default.aspx"/><siteMapNode title="Usuarios" url="~/Usuarios.aspx" /><siteMapNode title="Contactos" url="~/Contactos.aspx" />

<siteMapNode Title=”Administración” roles=”Administradores”><siteMapNode title="Empresas" url="~/Extras/Empresas.aspx" /><siteMapNode title="Altas pendientes" url="~/Extras/AltasPendientes.aspx" />

</siteMapNode>

</siteMapNode>

</siteMap>

Imports Microsoft.VisualBasic

Imports System.Web

Imports system.IO

Public Class FSSiteMapProvider

Inherits StaticSiteMapProvider

...

End Class

Page 30: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

30

para trabajar. El nombre de todas ellascomienza con un guión bajo, que es lanotación que suelo usar en mi códigopara este tipo de miembros.

Los mapas de sitio son una jerar-quía de nodos de tipo SiteMapNode. Cadauno de ellos contiene una referenciatanto en sentido ascendente como des-cendente, es decir, a su nodo padre y asus hijos. Por este motivo, para obte-ner un mapa completo sólo es necesa-ria la referencia al nodo raíz de la jerar-quía, ya que ASP.NET puede recorrerlaen el sentido que prefiera para generarlos mapas. Es por ello que este primermétodo devuelve simplemente una cla-se de tipo SiteMapNode.

Lo primero que se hace es compro-bar si ya existe un mapa del sitio previa-mente generado en la variable _nodoRaiz.Para no tener que estar recorriendo eldisco siempre que alguien haga una peti-ción y generar de nuevo el mapa en cada

ocasión, lo que hacemos es generarlo unaprimera vez y a partir de ese momento loalmacenamos en una variable privada, queserá lo que se devuelva en sucesivas oca-siones. También comprobamos (con cor-tocircuito) si ha cambiado la estructurade carpetas de la carpeta raíz de nuestromapa. Más tarde volveremos sobre estedetalle, pero de momento vamos a olvi-darnos porque es accesorio a la creacióndel proveedor en sí.

Si no hay ninguna copia del mapa encaché o ha cambiado la estructura de dis-co, volvemos a generar la jerarquía denuevo. El método Resetear simplemen-te borra la caché en caso de que exista,para empezar con la jerarquía desde cero.Se crea el primer nodo indicando la rutafísica y la virtual de la carpeta raíz que usa-remos para generar el mapa. Ésta se espe-cifica mediante configuración, como lue-go veremos, y se almacena en la variableprivada _carpetaRaiz.

El método CrearNodo se puede veren el listado 2. Éste aísla la lógica decreación de objetos SiteMapNode, y tra-ta de manera distinta a los nodos quevan a apuntar a carpetas y a los queapuntan a archivos. Si se trata de unacarpeta hace caso omiso de las que sonde sistema, esto es, las que empiezancon el nombre “App_” (como App_Code)y la carpeta bin, que no deben apareceren la navegación. Además, cuando seañade una referencia a una carpeta sele añade automáticamente el nombrede la página por defecto, Default.aspx,que deberá existir (podría optimizarseeste código para comprobar su exis-tencia, pero lo dejo para el lector). Elnodo se crea indicando el proveedor(Me), la ruta física y ruta virtual a la queapunta, y como título para éste el nom-bre de la carpeta o del archivo sin laextensión.

A este primer nodo creado directa-mente se le asigna el título que se hayaindicado en la configuración (luego loveremos), y que se lee a través de unpropiedad personalizada llamada Ini-cio. Se añade el nodo al mapa del pro-veedor usando una versión sobrecarga-da del método AddNode que ya imple-menta la clase base. Con esto quedaestablecida la raíz de la jerarquía.

Una vez que tenemos el primernodo, generamos los subsiguientes reco-rriendo la estructura de disco a partir dela carpeta raíz elegida. He creado unafunción a tal efecto llamada CreaMapaA-PartirDe. Se trata de una función recur-siva que toma como parámetros el nodoactual y la ruta de una carpeta cuyosarchivos debemos incluir como hijos deéste en el mapa. El código de este méto-do se muestra en el listado 3. Usando laclase System.IO.DirectoryInfo, añadi-mos como hijos del nodo actual tantosnodos como archivos .aspx haya en lacarpeta indicada. Además, por cada car-peta contenida en éste se añade tambiénun nodo hijo, y la función se llamarecursivamente a sí misma para generarlas entradas para sus archivos. Es labelleza de la recursividad.

Public Overrides Function BuildSiteMap() As System.Web.SiteMapNode

‘Para evitar conflictos cuando varios procesos llamen al método al mismo tiempoSyncLock Me‘Veo si no tenemos un mapa almacenado en memoria‘o si ha sido añadido, eliminado o modificado algún archivo o carpeta bajo la raízIf _nodoRaiz Is Nothing OrElse _monitor.HasChanged Then

‘Desechamos lo que teníamos y regeneramos el mapaResetear()

‘Creamos el nodo raíz, que apunta a “/”_nodoRaiz = CrearNodo(HttpContext.Current.Server.MapPath(_carpetaRaiz), _

_carpetaRaiz)_nodoRaiz.Title = Inicio

‘Se usa el truco de la caché para detectar cambios en la carpeta raíz_monitor = New CacheDependency(HttpContext.Current.Server.MapPath(_

_carpetaRaiz))

AddNode(_nodoRaiz) ‘Se añade el nodo raíz al mapa

‘y ahora de manera recursiva se añaden el resto de los nodos desde el raízCreaMapaAPartirDe(_nodoRaiz, _carpetaRaiz)

End If

‘En cualquier caso se devuelve el nodo raíz, calculado o en cachéReturn _nodoRaiz

End SyncLock

End Function

Listado 1

Page 31: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

31

Volviendo al listado 1, lo único queresta tras haber generado la jerarquía denodos es devolver el nodo padre comoresultado de llamar a la función.

Destrucción de la cachéDado que nuestro proveedor hace cachédel mapa, si se producen cambios en laestructura de disco una vez que éste hayasido generado, quedaría obsoleto. La úni-ca forma de volver a refrescarlo sería lla-mando por código al método Resetearque hemos definido. Esto podría ser unabuena solución, pues bastaría con colo-car un botón en alguna página de admi-nistración y pulsarlo cuando fuera nece-sario (las actualizaciones no serían fre-cuentes seguramente). De todos modos,he decidido mejorar el proveedor paraque detecte al menos los cambios que seproduzcan en la carpeta raíz de nuestrajerarquía. Para ello he aprovechado la cla-se CacheDependency de ASP.NET que esla que usa el sistema de caché para deter-minar cuándo debe hacer expirar los ele-mentos que dependen de algún archivo.El constructor de esta clase permite indi-car un archivo o carpeta a monitorizar yel momento en que queremos empezar acontrolarlo (si no lo indicamos, empiezainmediatamente). Posteriormente se pue-de comprobar su propiedad HasChanged,que devolverá true en caso de que hayacambiado algo. De hecho, también sepuede capturar un evento en el precisoinstante en que se produzca el cambiopara destruir la caché, pero en nuestrocaso sólo necesitamos saber si ha cam-biado cuando se nos solicite el mapa denuevo, no en tiempo real.

El único problema de este sistemaelegido es que sólo detectará cambiosen la carpeta raíz, pero en la mayor par-te de los casos será suficiente. Podría-mos construir un notificador más poten-te que controlase las subcarpetas usan-do la clase FileSystemMonitor, pero esose sale por completo del ámbito de nues-tro artículo.

Protected Function CrearNodo(rutaFisica As String, rutaVirtual As String) _As SiteMapNode

Dim url As String

‘Vemos si es una carpeta o un archivoIf Not rutaFisica.ToLower().EndsWith(“.aspx”) Then ‘Es una carpeta

‘Hacemos caso omiso de las carpetas de ASP.NETIf Path.GetFileName(rutaFisica).StartsWith(“App_”, _

StringComparison.InvariantCultureIgnoreCase) OrElse _String.Compare(Path.GetFileName(rutaFisica).ToLower(), “bin”) = 0 ThenReturn Nothing

Else‘Si es una carpeta le agregamos un enlace a la página por defectourl = String.Concat(rutaVirtual, “/”, “default.aspx”)

End IfElse ‘Es un archivo‘No metemos enlaces directos a páginas por defecto ‘(ya están los nodos de carpetas)If rutaFisica.ToLower().EndsWith(“default.aspx”) Then Return Nothingurl = String.Concat(rutaVirtual, “/”, Path.GetFileName(rutaFisica))

End If

Dim nodo As New SiteMapNode(Me, rutaFisica, url,_Path.GetFileNameWithoutExtension(rutaFisica))

Return nodo

End Function

Protected Sub CreaMapaAPartirDe(ByVal padre As SiteMapNode, ByVal rutaVirtual _As String)

‘Determinar la ruta física para la ruta Virtual actual (siempre son carpetas)Dim rutaFisicaCarpeta As String = HttpContext.Current.Server.MapPath(rutaVirtual)

Dim infoCarpeta As New DirectoryInfo(rutaFisicaCarpeta)

‘Se añadirá un nodo por cada archivo ASPX incluído en la carpeta. ‘El método de crear nodos ya tiene en cuenta los archivos a excluir, etc..For Each fi As FileInfo In infoCarpeta.GetFiles(“*.aspx”)

Dim nodo As SiteMapNode = CrearNodo(fi.FullName, rutaVirtual)If nodo IsNot Nothing Then AddNode(nodo, padre)

Next

‘Ahora se crea un nodo para cada subcarpeta, la cual será recorrida recursivamenteFor Each di As DirectoryInfo In infoCarpeta.GetDirectories()

Dim nodo As SiteMapNode = _CrearNodo(di.FullName, String.Concat(rutaVirtual, di.Name, “/”))

‘Se añade el nodo de la carpeta y se recorre para añadir sus hijosIf nodo IsNot Nothing Then

AddNode(nodo, padre)CreaMapaAPartirDe(nodo, String.Concat(rutaVirtual, di.Name, “/”))

End IfNext

End Sub

Listado 2

Listado 3

Page 32: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dnm.plataforma.net<<

dotN

etM

anía

<<

32

A estas alturas, algún lector avispa-do se estará preguntando por qué nohemos usado directamente el objetoCache de ASP.NET para almacenar elmapa que generamos, en lugar de guar-darlo en una variable privada. Ensegui-da veremos el motivo.

Otro detalle másSi a estas alturas aún sigue con nosotros,recordará que dije que era necesario otrométodo más para este tipo de provee-dor. Este otro método abstracto quedebemos implementar para acabar dedefinir nuestro flamante proveedor sellama GetRootNodeCore. Se encuentradefinido en la clase SiteMapProvider, dela que hereda StaticSiteMapProvider,como se observa en la figura 4. Éste esllamado automáticamente por los con-troles apropiados de ASP.NET cuandose necesita obtener una referencia alnodo raíz del mapa actual. Es funcio-nalmente idéntico al método anterior,por lo que su código es bien fácil, ya quesólo hay que llamar al método BuildSi-teMap:

Protected Overrides Function _GetRootNodeCore() As _

System.Web.SiteMapNodeReturn BuildSiteMap()

End Function

Consideraciones sobreseguridad para múltiples subprocesosAntes de continuar con los últimos deta-lles de nuestro proveedor para a conti-nuación poder probarlo, es necesariohacer unos comentarios muy importan-tes sobre el modo en que trabajan éstos.

En el listado 1 se observa que elcódigo está contenido dentro de unasentencia SyncLock. El motivo es quees necesario controlar el accesosimultáneo de varios hilos a las varia-bles privadas de nuestro proveedor. En

ASP.NET, generalmente todas las cla-ses como módulos o clases que repre-sentan páginas se instancian indivi-dualmente por cada petición recibida(por cada hilo de ejecución). De estemodo, cada petición tiene sus propiasclases, y no es necesario tener en cuen-ta que puedan ser accedidas por varioshilos al mismo tiempo. Los proveedo-res son una excepción a esta norma, yaque una misma instancia de un prove-edor es compartida por todos los hilosde ejecución de la misma aplicación.Por este motivo, es muy probable quehaya varios subprocesos accediendosimultáneamente a las mismas varia-bles privadas de nuestro proveedor, yes necesario por lo tanto regular elacceso a éstas estableciendo bloqueosde sincronización con SyncLock.

Si no hubiésemos tenido en cuentaeste detalle, seguramente nuestro pro-veedor funcionaría perfectamente en losentornos de pruebas y durante el desa-rrollo. Al ponerlo en producción y tenermuchos accesos es cuando empezaríanlos problemas y probablemente nos cos-taría mucho averiguar qué está pasan-do. Así que no debemos olvidar quetodos los métodos y propiedades de unproveedor deben estar preparados paratrabajar bajo múltiples subprocesos.

Para ilustrar este concepto es por loque hemos implementado la caché en unavariable privada de la clase. Su valor semantiene además entre las diferentes peti-ciones de un mismo o de diferentes usua-rios, por lo que tenemos una forma fácily eficiente de almacenar nuestros datoscomunes sin recurrir al objeto Cache. Haymultitud de formas de sincronizar el acce-so multi-hilo, pero el uso de SyncLock esel más sencillo para nuestro propósito.

InicializaciónCon lo visto hasta ahora tenemos casitodo lo necesario para dar por termi-nado nuestro proveedor. Nos faltatodavía una cuestión: la inicializacióndel mismo.

Para poner en funcionamiento unproveedor, debemos agregarlo al archivode configuración de nuestra aplicación.En éste se especifica la clase que define elproveedor y es posible indicar los pará-metros que sean necesarios para perso-nalizar su funcionamiento. En nuestroejemplo podremos indicar cuál es la car-peta raíz que usaremos para generar elmapa (por defecto “~/”) y también elnombre que queremos darle al nodo raíz(“Inicio” de forma predeterminada). Estosparámetros se especifican en Web.config,como veremos enseguida.

Cuando ASP.NET necesita usar elproveedor por primera vez llama a sumétodo Initialize, pasándole comoparámetros el nombre del proveedor yuna colección de parejas nombre/valorcon los atributos especificados en la con-figuración. De este modo, resulta muyfácil asignar configuraciones específicascomo se ilustra en el listado 4.

Lo único que hacemos es verificarsi se ha especificado o no el parámetro,y en tal caso lo asignamos usando la pro-piedad correspondiente que habremosdefinido en nuestra clase. Nótese quelos nombres de los parámetros distin-guen entre mayúsculas y minúsculas. Alfin y al cabo se trata de XML, y este tipode cosas importan.

Otra observación importante quedebo hacer es que este método de inicia-lización solo se llama una vez en el tiem-po de duración del dominio de aplicaciónde nuestro programa. Por lo tanto, este esel único método del proveedor que no esnecesario que sea seguro para múltiplessubprocesos.

También debemos asegurarnos de quellamamos al método de inicialización dela clase base, la cual también debe hacersus ajustes. Y si debemos lanzar algunaexcepción (algún parámetro erróneo oausente), lo mejor es siempre que trate-mos de usar excepciones específicas delespacio de nombres System.Configura-tion.Provider, o heredadas de éstas.Como en toda gestión de excepciones,cuanto más específico seamos, mejor.

Page 33: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

33

¡Vamos a probarlo!

Por fin tenemos nues-tro proveedor com-pletamente definido.Ahora es el momentode probarlo. Para ellodebemos definirlo en Web.config, en concreto dentro dela sección específica para pro-veedores de mapas de sitios(listado 5).

En este ejemplo hemos aña-dido dos instancias de nuestroproveedor. Una de ellas (Prove-edor_Sistema_Archivos) dejalos valores por defectopara los parámetrosde funcionamiento y

se convierte en el nuevo proveedor pordefecto. La otra (“Admon”) está para-metrizada para generar un mapa sólocon los contenidos de la carpeta Admi-nistración de nuestro proyecto y parausar la frase “Home sweet home” paramostrar el nodo raíz.

Una vez hecho esto, para probarlosvamos a agregar en una página dos con-troles de tipo SiteMapDataSource. Unode ellos lo dejaremos tal cual se ha arras-trado y en el otro ajustaremos su pro-piedad SiteMapProvider con el valor“Admon”, para que use el segundo pro-veedor que hemos definido. Añadire-mos un control TreeView enlazado al pri-mero y un control Menu al segundo, dán-doles un aspecto bonito con las planti-llas que incluyen.

Si ahora ejecutamos la aplicaciónveremos como no hay problema algunopara utilizar ambas instancias del prove-edor al mismo tiempo, e incluso podría-mos utilizar también alguna del provee-dor XmlSiteMapProvider que viene conASP.NET 2.0.

ConclusiónEn este artículo hemos estudiado elmodelo de proveedores de ASP.NET2.0 y todas las ventajas que nos ofrece.Hemos visto los distintos subsistemasque están basados en proveedores, consus correspondientes clases nativas.Finalmente, hemos desarrollado unejemplo completo de un proveedor paramapas de sitios que trabaja generandodirectamente enlaces para los archivosdel disco duro, evitándonos el tener quedefinir engorrosos archivos XML denavegación. Con todo esto, hemos sen-tado la base suficiente para poder crearcualquier proveedor propio o modificaralguno de los existentes heredando delas clases definidas en el sistema. Asípodremos personalizar fácilmente elcomportamiento de las API más impor-tantes de ASP.NET 2.0.

Public Overrides Sub Initialize(ByVal name As String, _

ByVal attributes As System.Collections.Specialized.NameValueCollection)

MyBase.Initialize(name, attributes)

‘Ver si se ha especificado la ruta raíz

If Not String.IsNullOrEmpty(attributes(“carpetaRaiz”)) Then

CarpetaRaiz = attributes(“carpetaRaiz”)

End If

‘y el nombre del nodo raíz

If Not String.IsNullOrEmpty(attributes(“Inicio”)) Then

Inicio = attributes(“Inicio”)

End If

End Sub

Listado 4

<system.web>

<siteMap enabled=”true” defaultProvider=”Proveedor_Sistema_Archivos”>

<providers>

<add name=”Proveedor_Sistema_Archivos” type=”FSSitemapProvider”/>

<add name=”Admon” type=”FSSitemapProvider” Inicio=”Home sweet home”

carpetaRaiz=”~/Administración”/>

</providers>

</siteMap>

</system.web>

Listado 5

dnm.plataforma.net<<

Page 34: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Introducción

Siempre que imparto ponencias sobre WindowsWorkflow Foundation intento explicar cuál es la fina-lidad que se trató de conseguir con este nuevo frame-work de desarrollo de procesos de negocio, y casi siem-pre suelo recurrir a un maravilloso ejemplo que utili-za Dharma Shukla en su libro “Essential WindowsWorkflow Foundation”, en el que trata de explicar losproblemas que existen actualmente a la hora de crearcon las diferentes tecnologías existentes nuestros pro-cesos. El problema consiste básicamente en que losentresijos de las tecnologías y la aplicación de las capa-cidades de las mismas provocan que nuestro códigooscurezca el propósito que intenta llevar a cabo. ¿Cuán-tas veces hemos intentado descifrar código de terce-ros en busca de su finalidad, apartando de nuestra lec-tura decoradores propios de la tecnología o elemen-tos que poco tienen que ver con el flujo de nuestraoperación de negocio?

Gracias a Windows Workflow Foundation, pre-cisamente lograremos centrarnos en nuestro proce-so de negocio, consiguiendo una vista clara del mis-mo. Incluso podríamos proporcionar esta vista a ana-listas que poco tienen que ver con el código y faci-litar que ellos mismos utilizaran los diseñadores deflujos de trabajo; pero para ello indudablementedebemos proporcionar mecanismos como las reglaso artefactos que guían los procesos, del mismo modoque otras herramientas anteriores a WF contienenreglas para guiar los procesos de negocio escritosusando distintos lenguajes, como BPEL o XPDL.

El motor de reglas de WF

Antes que nada, deberíamos empezar explicando quées una regla dentro de la terminología de WF. Real-mente una regla es cualquier expresión del tipo:

IF <condición> THEN <acción1> ELSE <acción2>

En donde <condición> es una expresión quedevolverá cierto o falso, y las expresiones después delos bloques THEN o ELSE serán las acciones que dese-emos que se ejecuten en función del cumplimientoo no de nuestra condición. Hablando de procesosde negocio, estas reglas tendrán distintos propósi-tos y para cada uno de ellos dispondremos de acti-vidades para evaluarlas y realizar las acciones nece-sarias. Las actividades de base de las que dispone-mos en WF y que están ligadas al motor de reglasse presentan en la tabla 1.

De las cinco actividades de la tabla 1, las cua-tro primeras están ligadas con la modificación delflujo de trabajo, algo esencial dentro de los proce-sos de negocio, y en todas podemos establecer laregla que permite modificar los flujos en funciónde un objeto de tipo ActivityCondition. En WFtenemos dos tipos que implementan la clase baseabstracta ActivityCondition; éstas son CodeCondition,la cual nos permitirá basar la evaluación de la con-dición en la ejecución de un determinado código,y DeclarativeRuleCondition, que nos permitirá expre-sar de forma declarativa la condición que deseamosevaluar.

El motor de reglas de Windows Workflow Foundation

plataforma.net

Unai Zorrilla trabajacomo Development

Advisor en PlainConcepts. Es MVP deMicrosoft y colabora

activamente conMSDN en eventos

de formación, talleresde Arquitectura ygiras de producto.

Cuando hablamos de procesos de negocio, indudablemente en algúnmomento tendremos que hablar de los mecanismos y reglas que pue-dan variar el comportamiento de los mismos y/o el flujo de nuestrosprocesos.

Unai Zorrilla

Page 35: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

A continuación veremos con un sencillo ejem-plo cómo expresar una regla dentro de la actividadIfElseActivity, que en definitiva será exactamente igualque en cualquiera de las otras actividades de modifica-ción de flujo. El ejemplo consistirá en agregar a un nue-vo workflow secuencial una actividad IfElseActivity quecontendrá en cada una de sus ramas una actividad decódigo, como se muestra en la figura 1.

La actividad IfElseActivity una vez introducidassus actividades hijas nos mostrará en la primera ramaun error de validación (marcado con un círculo rojo),puesto que aún no hemos introducido ninguna condi-ción que permita al motor de WF decidir si la ejecu-ción se encamina por una rama u otra. Para estableceresta condición dentro de la actividad, indicaremos enlas propiedades de la misma (figura 2) la condición quedeseemos que se valide. Tal y como habíamos comen-tado anteriormente, esta condición se puede expresar

mediante una condición en código, CodeCondition, obien mediante una condición declarativa, Declarative-RuleCondition. La diferencia entre ambas formas con-siste en que mediante CodeCondition la evaluación de laregla se hará usando un manejador con una firma espe-cial, mientras que mediante DeclarativeRuleConditionla regla se escribirá usando expresiones de CodeDOMy se almacenará en un archivo con extensión .rules con-tenido dentro del ensamblado. Veremos ambas formasde implementar nuestra regla, pero antes que nada aña-diremos la siguiente propiedad a nuestra instancia deworkflow que usaremos dentro de las reglas:

dotN

etM

anía

<<

35

dnm.plataforma.net<<

Nombre de Actividad Propósito

IfElseActivity Bifurcar la ejecución a un camino u otro.

WhileActivity Permite repetir la ejecución en función de un regla.

ReplicatorActivity Permite replicar la ejecución de una actividad en función deuna regla y un contexto inicial.

ConditionedActivityGroupActivity Similar a WhileActivity, pero con condiciones adicionales encada una de las actividades hijas.

PolicyActivity Ejecución de un conjunto de reglas para validar o modificar elestado de nuestra instancia de flujo de proceso.

Tabla 1. Actividades de base de WF

Figura 1. Modelo de nuestro proceso con IFElseActivity

Figura 2. Propiedades de IfElseActivity

private int mNumber = default(Int32);public int Number{

get{

return mNumber;}set{

mNumber = value;}

}

Page 36: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

36

dnm.plataforma.net<<

Para expresar una regla medianteCodeCondition lo único que deberemoshacer es crear el método a usar paravalidar la regla, que debe tener el mis-mo prototipo que el delegado Event-Handler<ConditionalEventArgs>. Unejemplo de ello es método que se pre-senta en el siguiente listado, en el quese comprueba si el valor de la propie-dad agregada anteriormente es par oimpar:

Ahora solamente tenemos que indi-car dentro de las propiedades de la ramainicial de la actividad IfElseActivity quela regla será de tipo CodeCondition y queel manejador es EvaluarRegla, como sepuede ver en la figura 3.

Si iniciamos nuestra instancia deworkflow con un valor adecuado de la pro-piedad Number, veremos cómo efectiva-mente podemos bifurcar el camino deejecución para el proceso de negociomodelado anteriormente. Para iniciali-zar el valor de Number utilizaremos lasobrecarga del método CreateInstance()de la clase WorkflowRuntime en el quepodemos pasar como segundo paráme-tro un diccionario con los valores quedeseemos que contengan algunas pro-piedades de nuestro workflow, tal y como

vemos en el fragmento de código que sepresenta en el siguiente listado:

La segunda de las formas de las quedisponemos para expresar nuestrasreglas de negocio es mediante reglasde tipo DeclarativeRuleCondition. Eneste caso, como hemos dicho antes,debemos basarnos en una expresión deCodeDOM que podemos crear direc-tamente desde el entorno de desarro-llo seleccionando en las propiedades dela primera rama de la actividad IfEl-seActivity la opción de “Declarative

Rule Condition” y des-plegando la opción “Con-dition Name”, como sepuede ver en las figuras 4y 5. Si seleccionamos laopción de crear una nue-va regla (figura 6), ten-dremos a nuestra disposi-ción un editor en el quepoder escribir la regla quedeberá evaluarse; este edi-tor nos proporciona inclu-so validación y ayudaIntellisense a la hora deescribir la regla.

Una vez creada nuestraregla con la misma condi-ción que para el ejemploanterior, veremos cómodentro del Explorador desoluciones disponemos deun nuevo archivo conextensión .rules que con-tendrá una expresión enCodeDOM equivalente ala condición escrita encódigo (figura 7).

private voidEvaluarRegla(object sender,

ConditionalEventArgs e){if ((mNumber & 1) != 0)

e.Result = true;else

e.Result = false;}

Dictionary<string, object>inputValues = new

Dictionary<string, object>();inputValues.Add(“Number”, 1);WorkflowInstance instance =workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1), inputValues);

instance.Start();

Figura 3. Estableciendo el manejadorEvaluarRegla

Figura 4. Estableciendo ‘Declarative Rule Condition’

Figura 5. Desplegando el editor de reglas

Figura 6. Creando una nueva regla

Figura 7. Nuevo archivo de reglas incorporado al proyecto

Page 37: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

37

dnm.plataforma.net<<

Reglas basadas en políticas

El uso de las reglas dentro de los pro-cesos de negocio no solamente tienecomo objetivo la modificación de losflujos de ejecución. En muchas ocasio-nes, estas reglas tienen que ver con lamodificación de los estados inherentesal proceso de negocio, es decir, sonreglas que nos permitan resolver casuís-ticas como la siguiente: “Si llegamos aeste punto y hemos obtenido un ‘ValorA’ superior a la cantidad ‘X’ y un ‘ValorB’ menor que la cantidad ‘Y’, debemosde establecer el ‘Valor C’ a el doble del‘Valor A”. La última de las actividadesque hemos presentado en la tabla 1,PolicyActivity, es la encargada de faci-litarnos la realización e implementaciónde las reglas que nos permitan resolverlos problemas similares al anterior. Real-mente PolicyActivity nos permite alma-cenar un conjunto de reglas, que a par-tir de ahora llamaremos RuleSet, y vali-dar y ejecutar dichas reglas en elmomento en el que el flujo de trabajoejecute esta actividad. Este RuleSet seestablece en la propiedad RuleSetRefe-rence de nuestra actividad Policy, comopodemos ver en la figura 8.

Para establecer este RuleSet dispo-nemos de una herramienta llamadaRuleSetDialog, en la cual podemos cre-ar nuestro conjunto de reglas y estable-cer las condiciones de dependenciasentre ellas (figuras 9 y 10).

En el editor de reglas debemos escri-bir todos aquellos conjuntos de reglasque deseemos que se ejecuten en un

momento dado dentro de nuestro flujode proceso. Sin embargo, aunque estoparece sencillo deberemos de tener cui-dado con posibles dependencias de unasreglas con otras. A continuación creare-mos dos reglas sencillas dentro de unnuevo RuleSet y veremos qué problemasse pueden derivar de ellas.

Inicialmente creamos un nuevoworkflow secuencial en el que incluimostres propiedades llamadas Edad, Mayor-DeEdad y PuedeConducir como las que sepresentan en el listado 1.

A continuación, incorporamos dentrodel flujo una actividad PolicyActivity yuna actividad de código que mostrará elvalor de las propiedades anteriores porpantalla. En la figura 11 puede ver unaimagen de nuestro flujo de trabajo.

Finalmente, creamos un nuevo Rule-Set que contenga las siguientes reglas:

Regla 1

IF this.mMayorDeEdad

THEN this.mPuedeConducir=true

ELSE this.mPuedeConducir=false;

Regla 2

IF this.mEdad >= 18

THEN this.mMayorDeEdad=true

ELSE this.mMayorDeEdad=false;

private int mEdad;

public int Edad{

get { return mEdad; }set { mEdad = value; }

}

private bool mMayorDeEdad;

public bool MayorDeEdad{

get { return mMayorDeEdad; }set { mMayorDeEdad = value; }

}

private bool mPuedeConducir;

public bool PuedeConducir{

get { return mPuedeConducir; }set { mPuedeConducir = value; }

}

Figura 9. Herramienta RuleSetDialog

Figura 10. Creando un conjunto de reglas con RuleSetDialog

Figura 11. Imagen del flujo de trabajo

Figura 8. Estableciendo el RuleSet parauna actividad Policy

Listado 1

Page 38: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

38

dnm.plataforma.net<<

A simple vista todo parece muysencillo; sin embargo, algún lectoravispado se habrá dado cuenta de quelas reglas contienen una dependenciaentre sí: la Regla 1 lee un valor, mMa-yorDeEdad, que se establece en la Regla2. Por lo tanto, el comportamientouna vez finalizada la ejecución de lasreglas podría no ser correcto. Estasdependencias entre las reglas escritaspara Windows Workflow Foundationson bastante comunes, por eso desdeel equipo de WF trataron de facilitarla vida de los programadores imple-mentando distintos mecanismos pararesolver las dependencias de las mis-mas, en concreto implementando tresmecanismos de resolución de depen-dencias:

• Resolución de dependencias de for-ma implícita: en este caso, WF es elresponsable de verificar las depen-dencias entre las reglas y de revaluaruna regla si lo considera necesario.

• Resolución de dependencias median-te atributos: en WF disponemos detres atributos, RuleRead, RuleWrite yRuleInvoke, que podremos usar paramarcar que una propiedad de unaregla se va leer o escribir. Más ade-lante veremos un ejemplo de esto.

• Resolución de dependencias de for-ma explícita: en este caso, el progra-mador de la regla deberá hacer uso deuna palabra reservada para indicar queuna determinada propiedad se estáactualizando.

Si volvemos a ver la figura 9,observaremos cómo disponemos de undesplegable denominado “Chaining”(encadenamiento), que podremos esta-blecer en las opciones “Full Chai-ning”, “Sequential” y “Explicit Upda-te Only”. La opción “Full Chaining”realiza todos los mecanismos de reso-lución de dependencias explicadosanteriormente; es por esto por lo quesi ejecutáramos nuestro flujo de tra-bajo obtendríamos un resultadocorrecto a pesar de la dependencia dela Regla 1 con la Regla 2. En el casoen el que la modificación de un deter-minado parámetro, por ejemplo, el de

mMayorDeEdad en nuestra Regla 2, serealice como resultado de un método,el motor de reglas no sería capaz deresolver la dependencia de formaimplícita, pero aún así disponemos delmecanismo de atributos. Un ejemplode ello podría ser:

Regla 2

IF this.mEdad >= 18

THEN SetMayorDeEdad(true)

ELSE SetMayorDeEdad(false);

En donde SetMayorDeEdad sería unmétodo como que se muestra en elsiguiente listado:

Observe que se ha decorado el méto-do SetMayorDeEdad con el atributo RuleW-rite, al cual le pasamos un parámetro indi-cando la ruta de la propiedad. De igualforma, si nuestro método leyera un valorque otra regla pudiera modificar podría-mos aplicar el atributo RuleRead y facili-tarle así al motor de reglas la resoluciónde dependencias. Para terminar con losatributos tenemos RuleInvoke, que se usarácomo decorador de un método que rea-liza una llamada a otro método en el quese leerá o escribirá una determinada pro-piedad usada en las reglas.

Le invito a probar en este momen-to el resultado de ejecutar el flujo de tra-bajo sin hacer uso del decorador RuleW-rite del método SetMayorDeEdad. ¿Cuáles el resultado?

Si establecemos la opción “ExplicitUpdate Only”, solamente dispondre-mos del uso de dos palabras reservadas,Update y Halt. En el caso de nuestraRegla 2 y esta opción de encadena-miento, la regla debería escribirse de lasiguiente forma:

IF this.mEdad >= 18

THEN

this.mMayorDeEdad=true;

Update(“this/mMayorDeEdad”);

ELSE

this.mMayorDeEdad=false;

Update(“this/mMayorDeEdad”);

Para terminar con los mecanismosde encadenamiento disponibles en WF,tenemos la opción “Sequential”, en laque no se realiza ninguna resolución dedependencias por parte del motor deejecución. Podría parecer que estaopción no tiene mucha importancia; dehecho, muchos pensarán que por quéno tenemos solamente la opción de“Full Chaining” con el fin de ahorrar-nos posibles problemas. La respuesta esporque la resolución de dependencias yla revaluación de las reglas tienen uncoste adicional que no siempre se deseatener; incluso es posible que la reeva-luación de las reglas nos introduzca enun bucle infinito.

Le invito a revisar los enlaces [1] y[2] para obtener más información sobreel motor de reglas de Windows Work-flow Foundation y los mecanismos deextensibilidad de las mismas.

ConclusionesEn este artículo hemos presentado unaintroducción al motor de reglas deWindows Workflow Foundation, enel que además se ha visto cómo utili-zar las actividades relacionadas con lasmismas, haciendo especial hincapié enla actividad PolicyActivity y en losmecanismos de resolución de depen-dencias de las reglas de un determi-nado RuleSet.

[RuleWrite(“this/mMayorDeEdad”)]

private void SetMayorDeEdad(bool flag)

{

this.mMayorDeEdad = flag;

}

Referenciashttp://geeks.ms/blogs/unai/archi-ve/2006/12/29/las-reglas-en-workflow-foundation.aspx

http://geeks.ms/blogs/unai/archi-ve/2007/01/03/el-motor-de-reglas-de-workflow-foundation-ii.aspx

[1]

[2]

Page 39: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 40: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

La palabra “metodología” es quizás la que más vecesse usa en el mundo informático sin que esto tenga unreflejo claro en el día a día. Al igual que otras profe-siones tienen bien determinado el protocolo de accio-nes a realizar en cada fase concreta de su actividad, lainformática en general aún sigue estando verde en estesentido y depende mucho de la capacidad de sus pro-fesionales. Si eso lo aplicamos a los proyectos y tareasrelacionados con las infraestructuras y los sistemasinformáticos, suele encontrarse un vacío mayor, dadoque muchas de las metodologías están enfocadas aldesarrollo de software en gran medida.

Estructura de las metodologías de Microsoft

Microsoft ha desarrollado a lo largo de los años unconjunto de best practices, conocimientos y métodos apli-cados tanto en la creación de sus productos como enlos servicios de consultoría que ofrece a sus clientes.De alguna forma, estas metodologías recogen formasde trabajar desarrolladas por el sector durante años,tamizadas con la experiencia acumulada por Microsoften la gestión de proyectos y sistemas informáticos. Elresultado final es más una filosofía de trabajo que unguión estricto de tareas a realizar, para que cada empre-sa y profesional lo adapte a su realidad cotidiana.

Estos conocimientos se desglosan en dos metodo-logías diferenciadas pero relacionadas entre sí. Por unlado tenemos Microsoft Solutions Framework —MSF en adelante—, destinado a la gestión y desarro-

llo de proyectos, sobre el que tratarán este artículo y elsiguiente. Y por otro lado, tenemos Microsoft Ope-rations Framework —MOF—, que detalla las fasesy procesos vinculados a la administración y evoluciónde sistemas en funcionamiento, al que se dedicará eltercer y último artículo de la serie.

Estas dos metodologías están enlazadas entre sí —como puede verse en la figura 1—, de forma que elpaso final de despliegue de una solución desarrolladacon MSF encaja con la entrada en operación de nue-vos productos previsto en MOF. Ambas metodologíasson totalmente atecnológicas, de forma que son apli-cables en proyectos o entornos mixtos o con herra-mientas no Microsoft. Este artículo está basado en losfundamentos de MSF expuestos en su versión 3.0, aun-que desde hace unos meses han aparecido las varian-tes de la versión 4.0 conocidas como MSF for AgileDevelopment y MSF for CMMI Development,incluidas en el entorno Team Foundation Server; perocreo interesante conocer primero estas bases comunesantes de entrar en la especialización que añaden cadauna de las nuevas variantes.

Componentes de MSF

Al contrario que otras metodologías mucho más estric-tas, que ofrecen un marco cerrado de acciones a reali-zar, MSF se basa en un enfoque más orientado a unasguías generales y unas herramientas de ayuda que pue-den ser complementadas con otras existentes en el mer-cado. La parte fundamental de este framework son losllamados modelos, que describen el entorno general

Microsoft Solutions Framework (1)Aplicar la metodología en el trabajo diario según Microsoft

metodologías

Joan Llopart es Pro-ject Manager y arqui-tecto de Raona. Joan

es MCSE, MCDBA,MCT, ITPro y MSF

Certified.

En esta serie de tres artículos se quiere dar una visión global sobre las herra-mientas que en este campo nos ofrece Microsoft y que suelen ser descono-cidas incluso para los propios interesados. El objetivo no es tanto dar un com-pleto repaso a estas metodologías como conocer las bases y elementos másinteresantes para su aplicación en el trabajo diario.

Joan LLopart

Page 41: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

del proyecto y los pasos necesarios parasu correcta realización y finalización. Adi-cionalmente, existen las disciplinas, méto-dos de gestión de elementos concretosque influyen en la calidad del proyecto.

MSF 3.0 consta de 2 modelos, cono-cidos como Team Model y ProcessModel, que aportan dos visiones distin-tas y complementarias que permitensituar la totalidad del proyecto en suentorno, y que serán descritos en estosartículos. Además, tiene 3 disciplinas: RiskManagement, orientada a la gestión deriesgos y quizá la más interesante por susencillez y utilidad; Readiness Manage-ment, que ayuda a planificar los conoci-mientos necesarios para los integrantesdel equipo; y Project Management, unaguía para la gestión de proyectos com-plejos enfocada a la distribución de res-ponsabilidades. De estas tres disciplinas,sólo se describirá la primera, dejando lasotras para una posterior consulta.

Team Model, el quién es quiéndel proyectoA diferencia de otras metodologías, MSFparte del planteamiento de que los miem-bros de un equipo de proyecto forman unpair team: un conjunto de personas queasumen solidariamente unas responsabi-lidades concretas que se encargarán decumplir, independientemente de su posi-ción, su empresa o su cargo. Así, estemodelo integra a personas que tienen uncometido claro en las distintas fases delproyecto y que son responsables que secumplan correctamente. De esta forma,la carga del proyecto se distribuye entre

los miembros del equipo, siendo el ges-tor del proyecto uno más del grupo y noel responsable final de todas las tareas. Eneste sentido, es imprescindible disponerde canales de comunicación ágiles entretodos los involucrados para que esta flu-ya fácilmente y sin necesidad de inter-mediarios.

El Team Model distingue a seis rolesdiferenciados que deben ser asumidossiempre por una persona o grupo. Así, segarantiza que todas las necesidades delresultado final serán atendidas y asigna-das a alguien. El detalle de los roles defi-nidos se puede observar en la figura 2, jun-to a las responsabilidades básicas de cadauno de ellos. Especial relieve tienen tresde estos roles en el enfoque del resultadofinal: el Program Management, encar-gado de cuándo y quién va a realizar lastareas necesarias; el Product Manage-ment, enfocado en qué necesidades debecubrir el proyecto; y el Development,responsable de cómo se implementaránlos requerimientos establecidos. Este últi-

mo rol incluye no sólo a los programado-res —en caso de haberlos—, sino tambiéna arquitectos, responsables de infraes-tructuras, comunicaciones y seguridad.

Los seis roles establecidos pueden serasumidos por una o varias personas cadauno, repartiéndose entre ellos las distin-tas responsabilidades funcionales de cadarol. De la misma forma, una persona pue-de tener varios roles en el proyecto, aun-que se recomienda mantener diferencia-dos algunos de ellos. Así, el Developmentdebe ser independiente del resto para noatenuar los requerimientos funcionales yde calidad por la complejidad habitual dela implementación. También es reco-mendable no depositar en la misma per-sona el rol de Program Manager y Pro-duct Manager, puesto que deben man-tenerse separadas las inquietudes sobre elresultado final y los plazos que se esta-blecen para conseguirlo.

Este modelo también contempla larelación que deben tener durante la vidadel proyecto los distintos miembros del

equipo con los agentesexternos que puedeninfluir en la aceptacióndel resultado final. Des-taca especialmente elsponsor del proyecto,impulsor y responsableúltimo del mismo y anteel que se deben rendircuentas. También jueganun papel de peso los usua-rios finales de la solucióny los responsables deotras áreas que esperanbeneficiarse de su resul-tado. Y cómo no, los res-

dotN

etM

anía

<<

41

dnm.metodologías<<

Figura 1MSF y MOF son dos metodologías

independientes pero relacionadas entre sÍ

Figura 2. Roles descritos por el Team Model y responsabilidades asociadas a cada uno

Roles y responsabilidades del Team Model

Program Management: gestión de proyecto, arquitectura de la solución, control de proce-sos y servicios administrativos.

Product Management: requerimientos funcionales, valor de negocio, marketing, represen-tación del cliente y plan de producto.

Development: consultoría tecnológica, diseño y arquitectura de la implementación, desa-rrollo de la aplicación y la infraestructura.

Test: planificación de pruebas, ejecución del test e informe de errores.

User Experience: accesibilidad, localización, test de usabilidad, diseño de interfaces, mate-rial de formación y representación de los usuarios finales.

Release Management: infraestructuras, paso a explotación, logística y lanzamiento de producto.

Page 42: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

42

dnm.metodologías<<

ponsables de la explotación final del sis-tema, que deberán responsabilizarse de éla largo plazo y cuyos requerimientosdeben estar presentes en todo el desarro-llo. De esta forma, el Team Model quedaextendido y relacionado con los agentesexternos al proyecto, siendo responsabi-lidad de cada rol atender e implementarlas necesidades de cada uno de ellos, comose puede apreciar en la figura 3.

En la práctica, la principal aportaciónde este modelo es la necesidad implícitade clarificar las responsabilidades del pro-yecto y asimilar que hay que preocupar-se por tener una visión global de las nece-sidades asociadas. Más allá del peso especí-fico que suele tener el Development entodo proyecto, es imprescindible cubrirtodos los roles para garantizar el éxito yevitar sorpresas al finalizar. Y esto inde-pendientemente de si el proyecto es inter-no en la empresa, si lo realizan externos ohay un equipo mixto. MSF invita a refle-xionar sobre si en los proyectos que hayen marcha se están teniendo en cuentatodas las necesidades y puntos de vista.Realice el ejercicio, y seguro que le ayu-dará a descubrir los muchos cabos que sesuelen dejar sueltos.

Risk Management, controlarlos riesgos es cosa de todosTodo proyecto o tarea que se realiceimplica un riesgo más o menos elevado.Fallos humanos, errores de la tecnología,retrasos inevitables o caídas del hardwa-re. Imprevistos de la más variada natu-raleza que suelen provocar retrasos, des-viaciones y en general, pérdidas econó-micas que nadie desea. Pero la cuestiónes si realmente son imprevistos o es queno se hace todo lo posible por evitarlos.La filosofía que aplica esta disciplina deMSF es incuestionable: si un riesgo es unpeligro potencial que puede perjudicaral proyecto, se debe hacer todo lo posi-ble para minimizarlo y prevenir sus con-secuencias si finalmente sucede. Ese prin-cipio es el que sustenta lo que se conocecomo gestión de riesgos y que Microsoftha incorporado como elemento de sumetodología para contar con una herra-mienta simple y útil para mejorar la cali-dad de la solución.

El primer paso para realizar esta ges-tión de riesgos es que todos los miembrosdel equipo analicen e identifiquen los peli-gros potenciales que existan en el pro-yecto. Se debe determinar la condiciónque debe cumplirse para que se haga rea-lidad y la consecuencia que esto acarrea.Aunque la responsabilidad de centralizarla gestión es del Program Manager, todoslos implicados en el proyecto deben invo-lucrarse en ella. Esto permite generar unalista de riesgos atómicos que no depen-den unos de los otros, de forma que se

producirán de forma aislada y con conse-cuencias propias. En la elaboración de estalista también deben participar las perso-nas que no forman parte del equipo, y ellopuede servir para aflorar temores y preo-cupaciones de los destinatarios del pro-yecto que se pueden prevenir, dandomayor confianza en el éxito del mismo.

El siguiente paso es priorizar los ries-gos, porque nunca hay tiempo ni recur-sos para afrontarlos todos; así que se debenseleccionar los que puedan afectar más alproyecto. A cada riesgo se le asignan dos

valores: la probabilidad en por-centaje de que suceda y elimpacto en costes que tendríaen el proyecto. Su productopermite calcular la exposicióndel proyecto a ese riesgo y orde-nar la lista en función de estevalor. De esta forma, se deter-minan los percances más gra-ves que pueden ocurrir y sepuede empezar a planificarcomo afrontarlos.

La última fase del procesoconsiste en preparar con el equi-po dos planes para cada riesgo:un plan de mitigación con elobjetivo de reducir la probabili-dad de que se convierta en rea-

lidad y un plan de contingencia para mini-mizar el impacto que tendría sobre el pro-yecto. Es importante determinar tambiénun trigger que sirva para evaluar si ese ries-go está convirtiéndose en realidad y un res-ponsable que tenga asignada la prevenciónde ese ítem, evitando que la gestión quedesólo en un papel. Del éxito de este procesodepende que se minimice el riesgo de des-viación o incluso de fracaso del proyecto.

La gestión de riesgos es un procesovivo que debe realizarse durante todo elproyecto y que evoluciona a medida que

éste avanza. Involucrar en él a todo el equi-po y a las personas que influyen en el resul-tado final es clave para incrementar lasposibilidades de éxito y mejorar la satis-facción. Y llevarlo a la práctica es tan sim-ple como rellenar y mantener viva unatabla como la que se muestra en la figura4. Aplicar el sencillo modelo que propo-ne MSF no debe suponer un gran esfuer-zo, pero sí implica el compromiso de todoel equipo en ser conscientes de los pro-blemas que pueden surgir y ser proacti-vos en evitarlos y resolverlos.

Figura 3Cada rol del proyecto debe gestionar la comunicacióncon las personas externas involucradas en el proyecto

Figura 4Ejemplo de lista de gestión de riesgos a cumplimentar para el proyecto

Page 43: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

43

dnm.inicio.taller<<

Las clases de compresión de .NET Framework 2.0

Un problema importante de las dos clases incluidas en.NET Framework 2.0 para realizar las tareas de com-presión/descompresión de ficheros es que son clasesque utilizan formatos, digamos, obsoletos, y si no obso-letos, al menos no son los formatos “habituales”. Esosdos formatos están basados en estándares, y por tantoserán aceptables en diferentes sistemas operativos. Deuno de esos dos formatos existen extensiones que nospueden resultar conocidas, como es el caso del forma-to GZip, que habitualmente utiliza la extensión .gz.Sin embargo, el algoritmo Deflate, que es el usado porotra de las clases de compresión, no suele tener ningu-na extensión asociada al tipo de fichero que produce.

Pero el problema principal no es que el formatosea ampliamente usado o no, ya que si lo que en rea-lidad nos interesa es proporcionar a nuestras aplica-ciones de un modo de aprovechar el espacio del discoo de crear ficheros que ocupen menos espacio, porejemplo, para usarlos en envíos por Internet, cualquierformato que nos permita reducir el tamaño de “un”fichero será bueno. El principal inconveniente es ése,que las clases definidas en .NET Framework 2.0 estánpensadas para manipular solamente un fichero. Es decir,si queremos comprimir varios ficheros en uno solo,tendremos que buscar otra forma de hacerlo.

Las clases de compresión de .NET Framework 3.0

En la versión 3.0 de .NET Framework, además delas dos clases incluidas en la versión 2.0, tambiénpodemos encontrar el espacio de nombresSystem.IO.Packaging, que define clases —particular-mente la clase ZipPackage— que precisamente estánpensadas para trabajar con varios ficheros en un mis-mo “paquete”, y que utiliza el formato ZIP para rea-lizar la compresión de esos ficheros. En realidad, esasclases de .NET 3.0 están más pensadas para traba-jar con el sistema de “empaquetado” OPC (Open Pac-kaging Conventions), que es el formato “abierto” usa-do por Office 2007.

Independientemente de cuál sea tipo de empa-que tado usado por las clases definidas en System.IO.Packaging, como comprobaremos en este artículo,la forma de usarlas será relativamente fácil; bueno,si no fácil, al menos nos permitirá almacenar másde un fichero en el ZIP, además de poder conser-var una estructura de directorios, que es en reali-dad lo que más nos puede interesar. La ventaja finalde estas clases de .NET Framework 3.0 es que elformato del fichero generado es totalmente están-dar y por tanto lo podremos abrir y manipular concualquier herramienta que trabaje con ese tipo deficheros comprimidos.

Comprimir con .NETEl compresor que lo comprima... puede usar la versión 2.0 o la 3.0

inicio

Guillermo “Guille”Som es Microsoft MVP

de Visual Basic desde1997. Es redactor de

dotNetManía, mentorde Solid Quality Iberoa-mericana, tutor de cam-

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

Imprescindible de VisualBasic .NET” y “Visual

Basic 2005”.http://www.elguille.info

Si queremos comprimir (o descomprimir) ficheros con .NET Framework 2.0 sin usarlibrerías externas, podemos usar las dos clases que se definen en el espacio de nom-bres System.IO.Compression: DeflateStream y GZipStream. Por otra parte, en la ver-sión 3.0 de .NET existen clases que nos permiten crear ficheros del tipo ZIP. En esteartículo veremos cómo usar las clases que las dos versiones de .NET nos ofrecen pararealizar las tareas de compresión.

Guillermo «Guille» Som

Page 44: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

44

dnm.inicio.taller<<

Comprimir/descomprimir con las clasesde .NET Framework 2.0

Como he mencionado antes, el espacio de nombresSystem.IO.Compression define dos clases que podemosusar para realizar tareas de compresión. Esas dos cla-ses son: GZipStream y DeflateStream. La peculiaridadde estas dos clases es que solo trabajan con un ficheroa la vez, y por tanto solo nos servirán para compri-mir/descomprimir un solo fichero. Las especificacio-nes de los algoritmos usados por estas dos clases son elRFC 1951, para el usado en DeflateStream, y el RFC1952, para el usado en GZipStream; como comentario,decir que el formato gráfico PNG utiliza el algoritmoDeflate para realizar la compresión.

Estas dos clases utilizan una “secuencia” (Stream)para hacer las tareas de compresión y descompresión,y las formas de utilizarlas son prácticamente idénti-cas; como veremos, solo tendremos que cambiar elnombre de la clase a usar cuando queramos realizarla compresión con una clase o con la otra.

Como veremos a continuación, la tarea de com-primir es muy simple, algo que se complica un poco ala hora de descomprimir. Veamos cómo realizar estasdos tareas con las clases GZipStream y DeflateStream.

Comprimir el contenido de un fichero

Tanto la clase DeflateStream como GZipStream tra-bajan con objetos del tipo Stream. Ese “flujo” lo usare-mos en el constructor de esas clases, en el que ademásindicaremos si nuestra intención es comprimir o des-comprimir. A la hora de comprimir, el objeto Stream quele pasaremos como primer argumento al constructor dela clase representará al fichero comprimido, y para rea-

lizar la tarea de comprimir simplemente llamaremos almétodo Write con el array de bytes que queremos guar-dar de forma comprimida.

En el listado 1 vemos cómo comprimir el conte-nido de un fichero. En este código, la variable fic-Compri representa al fichero en el que almacenaremosel contenido del array de bytes datos, que previamentehemos obtenido del fichero a comprimir.

Para obtener el array de bytes con los datos a com-primir podemos usar el método ReadAllBytes de la cla-se File:

byte[] datos = File.ReadAllBytes(fic);

Si en lugar de comprimir usando GZipStream que-remos usar la clase DeflateStream, lo único que tene-mos que hacer en el código del listado 1 es sustituiruna clase por otra; el resto del código es exactamen-te el mismo.

Descomprimir un fichero

La tarea de descomprimir es muy parecida a loque acabamos de ver, aunque no tan simple. En prin-cipio no debería ser complicado, ya que lo que debe-mos hacer es usar el constructor de la clase corres-pondiente al formato de compresión, al que le pasa-mos el objeto Stream del flujo que contiene los bytesdel fichero comprimido; después, por medio del méto-do Read asignamos a un array de bytes el contenidodel fichero una vez descomprimido. La complicaciónempieza a la hora de recuperar el contenido del fiche-ro comprimido, ya que el método Read espera que lepasemos un array con el espacio suficiente para asig-nar el contenido del fichero una vez descomprimido,además del número de bytes que debe leer de lasecuencia. El problema es que el objeto Stream que

En este artículo vamos a centrarnos principalmente en lasclases definidas en las dos versiones de .NET que hay actual-mente en el mercado; pero si queremos comprimir fiche-ros usando el formato “estándar” ZIP y no queremos usarlas clases definidas en .NET Framework 3.0, podemos usaruna librería que, entre otros formatos, nos permite traba-jar con ficheros del tipo ZIP. Esa librería es SharpZipLib,que se distribuye con licencia GPL y se puede descargardesde http://www.icsharpcode.net/OpenSource/SharpZi-pLib/Download.aspx. En el ZIP con el código de ejemploque acompaña al artículo he incluido una clase con variosmétodos para trabajar con las clases de SharpZipLib, conidea de que nos resulte más cómoda de usar.

[ ]NOTA

using (FileStream fs = newFileStream( ficCompri,

FileMode.OpenOrCreate,FileAccess.Write))

{using (GZipStream gz = new

GZipStream(fs,CompressionMode.Compress,true))

{gz.Write(datos, 0, datos.Length);gz.Close();fs.Close();

}}

Listado 1Comprimir un array de bytes usando la clase GZipStream

Page 45: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

45

dnm.inicio.taller<<

devuelven las clases de compresión nopermite averiguar la longitud del mis-mo; en realidad tiene una propiedadLength, que es la que nos debería servirpara saber cuántos bytes tendrá el fiche-ro una vez descomprimido, pero al usaresa propiedad se produce una excepcióndel tipo NotSupportedException; por tan-to, antes de leer el contenido descom-primido debemos averiguar cuántosbytes tiene.

En el código de ejemplo utilizo unafunción para averiguar cuántos bytescontiene un Stream. A esa función lepasaremos la variable de la clase de com-presión que usaremos, y devolverá elnúmero de bytes que contiene, que seráel número de bytes una vez descompri-mido el flujo. En el listado 2 podemosver la función que cuenta los bytes delfichero una vez descomprimido (en rea-lidad cuenta los bytes del objeto Streamcreado por la clase a la hora de des-comprimir).

Una vez que tenemos una forma deaveriguar cuántos bytes tendrá el fiche-ro una vez descomprimido, ya podemosver el código que nos permite descom-primir un fichero usando las clasesDeflateStream o GZipStream. Al igual queocurre a la hora de comprimir, el uso deestas dos clases es el mismo, por tanto,

aunque a continuación se muestre el usode una de estas clases, para usar el otroformato de compresión lo único quetendremos que hacer será cambiar elnombre de la clase.

En el listado 3 tenemos el códigopara descomprimir el contenido de unfichero previamente comprimido conla clase GZipStream. Ese código lo escri-biremos en una función que recibecomo parámetro el nombre del fiche-ro comprimido y devuelve un array debytes con el contenido una vez des-comprimido.

Una vez que tenemos un array debytes con los datos ya descomprimi-dos, lo podemos convertir en unacadena:

string contenido = new

UTF8Encoding().GetString(datos);

O usarlos para guardarlo en otrofichero:

Si examinamos el código mostrado enel listado 3, veremos que el trabajo de des-compresión es doble (tenemos que des-comprimir dos veces), ya que al no poder

usarse la propiedad Positionpara “re-posi-cionar” el puntero que indica la posiciónen la que se empezará a leer el contenidodel Stream devuelto por el constructor dela clase GZipStream, tenemos que cerrar-lo y después volver a abrirlo; pero paravolver a abrirlo debemos crear nueva-mente el objeto, lo que implica que debe-mos volver a descomprimirlo. Esto no esperfecto, pero al menos nos permite una

using (FileStream fs = new

FileStream(fic, FileMode.OpenOrCreate,

FileAccess.Write))

{

// Guardamos los bytes en el

// fichero de destino

fs.Write(datos,0,datos.Length);

fs.Close();

}

private static inttotalBytesDelStream(

Stream stream){// Averiguar cuantos bytes se// producen al descomprimirbyte[] buffer = new byte[100];int totalCount = 0;while (true){int bytesRead =stream.Read(buffer,0,100);

if (bytesRead == 0)break;

totalCount += bytesRead;}return totalCount;

}

Listado 2. Función para contar los bytes de un Stream

// Crear un stream del archivo comprimidoFileStream fs = new FileStream(ficCompri, FileMode.Open, FileAccess.Read);byte[] datos;// Asegurarse de que el stream de origen esté en el iniciofs.Position = 0;// Debemos mantener abierto el stream a descomprimir,// porque lo usaremos nuevamente.GZipStream gz = new GZipStream(fs, CompressionMode.Decompress, true);// Tenemos que averiguar los bytes una vez descomprimido// El Stream devuelto por las clases de compresión no permite// el uso de la propiedad Length, ya que// se producirá una excepción al usarla. (NotSupportedException)int total = totalBytesDelStream(gz);// Preparar el array de bytes con el total una vez descomprimidodatos = new byte[total];gz.Close();// Volver a descomprimir// Esto es necesario porque no se puede posicionar// el stream que descomprime.// También hay que reposicionar al principio el stream a descomprimir.fs.Position = 0;gz = new GZipStream(fs, CompressionMode.Decompress);// Leemos todos los bytes y los asignamos al arraytotal = gz.Read(datos, 0, datos.Length);gz.Close();fs.Close();

// Devolvemos el array de bytesreturn datos;

Listado 3. Contenido de una función para descomprimir usando GZipStream

Page 46: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

46

dnm.inicio.taller<<

forma de comprimir/descomprimir fiche-ros sin necesidad de usar herramientas deterceros, que es lo que muchos siempredeseamos, sobre todo para no dependerde que esas herramientas sigan existien-do y funcionando en futuras versiones.

Comprimir/descomprimircon las clases de .NET Framework 3.0

Como seguramente el lector sabrá, la ver-sión 3.0 de .NET Framework se incluyeen Windows Vista y se puede instalar enequipos con Windows XP SP2 o Win-dows 2003 SP1. El problema a estas altu-ras de la vida es que no existen tipos deproyectos en Visual Studio 2005 que nospermitan usar esa versión del .NET. Perocomo resulta que las clases definidas en elespacio de nombres System.IO.Packaging,que son las que nos permitirán realizartareas de compresión y descompresión con.NET 3.0, no necesitan de ningún “extra”para usarlas, será fácil crear un proyectoque utilice la librería en la que se defineese espacio de nombres, que en las refe-rencias se muestra como WindowsBase. Portanto, si queremos usar las clases decompresión de .NET 3.0, tenemos queagregar a nuestro proyecto de VisualStudio 2005 (o de cualquiera de las ver-siones Express de nuestro lenguajefavorito), una referencia a la libreríaWindowsBase.dll, situada en el directorioReference Assemblies\Microsoft\Frame-

work\v3.0 ubicado en la carpeta de Archi-vos de programa.

Una vez que hemos agregado esareferencia a nuestro proyecto, podremosusar las clases de compresión definidasen .NET Framework 3.0. En particular,solo necesitaremos una de las clases, laclase ZipPackage, para realizar la tarea decompresión y descompresión, aunquetambién podríamos usar la clase Packa-ge, ya que lo único (o mejor dicho, lo pri-mero) que necesitamos es crear un obje-to del tipo Package, que obtenemos pormedio del método compartido Open. Ytal como indica la documentación, si usa-mos ese método desde la clase “abstrac-ta” Package en realidad se llama al méto-do del mismo nombre definido en la cla-se ZipPackage; por tanto, el código queveremos a continuación funcionará igual-mente usemos la clase que usemos. Perocomo queda más evidente que ZipPacka-ge es para trabajar con clases que “empa-quetan” en un fichero de tipo ZIP, hepreferido usar la clase ZipPackage pararealizar las tareas de compresión.

¿Cómo está estructurado un fichero comprimido con Package?

Aunque no vamos a entrar en demasia-dos detalles de cómo está estructuradoun fichero creado con la clase Package (ocualquiera de sus derivadas), es impor-tante saber cuál es la estructura “básica”,con idea de que podamos almacenar losficheros a comprimir, y después poderrecuperarlos adecuadamente.

Un objeto Package permite crear unajerarquía como la de los directorios, en lasque podemos tener ficheros y subdirec-torios. Estos elementos se manejan conclases del tipo PackagePart. Al crear unade estas clases debemos indicar la ruta enla que se va a guardar esa parte. Esta rutala indicaremos mediante un objeto del

tipo Uri, que indicará tanto el nombrecomo el directorio en el que lo vamos aguardar (o del que lo queremos recupe-rar). Las clases basadas en Package tam-bién exponen un método que nos permi-te recorrer cada una de esas “partes”: Get-Parts, colección que tendremos que reco-rrer para acceder a cada uno de los fiche-ros que contiene el ZIP.

Veamos a continuación cómo reali-zar las tareas de comprimir y descom-primir usando la clase ZipPackage.

Comprimir usando la clase ZipPackage

Para comprimir un fichero usando laclase ZipPackage, debemos crear una ins-tancia del tipo Package, instancia queobtendremos por medio del método com-partido Open. A continuación, creamos unobjeto Uri en el que indicamos dónde que-remos guardar ese fichero; acto seguido,creamos un objeto del tipo PackagePartpor medio del método CreatePart de lainstancia del tipo Packageque previamentehemos creado, a que le indicamos dóndeguardarlo (el nombre), el tipo MIME delfichero que estamos guardando y el tipode compresión que queremos usar. El tipoMIME del fichero en realidad no es “trans-cendental” indicarlo de forma correcta;en el código de ejemplo del listado 4, estoyusando una función (tipoMime) que sim-plemente comprueba la extensión delfichero a guardar y devuelve la cadena conel tipo más adecuado. De esa “parte” obte-nemos el Stream (por medio del métodoGetStream) en el que escribiremos los datosque queremos almacenar.

Por ejemplo, si queremos almace-nar el fichero indicado por la variablefic en el ZIP indicado por la variableficCompri, podemos usar el código mos-trado en el listado 4.

En Visual Studio 2005 la refe-rencia a la librería WindowsBa-se.dll debemos agregarla hacien-do una búsqueda en el directorioindicado. Sin embargo, si esta-mos usando una versión superiorde Visual Studio, esa librería apa-recerá en las referencias de .NETy por tanto no será necesario bus-carla expresamente.

NOTA

[ ] using (Package pz = ZipPackage.Open(ficCompri, FileMode.Create)){

Uri docUri = PackUriHelper.CreatePartUri(new Uri(@”\” + Path.GetFileName(fic), UriKind.Relative));

PackagePart pPart = pz.CreatePart(docUri, tipoMime(fic), CompressionOption.Normal);

byte[] datos = File.ReadAllBytes(fic);pPart.GetStream().Write(datos, 0, datos.Length);

}

Listado 4. Comprimir un fichero usando la clase ZipPackage

Page 47: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

47

dnm.inicio.taller<<

En el código del listado 4, el ficherolo guardamos en la carpeta raíz del ZIP.En este caso no hay problemas, ya quesolo estamos guardando un solo fichero,pero si queremos guardar, por ejemplo, elcontenido de una carpeta (que puede tenermás subcarpetas), el procedimiento debe-ría ser algo distinto, ya que deberíamosusar los nombres de las carpetas que que-remos guardar. En el listado 5 tenemosun ejemplo que tiene en cuenta que poda-mos guardar varios ficheros y que estosestén en carpetas diferentes.

En el código del listado 5, la variabledir representa el directorio en el queestán los ficheros que queremos com-primir, la variable filtro es la especifi-cación de los ficheros que queremosincluir (por ejemplo *.*), la variable fic-Compri es el nombre completo del fiche-ro ZIP y conSubDir es una variable deltipo SearchOption que usaremos parasaber si se deben procesar todos los sub-directorios o solo el de primer nivel.

Debido a que la ruta dentro del fiche-ro ZIP no debe contener el nombre de launidad en la que están los ficheros a com-primir, al crear el objeto Uri (docUri) enel que vamos a guardar el fichero dentrodel ZIP debemos quitar el directorio raíz;si no lo hiciéramos, todo el contenido seguardaría en una carpeta que tiene pornombre la unidad en la que originalmen-te estaban esos ficheros.

Descomprimir usando la clase ZipPackage

Para extraer los ficheros que previamentehemos comprimido con la clase ZipPackage,debemos recorrer cada una de las partes deque se compone el ZIP. Esto lo haremosrecorriendo cada uno de los elementos de lacolección de tipo PackagePartCollectiondevuelta por el método GetParts del objetoPackage creado al abrir el ZIP.

Cada una de las “partes” contenidas enla colección nos indicará el nombre delfichero, además del directorio relativo enel que se encuentra. Sabiendo esto, si que-remos mantener la misma estructura dedirectorios debemos comprobar si existenlos directorios en cuestión, y en caso de queno existan debemos crearlos. En el listado6 podemos ver el código de un método quese encarga de extraer el contenido de unZIP comprimido con el código mostradoen el listado 5 de la sección anterior.

Como podemos comprobar, los espa-cios que contengan los directorios o losficheros se almacenan al estilo de las direc-ciones Web, por eso debemos convertiresos caracteres en caracteres “normales”.En este código solo se tiene en cuenta elespacio (indicado por %20), pero es posibleque debamos hacer otras conversiones.

ConclusionesEn este artículo hemos visto cómo pode-mos comprimir y descomprimir ficherosusando las clases que se incluyen en .NETFramework 2.0 y 3.0 . Como de costum-bre, en el ZIP con el código de ejemploque acompaña al artículo está el códigotanto para Visual Basic como para VisualC#, pero usando la versión 2005 del entor-no de trabajo de estos lenguajes.

string[] fics = Directory.GetFiles(dir, filtro, conSubDir);using (Package pz = ZipPackage.Open(ficCompri, FileMode.Create)){

foreach (string fic in fics){// No procesar el fichero que se está comprimiendoif (fic == ficCompri)

continue;

DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(fic));// Quitar el nombre de la unidadstring docPath = Path.GetDirectoryName(fic).Remove(

0, di.Root.Name.Length);Uri docUri = PackUriHelper.CreatePartUri(new

Uri(docPath + @”\” + Path.GetFileName(fic),UriKind.Relative));

PackagePart pPart = pz.CreatePart(docUri, tipoMime(fic), CompressionOption.Normal);

byte[] datos = File.ReadAllBytes(fic);pPart.GetStream().Write(datos, 0, datos.Length);

}}

Listado 5. Comprimir más de un fichero usando la clase ZipPackage

Listado 6. Descomprimir con ZipPackage

using (Package pz = ZipPackage.Open(ficCompri, FileMode.Open, FileAccess.Read))

{foreach (PackagePart pPart in pz.GetParts()){Uri docUri = pPart.Uri;// Comprobar y cambiar los caracteres “extraños”string ficDest = dirDest.FullName +

docUri.OriginalString.Replace(“/”, @”\”).Replace(“%20”, “ “);// Si no existe el directorio de destino, crearloDirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(ficDest));if (di.Exists == false)

di.Create();

// Leer el contenido del fichero en el Stream devuelto por GetStreamStream pStream = pPart.GetStream();int n = (int)pStream.Length;byte[] datos = new byte[n];pStream.Read(datos, 0, n);using (FileStream fs =

new FileStream(ficDest, FileMode.Create, FileAccess.Write)){

fs.Write(datos, 0, datos.Length);}

}}

Page 48: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Vale, creo que ya sé el resto de la historia.Supongo que estás usando el código siguiente (ouna pequeña variante del mismo) para guardar losbits de la imagen generada:

// bmp es una instancia de la clase

// Bitmap que contiene la imagen

// generada mediante GDI+

Response.ContentType = "image/jpeg";

bmp.Save( Response.OutputStream,

ImageFormat.Jpeg);

bmp.Dispose();

Primero, utilizas las facilidades GDI+ de.NET Framework para dibujar la imagen a tugusto; después, llamas al método Save() de laclase System.Drawing.Bitmap para persistir losbits del stream especificado. A propósito, la cla-se Bitmap solo representa el mapa de píxeles parala imagen y no tiene nada que ver con el for-mato de fichero de mapas de bits (*.BMP). Es,más bien, una descripción genérica de los píxe-les de la imagen que puede guardarse en un for-mato de fichero particular mediante el métodoSave(). Este método soporta todos los forma-

tos de imagen definidos por el tipo enumeradoImageFormat.

Cuando intentas guardar una imagen a un stre-am, el sistema intenta localizar un codificador delformato solicitado. El codificador (encoder) es unmódulo GDI que convierte del formato genéricode mapas de bits al formato requerido. Este codi-ficador es un fragmento de código no manejadoque se ubica dentro de las librerías de la platafor-ma Win32. Para cada formato de salida, el méto-do Save() de la clase Bitmap busca el codificadoradecuado y procede.

Como tu objetivo parece que es enviar la ima-gen generada al navegador del cliente, razonable-mente utilizas Response.OutputStream para volcarlos contenidos del objeto Bitmap que está en memo-ria. Claro, limpio y aparentemente efectivo.

Admito que he tenido la misma experienciaque tú. Fue durante un proyecto en el que estabaimplicado hace unos tres años. Traté de guardarel mapa de bits en memoria a otros formatos talescomo BMP, TIFF o PNG desde una aplicaciónASP.NET 1.1. No importa el caso, siempreobtenía un error genérico de GDI+. No pudeentender la excepción, pero al menos encontré

Fallos poco conocidosen ASP.NET

Dino Esposito

Dino Espositoes mentor de SolidQuality Learning. Esponente habitual en

los eventos de laindustria a nivel

mundial. Visite sublog en: http://weblogs.

asp.net/despos.(todotNet.QA@

dotnetmania.com)

En mi aplicación Web tengo páginas que sirven imágenes generadas automáticamente. Utilizo lasclases GDI+ de .NET para realizar la tarea. Una vez que el bitmap está construido, no tengo pro-blemas para guardarlo en formatos JPG o GIF. Sin embargo, el código que utilizo para almacenarlono funciona con el formato PNG.

todonet@qa

Nacida como una plataforma de desarrollo de envergadura, ASP.NET está creciendo con cadanueva versión. Hay, sin embargo, unas pocas áreas que no son totalmente conocidas por lamayoría de desarrolladores. En esta columna me centraré en ciertos aspectos extraños: erro-res en GDI+, streams, formatos, configuración y proveedores de cifrado, y por último, pero nomenos importante, serialización JSON en ASP.NET AJAX.

tod

otN

et.q

a@

dot

netm

ania.c

om

Page 49: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

una vía alternativa, que funciona para cualquier for-mato de imagen:

Response.ContentType = "image/png";

MemoryStream ms = new MemoryStream();

bmp.Save(ms, ImageFormat.Png);

Response.BinaryWrite(ms.GetBuffer());

Como puedes ver, el truco está en utilizar un obje-to MemoryStream intermedio. Primero utilizas elMemoryStream para almacenar la imagen, y después lla-mas al método BinaryWrite() del objeto Response paradirigir la respuesta hacia el navegador. Funcionó, ytodavía funciona ahora. Por más de tres años, las razo-nes para tener que obrar de esta forma no me habíaninteresado excesivamente. Pero, de alguna forma, tupregunta ha despertado mi curiosidad, así que he vuel-to a investigar el problema. Y, afortunadamente, sinla presión de tener que encontrar una solución parano retrasar el proyecto, creo que he encontrado lasolución.

Como puedes tú mismo comprobar, la excepciónGDI+ se lanza siempre que el código intenta escribiren el stream. En este punto, el código GDI+ no mane-jado captura alguna situación anómala y eleva la excep-ción a ASP.NET como un error ExternalException.Veamos las piezas de información de que disponemos:

• Si guardas a JPEG o GIF todo funciona correc-tamente.

• Si guardas como PNG u otro formato más gran-de, la operación falla si el stream suministradoes Response.OutputStream.

• En el caso anterior, todo funciona si el streamsuministrado es un MemoryStream.

• La excepción se lanza cuando el código GDI+intenta trabajar con el stream suministrado.

No hay que ser Sherlock Holmes para sospecharque tiene que haber algún problema con el stream rela-cionado con el formato de imagen. Comparemosambos: el stream devuelto por la propiedad Respon-se.OutputStream es un stream muy simple, de soloescritura. El objeto MemoryStream, sin embargo, repre-senta un flujo de datos en el que se puede escribir,leer, y buscar. Esta es la primera diferencia clave. Dehecho, si intentas realizar la misma operación en cual-quier otro stream que sea de lectura/escritura y per-mita búsquedas, la grabación funciona independien-temente del formato utilizado. En este punto, puedesimaginar que –con la notable excepción de JPEG yGIF- la mayoría de los codificadores requieren de lec-tura hacia atrás o búsquedas en el stream para realizarsu labor. Y fallan en cuanto acceden al stream, si ésteno dispone de esas capacidades.

dotN

etM

anía

<<

49

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

dnm.todonet@qa<<

Tengo una pregunta relacionada con el cifrado de algunas secciones del fichero web.config en una apli-cación ASP.NET. Además, solo puedo usar el FTP para subir ficheros, y no se me permite ejecutar nin-guna utilidad en el servidor de producción. ¿Cómo puedo usar un fichero de configuración cifrado?

Buena pregunta. Sin embargo, déjame añadir pri-mero un poco de información de fondo, ya que noestoy seguro del todo de que el problema sea simple-mente la situación que planteas en tu e-mail.

En ASP.NET 2.0, puedes proteger mediante cifra-do la mayor parte de las secciones del fichero web.con-fig de la aplicación, pero no todas. Normalmente, seemplea una herramienta de línea de comandos, asp-net_regiis.exe, que se encuentra en la ruta de insta-lación de ASP.NET. A continuación, veamos un ejem-plo que cifra la sección <appSettings> para una apli-cación llamada Test1.

aspnet_regiis.exe –pe appSettings –app /Test1

El efecto final del comando es el cifrado de lasección <appSettings> en la raíz del fichero web.con-fig de la aplicación Test1. El cifrado XML (verhttp://www.w3.org/TR/xmlenc-core) es una forma

de cifrar datos y representar el resultado en XML.El cifrado es llevado a cabo utilizando un provee-dor de cifrado de vuestra elección, y .NET Fra-mework 2.0 viene con dos proveedores predefini-dos:

• DPAPIProtectedConfigurationProvider

• RSAProtectedConfigurationProvider

El primero utiliza la API Windows Data Protec-tion (DPAPI) para el cifrado y descifrado de datos. Elsegundo es el proveedor predeterminado y utiliza elalgoritmo de cifrado RSA.

Si optamos por el proveedor DPAPI, no necesita-mos almacenar claves para cifrar y descifrar, ya que lapropia API utiliza de forma transparente una infor-mación específica de la máquina. Esto significa queno puedes simplemente cifrar el web.config en tumáquina y enviarlo a la máquina de producción, por-que el servidor ASP.NET no será capaz de descifrar-

Page 50: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Para decirlo simplemente, supongamos que estamoshablando del método de un servicio Web que devuelve unainstancia de la clase Cliente. La clase tiene, por ejemplo,4 propiedades: Nombre, Contacto, Dirección e ID.

[WebMethod]

public Cliente Lookup(string IdCliente)

{

// ...

}

Por defecto, el serializador JSON devuelve una cade-na que incluye todas las propiedades públicas de ins-tancia definidas en la clase. Necesitas un subconjuntode ellas, ¿no?

Una posible respuesta es usar el atributo [Scrip-tIgnore] en la definición de las propiedades que sequiere uno saltar en el código de la clase original. Esofuncionará.

Sin embargo, hay algo más que decir. En general,cuando estableces un mecanismo de comunicación entrecapas, podrías estar interesado en usar el Object DataTransfer (DTO). ¿Qué es eso? Simplemente, un nom-bre patrón para indicar a los objetos proxy donde estámodelada la interfaz que queremos, sin necesidad deeditar las clases que forman la capa intermedia. De for-ma que la alternativa consiste en usar una nueva claseDTO en la interfaz pública del servicio, que expongaexactamente el conjunto de propiedades que quieres queel cliente AJAX se descargue.

dotN

etM

anía

<<

50

dnm.todonet@qa<<T

odot

Net.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

Tengo un servicio Web expuesto como un servicio de script ASP.NET AJAX. El servicio tiene unmétodo que devuelve un objeto personalizado directamente desde la capa intermedia de la apli-cación. ASP.NET AJAX hace un buen trabajo serializando el objeto en un objeto Javascriptmediante JSON, pero por alguna razón necesito filtrar algunas de sus propiedades, de la mismaforma que lo hago con serialización XML. ¿Es eso posible?

lo calculando la clave, ya que ambas serán distintas, alhaber sido ésta generada en otra máquina diferente.

Si optas por el RSA —el caso predeterminado—, elproblema está en transferir la clave usada para el cifra-do a la máquina de producción. Así que, normalmente,se cifra el fichero web.config en la máquina de desarro-llo, y se las arregla uno para copiar la clave de cifrado yel fichero web.config al servidor de producción. A propó-sito, esto garantiza que puedes utilizar cifrado en unagranja de servidores.

¿Cómo se copia una clave RSA a una máquina dife-rente? Se crea un contenedor para la clave y se exportaa un fichero XML. A continuación, se importa desdecada servidor que necesite descifrarla para usar el fiche-ro web.config. Para crear un contenedor de clave, pue-de hacerse lo siguiente:

aspnet_regiis.exe –pc NombreContenedor –exp

Para exportar el contenedor a un fichero XML, pode-mos hacer:

aspnet_regiis.exe –px

NombreContenedor FicheroXml.xml

Finalmente, para mover el fichero XML al servidorde producción e importarla:

aspnet_regiis.exe –pi

NombreContenedor FicheroXml.xml

No deberías tener problemas ahora desde el punto devista del FTP, porque todo lo que se necesita es subir elfichero web.config. Como se ha dicho, sin embargo, estono es suficiente, ya que se necesita subir también la clavecontenedora en forma de fichero XML. Puedes hacerlo deigual forma, pero entonces necesitarás ejecutar una utili-dad para extraer la clave del contenedor y almacenarla deforma segura en el servidor. Si no tienes permiso para eje-cutar ese comando de forma remota, estás perdido.

En este punto, queda sólo una excepción: dejar quela aplicación cifre el fichero al inicio. La más que con-veniente API de configuración de ASP.NET 2.0, haceque la tarea sea sencilla:

string name = "appSettings";

string path = "/Test1";

string provider = "RsaProtectedConfigurationProvider";

Configuration cfg =

WebConfigurationManager.OpenWebConfiguration(path);

ConnectionStringsSection section;

section = (ConnectionStringsSection)

cfg.GetSection(name);

section.SectionInformation.ProtectSection(provider);

cfg.Save();

Para desprotegerlo, basta con cambiar el método usa-do por UnprotectSection().

Traducido al castellano por Marino Posadas

Page 51: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

51

dnm.laboratorio.net<<

Una vez superada la fase inicial de aceptación de Win-dows Presentation Foundation por parte de los usua-rios, la siguiente necesidad que se presenta ante los desa-rrolladores y a la que comienza a reaccionar ahora elmercado es la de disponer de marcos de trabajo ylibrerías que faciliten el desarrollo de aplicaciones delínea de negocio basados en esa tecnología, que ya seha mostrado capaz de garantizar cotas de experienciasde usuario nunca antes alcanzadas en la historia de lainformática. Infragistics NetAdvantage for WPF esuna de las primeras librerías de componentes de inter-faz de usuario orientadas a WPF que han aparecido enel mercado. NetAdvantage for WPF incluye varios com-ponentes potentes y fáciles de usar que pueden ser incor-porados a las aplicaciones de línea de negocio que uti-licen WPF en su capa de presentación, incluyendo reji-llas, carruseles y editores de datos que soportan varia-dos temas visuales, entre los que se encuentran los temasde Windows Vista y Office 2007.

Instalación y configuraciónLa instalación de esta librería exige como prerre-quisito la disponibilidad en el ordenador de destinode la versión 3.0 de .NET Framework, incorporadade serie en Windows Vista pero no así en WindowsXP SP2, donde debe instalarse manualmente. Si loscontroles de la librería solo van a ser utilizados des-de la nueva herramienta de diseño para WPF Micro-soft Expression Blend, no se requiere la presencia deningún software adicional; pero si los componentesvan a ser utilizados desde Visual Studio, es necesa-rio haber actualizado éste con el service pack 1 y lasExtensiones para .NET Framework 3.0. Un exce-lente resumen de los pasos a dar para la preparación

de un equipo para el desarrollo con WPF puedeencontrarse en el blog de mi colega Cristian Man-teiga en http://www.geeks.ms. El artículo se llama“Una instalación perfecta para trabajar con WPF”.Como requisitos adicionales, la instalación de NetAd-vantage for WPF deberá realizarse desde una uni-dad local y bajo una identidad de administrador, ysin que Visual Studio esté en ejecución.

Una vez satisfechos todos los prerrequisitos ante-riores, estamos listos para realizar la instalación delproducto, labor que se lleva a cabo de maneraautomática y con una experiencia de usuario ade-cuada. Ahora bien, después de la instalación es nece-sario llevar a cabo algunas tareas manuales para laconfiguración del uso de la librería desde los dife-rentes entornos de diseño y desarrollo disponibles,como Expression Blend, Visual Studio 2005 y la Beta1 de Visual Studio 2008 (“Orcas”) para los más arries-gados. Es de agradecer el fichero Quick Start quese despliega automáticamente después de la instala-ción, y que contiene orientaciones detalladas paraesta configuración, así como enlaces a la documen-tación del producto y los ejemplos.

Infragistics NetAdvantage for WPF

Octavio Hernández

Octavio Hernándezes Development

Advisor de PlainConcepts, editor

técnico dedotNetManía y tutor

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

Nombre: Infragistics NetAdvantage for WPF

Versión: Volume 1 (abril de 2007)

Fabricante: Infragistics

Sitio Web: http://www.infragistics.com/

Categoría: Componentes de interfaz de usuario

Precio: 325 EUR (729 EUR con soporte técnico

prioritario)

Ficha técnica

Han pasado ya varios meses desde la aparición de .NET Framework 3.0 y suslibrerías asociadas, entre ellas Windows Presentation Foundation (WPF). Ahoracomienzan a aparecer en el mercado las primeras librerías comerciales de com-ponentes de interfaz de usuario basadas en esta nueva tecnología de presenta-ción. Este mes presentamos Infragistics NetAdvantage for WPF, la primera ofer-ta en este sentido del conocido fabricante de componentes.

Laboratorio.net

Page 52: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Es bien conocido el hecho de queVisual Studio 2005, incluso después de ins-taladas las antes mencionadas extensiones,no ofrece soporte de tiempo de diseño parael desarrollo visual de aplicaciones WPF,hecho que se corregirá con la próxima apa-rición de Visual Studio 2008. Sin embar-go, los equipos que deseen utilizar estaimpresionante tecnología sí pueden hoyutilizar Expression Blend para el diseño desus interfaces de usuario.

Configuración para Blend

Si se desea utilizar los componentesvisuales de NetAdvantage for WPF des-de Expression Blend, será necesarioagregar en su proyecto referencias a lostres ensamblados de código que com-ponen el producto:

• Infragistics.Windows.v7.1.dll

• Infragistics.Windows.Editors.v7.1.dll• Infragistics.Windows.DataPreseter.

v7.1.dll

Una vez guardado o generado el pro-yecto, tendrá a su disposición en laLibrería de activos de Blend los contro-les que conforman la librería para arras-trarlos y soltarlos sobre sus ventanas.

Configuración para VS 2005

La tarea de agregar las referencias a losensamblados de NetAdvantage para WPFes igualmente necesaria en el caso de queestemos desarrollando las aplicacionesdirectamente en Visual Studio 2005. Adi-cionalmente, será necesario agregarmanualmente al nodo de nivel superior(generalmente <Window>) del códigoXAML los atributos de espacios de nom-bres (xmlns) correspondientes a la librería.Blend se encarga de hacer esto automáti-camente cuando el diseñador arrastra ysuelta un control de la librería sobre elcontenedor gráfico activo.

Componentes de la libreríaInfragistics NetAdvantage está com-

puesto en su versión actual por los siguien-tes componentes y otros activos:

• Un conjunto de controles visuales quecomparten una arquitectura y modode utilización comunes, lo que suavi-za sustancialmente la curva de apren-dizaje. Todos los controles han sidodiseñados de forma tal que permitanaprovechar todas las características dela plataforma subyacente, como plan-tillas, estilos o posibilidades de ani-mación, y son XBAP compatibles, loque significa que pueden formar par-te de aplicaciones WPF desplegadasa través del navegador. Los compo-nentes que conforman la librería sedescriben con algo más de detalle acontinuación.

• Un conjunto de paquetes de temasvisuales (15 en total), que hacen posi-ble dar a las interfaces de usuario desa-rrolladas con NetAdvantage una apa-riencia visual consistente a la vez queimpactante, y lo más importante (almenos desde el punto de vista de unviejo programador ☺), que permitencambiar simultáneamente el aspectode todos los elementos de una inter-faz de usuario con una simple asigna-ción a una propiedad.

• Un par de aplicaciones de ejemplo quecubren todas las posibles necesidadesde un usuario a la hora de conocer losactivos que componen el paquete yaprender a utilizarlos. Por una parte,un programa llamado xamFeature-Browserofrece más de 60 xamples (frag-mentos de código orientados a mos-trar las características de cada controlespecífico); por otra, xamS-howCase es un ejemplo crea-do con el fin de mostrar has-ta dónde puede llegar unequipo inspirado que dis-ponga de la librería.

A continuación se describenestos tres grupos de activos conun poco más de detalle.

Controles visuales

Los controles visuales que con-forman la presente versión deNetAdvantage for WPF se enu-

meran en la tabla 1. Entre estos compo-nentes hay que destacar a xamDataGrid, unapotente rejilla de datos que ofrece soportecompleta para la navegación, adición, modi-ficación, borrado, ordenación, agrupacióny carga según demanda de datos prove-nientes de orígenes de datos planos o jerár-quicos, y a xamCarouselPanel, un panel per-sonalizado que posibilita la presentaciónimpactante de un conjunto de elementosgráficos apoyándose en el movimiento ylos efectos visuales y transparencias. Asi-mismo, la librería ofrece un conjunto deeditores para los tipos de datos más comu-nes que se utilizan en las aplicaciones delínea de negocios.

Paquetes de temas

NetAdvantage for WPF contiene 15paquetes de temas, que podemos clasifi-car en los siguientes grupos:

• Temas de Windows, entre los que seincluyen Luna (Windows XP), Aero(Windows Vista) y Royale (Win-dows Media Center Edition).

• Temas de Office 2007: Office 2007Black, Office 2007 Blue y Office2007 Silver.

• Temas creados por Infragistics, entre losque se incluyen Fall, ForestGreen,Leaf, Lipstick, Wind, Water y Onyx.

Los ejemplos

Sobre los ejemplos queda poco quedecir; repetiré el consabido hecho de

dotN

etM

anía

<<

52

dnm.laboratorio.net<<

Figura 1. El ejemplo xamShowCaseen ejecución

Page 53: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

53

dnm.laboratorio.net<<

que una imagen vale más que mil pala-bras, y por ello recomiendo al lector des-cargar e instalar la versión de evaluacióndel producto, o simplemente visitarhttp://www.infragistics.com, desdedonde es posible ejecutar las versionesXBAP de los ejemplos, y verlos por símismo. La figura 1 muestra el ejemploxamShowCase en ejecución.

ConclusionesEn este artículo hemos descrito las carac-terísticas principales de NetAdvantagefor WPF, una librería de componentesy recursos de presentación para .NET

Framework 3.0 y posteriores que facili-ta en gran medida la creación de lasinterfaces de usuario de nueva genera-ción que propone Microsoft para Win-dows Vista a través de WPF. Se trata deuna de las primeras librerías de este tipoque aparecen en el mercado (aunque yaempieza a aparecer competencia: vea“Novedades”), y es de esperar que evo-lucione rápidamente para hacer frente alas necesidades que irán surgiendo; perosi desea aprovechar desde ya las posibi-lidades que esta librería ofrece, no lopiense dos veces: se trata de una inver-sión con retorno garantizado en un míni-mo tiempo.

Xceed ofrece rejilla para WPFgratuita

Xceed Software, fabricante decomponentes .NET conocidoprincipalmente por su suite en laque se incluye una potente rejillapara Windows Forms (que tam-bién se vende de manera inde-pendiente) ofrece de manera gra-tuita desde hace algún tiempo ensu página Web una rejilla paraWPF: Xceed DataGrid forWPF. El componente podríahacerse de pago en un futuro;pero el fabricante considerará alos usuarios registrados de estaversión gratuita como compra-dores oficiales de la primera ver-sión. Más información en el sitio:http://xceed.com/Grid_WPF_New.htm.

ActiPro Ribbon for WPF

Otro componente de reciente apa-rición relacionado con WPF esActiPro Ribbon for WPF, deActiPro Software. Se trata de uncontrol para WPF que imple-menta la conocida banda elástica(ribbon) que apareció por prime-ra vez en la suite de productosOffice 2007. ActiPro Ribbon hasido diseñado desde cero paracumplir con las prácticas reco-mendadas para WPF, es total-mente configurable, utiliza unmodelo de ejecución guiado porcomandos y permite reproducir lapráctica totalidad de las carac-terísticas UI que pueden encon-trarse en Office. Más informaciónen el sitio: http://www.actipro-software.com/Products/DotNet/WP

F/Ribbon.

noticias • noticias

NovedadesControl Funcionalidad

xamDataGrid Rejilla de datos para presentar información de la manera tabular ala que están habituados los usuarios. Ofrece una gran versatilidad ala hora del enlace a datos y de la edición, ordenación, agrupación ovisualización jerárquica de los datos.

xamCarouselPanel Panel personalizado que permite colocar y navegar por su conteni-do utilizando el paradigma del carrusel o la cinta transportadora,además de permitir otras posibilidades gráficas como la reflexión ola transparencia. Los objetos del carrusel se desplazan a lo largo deuna ruta animada pasando a primer o a segundo plano de atenciónsegún el usuario los vaya solicitando.

xamCarouselListbox Clase heredera de la anterior, ofrece el mismo paradigma de pre-sentación de datos sobre un cuadro de lista.

xamDataCarousel Control que funde en uno solo las posibilidades del xamDataGrid yel xamCarouselPanel. Ofrece todas las posibilidades de la rejilla parala presentación y manipulación de datos, ofreciendo a la vez el mayorsentido de movimiento y perspectiva del carrusel.

xamDataPresenter El presentador de datos es un control que ofrece una arquitecturade visualización abierta y extensible a la que es posible enchufar unxamDataGrid, un xamDataCarousel o cualquier otro control que pue-da aparecer en el futuro.

Editores Controles de edición que mejoran la experiencia del usuario alintroducir datos en las aplicaciones WPF. Ofrecen soporte parala validación en línea y el formato de los valores introducidos,y ofrecen ayudas visuales al usuario, entre otras facilidades. Pue-den ser utilizados como controles independientes o integradosdentro de una xamDataGrid.

xamTextEditor Editor de texto de propósito general.

xamMaskedEditor Editor de texto controlado por una máscara de formato.

xamNumericEditor Editor para cantidades numéricas.

xamCurrencyEditor Editor para importes monetarios.

xamDateTimeEditor Editor para fechas/horas.

xamCheckEditor Editor para valores lógicos.

Tabla 1. Controles incorporados en NetAdvantage for WPF

Page 54: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

54

El día 10 de mayo se presentó en el Centre de Serveis aEmpreses de l’Ajuntament d’Igualada el Grupo de usua-rios .NET de la Catalunya Central, CatDotNet. Unos40 asistentes, entre profesionales del sector y estudian-tes, pudieron participar en un evento que normalmentequeda “restringido”, por cuestiones geográficas, a pro-fesionales del área metropolitana de Barcelona.

Cuatro meses de planificación y trabajo desdeque, a mediados de enero, a Lleonard del Río y amí nos surgió, más que la idea, la necesidad de for-mar parte de un grupo de usuarios y profesionalescercano donde poder discutir, compartir y mostrarideas acerca de la plataforma .NET. Por entonces,Diego Gómez estaba haciendo las maletas e incor-

porándose como Business Producti-vity Advisor al Centro Microsoft deInnovación en Productividad queempezaba a dar sus primeros pasos enManresa. La verdad es que no nos hizofalta convencerle y de inmediato seprestó a colaborar, involucrando almencionado Centro Microsoft graciasa la ayuda de Albert Esplugas, sudirector, que puso a nuestra disposi-ción los recursos necesarios para poderofrecer en Manresa nuestros encuen-tros y charlas.

En marzo nos reunimos los tres para empezar aorganizar tanto el evento como el enfoque para pró-ximas reuniones. Una idea teníamos clara: los miem-bros del grupo de usuarios decidirían el contenido delas charlas.

En nuestra primera reunión, Diego, después deque Lleonard hiciera la presentación oficial de grupo,hizo una introducción sobre cuatro áreas para quecada asistente pudiera, para futuros eventos, elegir laque le resultara de mayor interés. Estas áreas fueron:

• Integración de Sistemas a la plataforma Microsoft.• Business Process Management de Microsoft.• Plataforma Business Intelligence.• Office Business Applications (OBA).

Además, nos deleitó con unos vídeos sobre unatecnología de movilidad que verá la luz durante esteaño y otro vídeo “futurista” sobre tecnología que yaexiste pero que no estará disponible hasta dentro de8 años.

Por mi parte, presenté aspectos más técnicos, enfo-cados al desarrollo en .NET. La temática elegida: eluso de transacciones en .NET 2.0 y .NET 3.0.Además, mostramos unos rápidos ejemplos de Fidd-ler y de Internet Explorer Developer Toolbar, den-

CatDotNet.Grupo de usuarios .NET de Catalunya Central

comunidad.net

CatDotNet pretende ser un grupo deprofesionales, estudiantes y entusiastasde la tecnología .NET en el cual podercompartir, discutir y mostrar ideas enun marco de colaboración único.

Page 55: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

tro la de sección “Herramientas indis-pensables para el desarrollador”; mos-tramos dos libros para diferentes nive-les de conocimiento y la iniciativa Desa-rrollador Cinco Estrellas 2005 a todoslos presentes.

Santi Balboa, compañero de bata-lla en MRW, es el encargado de admi-nistrar y crear el espacio Web a travésdel cual esperamos brindar todos losmateriales y recursos sobre .NET. Élmismo, junto a Diego y Lleonard, y pesea que le separan más de 80 kilómetrosde Igualada o Manresa, colabora deforma activa en el grupo en todas y cadauna de las decisiones que tomamos.

Nuestra segunda reunión tuvo lugaren Manresa, en el mismo CentroMicrosoft de Innovación en Producti-

vidad, donde contamos con la cola-boración de Benjamín Adell, deBcnDev.NET, que nos deleitó conuna presentación de LINQ, conbatería de ejemplos incluida. Porotro lado, Diego ofreció unademostración en vivo de las posibilida-des de Unified Communications deMicrosoft, esto es MS Office Commu-nicator 2007, MS Office Communica-tions Server 2007 y Outlook 2007.

Aunque los verdaderos protagonistasde CatDotNet, como en todos los demásgrupos, son los miembros, no queremosolvidarnos de las instituciones y entida-des de que una forma u otra han contri-buido, desde el Ajuntament d’Igualada,Diputació de Barcelona, Centre Micro-soft d’Innovació en Productivitat y, cómo

no, dotNetManía. De la misma forma,queremos también agradecer a IsidreGuixà, Jefe de Estudios de Informáticadel IES Milà i Fontanals, por acercar estainiciativa a sus alumnos.

De aquí en adelante esperamosveros por las localidades en las que ire-mos reuniéndonos, mes a mes, com-partiendo, intercambiando y disfru-tando de nuestro trabajo.

dnm.comunidad.net<<

CatDotNet• Ubicación: Cataluña Central• Fecha de fundación: 10 de mayo

de 2007• Fundadores: Lleonard del Rio y

José Miguel Torres• Página web: www.catdotnet.org• Email de contacto:

[email protected]

José Miguel Torres

Desafío Silverlight

Desafío Silverlight es un concurso para el desarrollo de un componente o aplicación Web utilizandoSilverlight para su capa de interfaz de usuario organizado por BcnDev y Microsoft Ibérica. Los trabajospresentados tienen que ser utilidad para la comunidad .NET, para luego poder aplicarlo en los portales Webde los grupos de usuarios, comunidades online, etc., ya que serán publicados en forma de Open Source bajola licencia Ms-PL asignadas a sus respectivos autores, que mantendrán la autoría de los componentes Sil-verlight desarrollados.

La competición es de ámbito nacional y dispone de suculentos premios como una entrada al Tech-Ed,la consola XBox 360, Smart Phone, PDA, Expression Studio, DevForce Professional, licencias de ReSharpery DotTrace, lotes de libros y suscripciones a las revistas líderes del mercado. Los premios serán otorgadospor un jurado que determinará los ganadores bajo los criterios de: técnica, diseño, originalidad y utilidad.

Va a ser una oportunidad estupenda tanto para el aprendizaje de esta estupenda e innovadora tecnologíacomo para profundizar en la misma, ya que los premios lo valen. Hay que dar las gracias a todas las com-pañías que apoyan este concurso: a fabricantes de software como Microsoft, IdeaBlade y JetBrains, a empre-sas de servicios como Avanade, IN2 y a editoriales como Anaya Multimedia y .netalia (dotNetManía).

Más información en http://desafiosilverlight.bcndev.net.

eventos.eventos.eventos.eventos.eventos.eventos

Page 56: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

56

dnm.comunidad.net<<

Microsoft Ibérica ha puesto a disposi-ción pública una serie de cursos onlinegratuitos y en castellano para desarro-lladores de la plataforma .NET. Todoscon una duración de 300 minutos:

Curso Desarrollo Web

Autor: José Manuel Alarcónhttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .aspx?Even-tID=1032304900&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de Introducción a .NET con VisualBasic 2005

Autores: Guillermo Som, UnaiZorrilla y Jorge Serranohttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032304899&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de Introducción a .NET con C#

Autores: Guillermo Som, UnaiZorrilla y Jorge Serranohttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032304898&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de Visual Basic 2005 para desarrolladores VB6

Autor: Guillermo Somhttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032304897&EventCate-gory=3&culture=es-ES&Country-Code=ES..

Curso de SQL Server 2005

Autores: Solid Quality Mentors(Miguel Egea, Eladio Rincón, Euge-nio Serrano, Antonio Soto)http://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-

tID=1032348698&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de desarrollo con dispositivosmóviles

Autor: Unai Zorrillahttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032348699&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de desarrollo con Windows Presenta-tion Foundation

Autores: Grupo Weboo (IskanderSierra, Mario del Valle, MiguelKatrib, y Yamil Hernández)http://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032348701&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Curso de desarrollo con Sharepoint 2007

Autor: Gustavo Vélezhttp://msevents.microsoft.com/CUI/WebCastEventDetai l s .a spx?Even-tID=1032348700&EventCate-gory=3&culture=es-ES&Country-Code=ES.

Nuevos cursos online para desarrolladores

October Conference2007 en Málaga

Los próximos 15 y 16 de octubre de2007 tendrá lugar en el hotel Silkende Málaga el evento October Con-ference 2007, organizado por elGrupo de usuarios .NET de Málagay patrocinado por iMeta y MSDN,además de otras empresas.

Durante el evento (la asistenciaal cual es gratuita) se presentaránnumerosas ponencias de gran interéspara los desarrolladores .NET y queserán impartidas por ponentes dereconocido prestigio, tanto naciona-les (José Manuel Alarcón, Gui-llermo “El Guille” Som, OctavioHernández, Unai Zorrilla y MartínLópez) como extranjeros (DinoEsposito, Chad Hower, NealFord, Hadi Hariri y Michael Li).

Para más información y regis-tro: http://www.octoberconference.net.

Servicio de bloggingde BcnDev.NET

BcnDev ha lanzado un servicio gratuitode blogging y galería de fotos para todoslos geeks de BcnDev, con la finalidad decompartir en comunidad experienciasy desafíos comunes para los miembrosde este grupo. A destacar que el sistemaque hace esto posible es CommunityServer 2007, una plataforma tecnoló-gica bastante potente de la compañíaTelligent (www.telligent.com), que ha faci-litado gratuitamente una licencia parala comunidad.

Se puede acceder a bcngeeks através de: http://bcngeeks.com.

Page 57: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

Microsoft Windows Communication Foundation Step by StepJohn SharpEditorial: Microsoft PressPáginas: 415Publicado: enero 2007ISBN: 978-0735623361Idioma: inglés

Conocido por dos obras anteriores del tipo “paso a paso” sobre C# en las versiones 1.1y 2.0 de .NET, Sharp (con ese apellido, ¡qué podía hacer!) indaga esta vez con deteni-miento, pero desde un punto de vista de iniciación, en las principales características deWCF, con el ánimo de servir de presentación formal a las buenas prácticas en la progra-mación con esta tecnología.

De esta forma, aun tratándose de una obra introductoria, los conceptos explicadosno lo son. La forma de garantizar el aprendizaje de WCF es a través de un conjunto muyelaborado de ejemplos. No es una obra de referencia, y no solemos ser muy proclives alos libros “paso a paso”, pero los que quieran iniciarse verán que su lectura resulta escla-recedora y más que suficiente para comenzar a trabajar seriamente con la plataforma. Adestacar, los capítulos dedicados a los contratos de servicio, transacciones y sesiones fia-bles, además de los últimos, centrados en el rendimiento y la seguridad.

Learning WCF: A Hands-on GuideMichelle Lerroux BustamanteEditorial: O’Reilly Páginas: 607Publicado: mayo 2007ISBN: 978-0596101626Idioma: inglés

La autora es una de las conferenciantes más reputadas en los eventos internacionales deMicrosoft, y suele ser habitual verle hablando en el Tech-Ed sobre servicios Web y tec-nologías de comunicación en general. Esta vez, con su habitual carácter didascálico, noscuenta en esta obra lo que —dada su trayectoria anterior— cabía esperar: sus experien-cias de primera mano con WCF, y su concepción global de esta plataforma. Como sue-le ser habitual, aborda el problema mediante definiciones claras y ejemplos más clarosaún, que funcionan tal cual se presentan en el libro.

Y no solo ejemplos, sino soluciones reales que permiten probar, en toda su comple-jidad, las características operativas de esta tecnología. Ni uno solo de los conceptos fun-damentales en WCF deja de estar ejemplificado. Dicen los lectores que, una vez que seha asimilado el primer capítulo, uno ya puede empezar a trabajar. No les falta razón, aun-que recomendamos la lectura completa de esta obra.

biblioteca.net

nove

dad

es ADO.NET 3.5 Cookbook

Bill Hamilton. Editorial: O’Reilly. Páginas: 800. Publicado: pendiente de publicación. ISBN:

978-0596101404.

CSS, DHTML y Ajax Cranford Teague, Jason. Editorial: Anaya. Páginas: 768 . Publicado: junio, 2007. ISBN: 978-

8441522176.

TEXTO: MARINO POSADAS

Page 58: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo

dotN

etM

anía

<<

58

desván

¿Conocen a Rosario Orcas?

Resulta que Rosario es un complejo hotelero que está enla isla de Orcas, y no se trata de ninguna muchacha, sino de“un sitio maravilloso donde olvidarnos de problemas y preo-cupaciones”, según reza en la foto el comentario de RobertMoran, allá por 1932.

Aunque Orcas —quiero decir Visual Studio 2008— seencuentra ya en fase Beta 2, su versión Team System —de nom-bre en clave Rosario— está disponible para descarga por elmomento en versión CTP. ¿Cuáles son las novedades en lasque se centrará esta versión? Según Brian Harry, de Micro-soft, en dos puntos principales: “depuración y calidad del soft-ware”, por un lado, y “alineamiento con las directrices de nego-cio” por otro. Para ello, incluirán “asombrosas capacidades detesting, junto a nuevas plantillas MSF CMMI, que incluyencontrol de tiempos de desarrollo, control de requisitos y depen-dencias extendido y mucho más, basándose como siempre enel feedback de nuestros usuarios”. Existe una interesante entra-da en el blog de Jeff Beehler (http://blogs.msdn.com/jeffbe/archi-ve/2007/08/03/first-rosario-ctp-now-available.aspx) que explicalos pormenores de esta futura versión de Visual Studio.

Mientras tanto, quien pueda irse de vacaciones ahora, a lomejor quiere probar este resort que forma parte del estado deWashington…

Marino Posadas

WinTasks Process Library. Se trata de una librería on-line que contiene una exhaustiva lista de procesos que pode-mos encontrar ejecutándose en nuestros equipos. Si eresde los que se cuida mucho de lo que está pasando en suequipo, es recomendable tener este enlace a mano. Cadaproceso está asociado con un vínculo que explica en deta-lle su función, grado de peligrosidad, origen, etc. Seencuentra disponible en http://www.liutilities.com/pro-ducts/wintaskspro/processlibrary.

ProBlogger. No uno, sino 70documentos sobre cómo debehacerse y mantenerse un blog deéxito, pueden encontrarse en lapágina de ProBlogger: http://www.problogger.net/archi-ves/2007/08/08/how-to-blog-successfully-70-reader-blogging-tips, cada uno de ellos referenciado por su título para quecada blogger busque mejor sus partes débiles o inexisten-tes y mejore de esa forma su presencia y número de lec-tores. En inglés, claro.

Take Advantage of Two-Way Data Binding inASP.NET es un documento disponible en el bien cono-

cido sitio DevX dentro de supágina http://www.devx.com/DevX/Article/35058?trk=DXRSS_LATEST, en el que se explica

cómo implementar el doble enlace a datos de manera senci-lla, desde la IU hacia los objetos de negocio y viceversa. Noes muy nuevo, pero a más de uno le puede resultar útil.

Charles Petzold. Todo un clásico. He hablado enesta revista muchas veces de sus obras y es raro quehaya alguna que no haya comentado en la secciónde Bibliografía, pero su blog es algo menos cono-cido. Últimamente se ha enzarzado en una intere-santísima discusión con el inefable Don Box sobreaspectos de WPF/C# que merece la pena seguir:http://www.charlespetzold.com/blog/2007/05/040445.html.

Adam Nathan. También es aconsejable la visita alblog de este escritor sobradamente conocido, autorde uno de los 3 mejores libros sobre WPF en elmercado, en mi opinión, y que acaba de sacar unosobre Silverlight: http://blogs.msdn.com/adam_nathan.

documentos en la red

utilidades del mes

blogs del mesnoticias.noticias.noticias

Text2EXE: Maxa Research es unaempresa dedicada a la producciónde herramientas criptográficas, entrelas que citamos hoy Text2EXE, queconvierte un texto cualquiera (pare-ce un editor normal) en un ejecuta-ble cifrado. Si se quiere enviar untexto cifrado de forma segura, bas-ta con enviar el fichero como .EXE

y el destinatario solo podrá abrirlocon la clave correspondiente. Dis-ponible en : http://www.maxa-tools.com/indexe.htm.

VLite. Se trata de una interesanteutilidad para los que nos gustareinstalar el sistema con cierta fre-cuencia (cosa cada vez más difí-cil). Permite rehacer el ISOcorrespondiente a la instalaciónde forma que se elimine el con-junto de funcionalidades que nonecesitamos, y dejándolo comouna versión personalizada deWindows Vista. Es gratuito y estádisponible en el sitio de VLite:http://www.vlite.net.

Page 59: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo
Page 60: dotNetManía - sergiogonzalezc.files.wordpress.com · nº 40 septiembre 2007 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System ... lar con Arturo