dotnetmanía - tecnología, tips de programación y … · entrevista don syme investigador ......

60
entrevista Don Syme Investigador Microsoft Research nº 45 febrero 2008 6,50 Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System dedicada a los profesionales de la plataforma .NET dotNetManía www.dotnetmania.com dotNetManía Comunidad.NET AndorraDotNet TodotNet@QA Cachés globales y Silverlight El Calendario que le estaba faltando a WPF El Marco de trabajo de entidades de ADO.NET v3.5 (II) • VS 2005 Team Edition para profesionales de bases de datos (y II) • Manejadores de eventos en SharePoint 2007 • Componentes de uso general. Acceso a datos • Una isla para Visual Basic en dotNetManía Laboratorio.NET Visual Guard .NET

Upload: dinhkhuong

Post on 29-Sep-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

entrevistaDon Syme

InvestigadorMicrosoft Research

nº 45 febrero 2008 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System

www.

dotne

tman

ia.co

m

dedicada a los profesionales de la plataforma .NET

dotNetManíawww.

dotne

tman

ia.co

m

dotNetManía

Comunidad.NETAndorraDotNet

TodotNet@QACachés globales y Silverlight

El Calendario que le estaba faltando a WPFEl Marco de trabajo de entidades de ADO.NET v3.5 (II) • VS 2005 Team Edition para profesionalesde bases de datos (y II) • Manejadores de eventos en SharePoint 2007 • Componentes de usogeneral. Acceso a datos • Una isla para Visual Basic en dotNetManía

Laboratorio.NETVisual Guard .NET

Page 2: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 3: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Bienvenido al número 45, de febrero de2008, de dotNetManía.

Con éste comenzamos el quinto volu-men, y con él nuestra declaración de inten-ciones para este año: dotNetManía onli-ne. Empecé a editar contenidos en forma-to digital en 1991 (clippeRmanía); desdeese momento hasta la fecha he participa-do en varios proyectos de contenidos digi-tales que no terminaron de cuajar, a pesarde las evidentes ventajas... ¿quizá no era elmomento? Ahora sí creo que pueda ser elmomento de combinar la documentaciónimpresa con la documentación online, yéste será nuestro principal propósito en lospróximos meses.

Durante los días 26 y 27 de febrero secelebrará a nivel mundial el lanzamientode Visual Studio 2008, junto con el deSQL Server 2008 y de Windows Server2008, en el que será, posiblemente, elevento más importante en la historia deMicrosoft. Me consta que en España seestán haciendo enormes esfuerzos paraconseguir una afluencia de miles de pro-fesionales. La cita será en el Palacio deCongresos de Madrid y el evento se lla-ma Microsoft Tech Days.

Y hablando de eventos, este mes infor-mamos de Envision, un evento para dise-ñadores celebrado en Milán. Que unarevista para desarrolladores como es éstacubra, aunque sea mínimamente, un even-to para diseñadores, puede ser síntoma deque algo está cambiando. Que en un even-to para diseñadores se hable de interfacesde usuario, aplicaciones móviles, Web2.0..., lo confirma.

Este mes entrevistamos a Don Syme,principal artífice de F#, un lenguaje concapacidades para el cálculo matemático.

Don nos demuestra cómo la pasión por loque uno hace es el mejor argumento comer-cial. Marino Posadas no deja de hablarmaravillas de este lenguaje desde que entre-vistó a Don y sin duda convencerá al máspintado. Tenga cuidado con su lectura, novaya a convencerle también. Si despierta suinterés y quiere conocer más sobre éste uotros lenguajes .NET, le recomiendo unavisita a http://www.dotnetlanguages.net.

El Grupo Weboo vuelve a ocupar laportada con “El calendario que le estabafaltando a WPF”, continuando con la sagarelacionada con elementos avanzados deWPF. En este caso, nos explican cómodefinir un control personalizado desdecero, usando como ejemplo el gadgetCalendario de Windows Vista y mostran-do cómo se implementaría en WPF.

Interesante artículo el que GustavoVélez publica bajo el largo y descriptivotítulo: “Manejadores de eventos en Sha-rePoint 2007. Los flujos de trabajo nosiempre son necesarios para hacer que lascosas funcionen bien”. Con la integra-ción de Workflow Foundation y Share-Point 2007, la utilidad que los manejado-res de eventos tenían a la hora de crearflujos de trabajo desaparece en su mayorparte. Sin embargo, Gustavo nos descri-be las tareas donde usar manejadores deeventos en lugar de flujos de trabajo esmás conveniente.

Finalmente, Guillermo “Guille”Som se ha comprado una isla, la isla deVisual Basic en dotNetManía, y la hallamado Isla.VB. Una columna o reduc-to para los programadores que quieranver código Visual Basic de la mano delviejo maestro, que dice estar rodeado de“cesharperos” por todas partes.

dotN

etM

anía

<<

3

dotNetManía, año 5to.

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 45 • Febrero 2008Precio: 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

Krasis

Plain Concepts

Raona

Solid Quality Learning

Además colaboran en este númeroDaniel Seara, Gustavo Vélez, Iskander Sierra,José Luis Latorre, Mario del Valle, RubénGarrigós 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/ Thomas Edison, 4 Oficina 1406Parque empresarial Rivas Futura

28521 - 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 - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

sumario 45Entrevista a Don Syme 10-12

En el pasado Tech-Ed se hablaba mucho de un nuevo lenguaje de la familia #. Ya son 4 ó 5 (F#,S#, P#, etc.), pero éste en concreto dispone de características para el cálculo matemático quecualquier científico valorará. Su artífice principal es Don Syme, investigador en Microsoft ResearchCambridge (Reino Unido), cabeza del equipo de investigación de aspectos avanzados del CLR en suversión 2.0, amable persona y excelente demostrador de las cualidades de “su lenguaje”.

El Marco de trabajo de entidades de ADO.NET v3.5 (II) 14-17En nuestro anterior artículo [1] hicimos una introducción al Marco de entidades de ADO.NET3.5, en la que se trató de dar especial importancia a la capacidad de éste para crear una capa deabstracción sobre el modelo relacional. Esta abstracción, a la postre, nos permitirá centrarnos en unaprogramación más conceptual, enfocada en el dominio del negocio que deseamos modelar. En estaentrega y las siguientes veremos cómo modelar nuestro dominio de trabajo y cómo mapear el mismocontra el almacén relacional sobre el que estemos trabajando.

VS 2005 Team Edition para profesionales de bases de datos (y II) 18-22Visual Studio 2005 Team Edition for Database Professionals es la herramienta para profesionalesde base de datos de la plataforma Visual Studio. Desplegar nuevos entornos de datos, refactorizarobjetos, realizar pruebas unitarias de la base de datos... todo se vuelve sencillo con DataDude.

El Calendario que le estaba faltando a WPF 24-30Con este artículo continúa la saga relacionada con elementos avanzados de WPF. En el último deestos trabajos, vimos cómo definir un control personalizado, al presentar un “scroll circular”. Sinembargo, en aquel caso realmente bastó con asociarle las plantillas y estilos adecuados al controlbásico ScrollBar ya existente en WPF.

Manejadores de eventos en SharePoint 2007. Los flujos de trabajo no siempre son necesarios para hacer que las cosas funcionen bien. 32-36

Los manejadores de eventos de SharePoint 2007 son más que una herencia de la versión 2003: enWSS y MOSS 2007 han sido ampliados y enriquecidos considerablemente. Ahora pueden serutilizados a lo largo y ancho del sistema, y su modelo de objetos ha sido mejorado en diferentesdirecciones. Los manejadores de eventos permiten realizar algunas de las tareas que los flujos detrabajo están en capacidad de ejecutar, pero de una forma mucho más sencilla y efectiva, e inclusivepueden anticiparse a eventos, algo que es difícil de realizar con flujos de trabajo.

Componentes de uso general. Acceso a datos 38-42Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada laimportancia que tiene a la hora de desarrollar aplicaciones, comenzaremos con el acceso a datos,explicando según se desarrolla los fundamentos y consideraciones en los que basa, para que se puedausar, modificar o repensar completamente y que os pueda ser realmente útil.

Una isla para Visual Basic en dotNetManía. O cómo hacer las cosas mejor con Visual Basic. 44-48

Con el quinto año de dotNetManía estrenamos una nueva columna en la revista dedicadaexclusivamente a los que gustan desarrollar con Visual Basic. No es que antes no hubiera nada paraVisual Basic, pero ya iba siendo hora de que tuviésemos nuestro propio rincón. En esta islatendremos ocasión de ver muchas cosas relacionadas con Visual Basic, particularmente con la versión9.0, que es la que se incluye en Visual Studio 2008, aunque muchos conceptos serán válidos tambiénpara las versiones anteriores.

dnm.todotnet.qaCachés globales y Silverlight 49-51

dnm.laboratorio.net 52-54Visual Guard .NET

dnm.biblioteca.net 55Silverlight 1.0 UnleashedSilverlight 1.0

dnm.comunidad.net 56-57AndorraDotNet. Grupo de usuarios .NET de Andorra

dnm.desvan 58

Page 5: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 6: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Microsoft Ibérica presentó el pasado 15 de enero la versiónen castellano de Visual Studio 2008 y de .NET Framework3.5. Según Enrique Fernández-Laguilhoat, director dePlataforma y Desarrollo de Microsoft Ibérica, “Visual Stu-dio 2008 posibilita una nueva generación de aplicacionescon una experiencia de usuario revolucionaria, ya que pro-porciona toda la potencia de la plataforma Windows Pre-sentation Foundation, con la productividad del IDE (Inte-grated Development Environment), y una integración connuestras herramientas de diseño, Microsoft Expression, quepermiten la colaboración entre desarrollador y diseñador.Por su parte, los servicios online –que Microsoft lleva impul-sando desde el nacimiento de .NET en 1999– están trans-formando el mercado TIC. Nuestra compañía ha encon-trado en este mundo de servicios a través de Internet otraforma de seguir proporcionando valor al cliente, com-binándolos de forma equilibrada con nuestras ofertas líde-res de software de sobremesa y servidor. Se trata de ofre-cer a nuestros partners nuevas vías de hacer negocio sobreuna plataforma que liderará el futuro de Internet. VisualStudio 2008 permite desarrollar este tipo de aplicacionesde una forma productiva, ágil e integrada con tecnologíascomo LINQ, WCF y WF.”

El mercado de desarrollo de software en España

Enrique Fernández-Laguilhoat aprovechó para darcifras del estado actual del mercado de desarrollo enEspaña, además de dar un repaso a todas las novedades deVisual Studio 2008 y un rápido repaso a los avances de losúltimos años, desde las tecnologías cliente-servidor, lasaplicaciones distribuidas, más tarde servicios Web y final-mente entramos en el concepto de software+servicios enel que se engloba Visual Studio 2008.

Actualmente, el mercado del desarrollo de softwarecuenta con 97.500 desarrolladores profesionales enEspaña (algunas fuentes estiman esta cifra en 130.000),de los cuales 61.500 están repartidos en 8.500 empresasde desarrollo a medida, 7.000 son programadores en1.200 ISV y 29.000 son desarrolladores corporativos

(grandes bancos, organismos oficiales, con desarrolla-dores en nómina).

Según la compañía, el 70% de los desarrolladores haadoptado la tecnología .NET, y en cifras globales losdesarrolladores de .NET y los desarrolladores de Javaestán prácticamente a la par en estos momentos. Lacomunidad de desarrolladores en España ha venido cre-ciendo y organizándose, de modo que hasta la fecha exis-ten 20 grupos de usuarios con 4.000 miembros y 39 MVPcertificados. Por su parte, MSDN online ha registrado30.000 inscripciones y en los programas de betatesting ypruebas han participado 11.000 desarrolladores. Además,se han realizado 35.000 y 2.800 descargas de las versio-nes Express y de prueba de Visual Studio, respectiva-mente.

Microsoft Tech Days: presentación Mundial de VisualStudio 2008, Windows Server 2008 y SQL Server 2008

Los días 26 y 27 defebrero son los designadospara el lanzamiento mun-dial de Visual Studio 2008,SQL Server 2008 y Win-

dows Server 2008 y. El evento en español tendrá lugaren el Palacio Municipal de Congresos de Madrid.

Junto con la presentación de estas tres nuevas solu-ciones, se contactará con la presentación que Steve Ball-mer realizará ese mismo día en Estados Unidos. Tam-bién se contará con la presencia de Rosa Mª García,presidenta de Microsoft Ibérica, además de los respon-sables del área de Desarrollo y Plataformas de la com-pañía en nuestro país.

Si quiere más información, puede visitar la páginawww.microsoft.es/lanzamiento.

Disponibilidad de Visual Studio 2008 en castellano

La versión en castellano de Visual Studio 2008 estarádisponible a partir del 1 de febrero para los suscriptoresMSDN en España. Más información y descargas enhttp://www.microsoft.com/spanish/msdn/latam/visualstu-dio2008.

dotN

etM

anía

<<

6

noticiasnoticias

noticias

noticias

noticias

Microsoft Ibérica presenta Visual Studio 2008 en castellanoLa compañía presentó la versión en castellano de Visual Studio 2008 y de .NETFramework 3.5, como paso previo al Microsoft Tech Days, el mayor evento delanzamiento realizado hasta la fecha por Microsoft, en el que además de Visual Studio2008 se presentarán SQL Server 2008 y Windows Server 2008.

Page 7: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

7

dnm.directo.noticias<<

Sun Microsystems anuncia que ha lle-gado a un acuerdo definitivo para adqui-rir MySQL AB, uno de los máximosiconos de la tecnología Open Source ydesarrollador de una de las bases dedatos sobre código abierto de mayorcrecimiento del mundo. La adquisiciónse llevará a cabo por aproximadamente1.000 millones de dólares.

Una vez se complete la transacciónpropuesta, MySQL se integrará en lasorganizaciones de Software, Ventas yServicios de Sun, y Marten Mickos,hasta ahora CEO de MySQL, pasará aformar parte del equipo directivo deSun. Mientras tanto, un equipo con-junto formado por representantes deambas compañías desarrollará los pla-nes de integración basados en las siner-gias técnicas, de producto, así comoculturales y las mejores prácticas de

negocio y desarrollo de ambas com-pañías. MySQL tiene su sede centralen Cupertino, California, y Uppsala,Suecia, y cuenta con 400 empleados en25 países.

La base de datos open sourceMySQL es la “M” en el acrónimoLAMP –la plataforma de softwarecompuesta por la unión de las tecno-logías de sistema operativo Linux, elservidor web Apache, el gestor de basede datos MySQL y los lenguajes deprogramación PHP/Perl–. Sun estácomprometida en mejorar y optimi-zar las tecnologías LAMP sobreGNU/Linux y Microsoft Windowsjunto con OpenSolaris y Mac OS/X.

Se espera que la operación quedetotalmente cerrada a finales del tercertrimestre o principios del cuarto del añofiscal 2008.

Sun Microsystems adquiere MySQL El código fuente de .NET Framework disponible Microsoft ha liberado el código fuente delas librerías de .NET Framework, permi-tiendo su depuración con Visual Studio2008. Está disponible el código de lassiguientes librerías:- .NET Base Class Libraries (System, Sys-

tem.CodeDom, System.Collections, Sys-tem.ComponentModel, System.Diagnostics,System.Drawing, System.Globalization,System.IO, System.Net, System.Reflec-tion, System.Runtime, System.Security,System.Text, System.Threading, etc).

- ASP.NET (System.Web, System.Web.Extensions).

- Windows Forms (System.Windows.Forms).

- Windows Presentation Foundation(System.Windows).

- ADO.NET y XML (System.Data y Sys-tem.Xml).

En breve, se incluirán nuevas librerías,incluyendo LINQ, WCF y Workflow. Másinformación en: http://weblogs.asp.net/scottgu.

El acuerdo acelera la estrategia de crecimiento de Sun, quetoma una relevante posición en un mercado mundial de basesde datos que asciende a más de 15.000 millones de dólares.

Microsoft ha presentado su nuevo softwarede gestión de relaciones con clientes, Micro-soft Dynamics CRM 4.0, anteriormenteconocido como Titan. La nueva versión seofrece bajo dos nombres de producto:Microsoft Dynamics CRM 4.0 para lasimplantaciones en local y hospedadas porpartners y Microsoft Dynamics CRM Livepara la solución hospedada por Microsoft.

Al haber sido diseñada con un mismocódigo base tanto para las implantacionesen local como hospedadas, los clientespodrán elegir el modelo que mejor se adap-te a sus necesidades, con la flexibilidad decambiar de opción en función de la evolu-ción de dichas necesidades.

Microsoft Dynamics CRM 4.0 ofrecemás de 200 novedades, entre las que seincluyen:

• Una avanzada arquitectura multi-empresa (multi-tenant) que soportavarios clientes por servidor.

• Nuevas capacidades globales que ofre-cen al usuario la posibilidad de elegirentre más de 25 idiomas y múltiplesdivisas.

• Nuevas capacidades de Business Inte-lligence, con nuevas vistas y asistentesde informes para el usuario final.

• Automatización de procesos avan-zada gracias a la integración conMicrosoft Windows WorkflowFoundation.

• Nuevas posibilidades de colaboracióncon Microsoft Office Communica-tions Server 2007, con indicadores depresencia en tiempo real dentro de lapropia aplicación CRM.

Disponibilidad de la soluciónM i c r o s o f t

Dyna mics CRM4.0 ya está dispo-nible en inglés,alemán, fran cés,holandés, español,danés y finlandés.El resto de idio-mas se irán lan-zando a lo largo delas próximas semanas. Los clientes actua-les con un plan de mantenimiento activo(Software Assurance) pueden disponer dela nueva versión sin cargo adicional.

La solución hospedada por Microsoft,“Microsoft Dynamics CRM Live” se ofre-ce solo en Estados Unidos y Canadá.

Microsoft presenta Microsoft Dynamics CRM 4.0La nueva versión de Microsoft Dynamics CRM incorpora más de 200 novedades con una experienciade usuario muy familiar, ya que está integrada con las herramientas de Microsoft Office.

Page 8: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

El pasado mes de enero se celebró enMilán, Italia, un evento sin precedentes, dedi-cado a la forma en que diseñamos y comu-nicamos mediante los nuevos medios digita-les. Todo ello sin concretar tecnologías y deuna forma general, sin entrar en técnicas niherramientas, simplemente centrándose enconceptos, y en las nuevas tendencias dediseño y líneas de investigación en todos losámbitos, desde la creación de logotipos has-ta las interfaces de usuario.

Este evento fue Envision, http://www.envision-event.com, un curioso (y, a todasluces, exitoso) experimento cuyo plantea-miento era una interactividad total entreponentes y asistentes, con un número bas-tante reducido de estos últimos. Se estruc-turó alrededor de la realización de ponen-cias seguidas de una tanda de preguntas alponente, estableciendo un diálogo direc-to con los asistentes. La última sesióncorrespondió a una distribución de los ponentes entrelas mesas en que estaban ubicados los asistentes, lo queprovocó unas conversaciones muy interesantes.

En Envision pudimos contemplar, desde el puntode vista de varias figuras internacionales del diseño, laevolución de las tecnologías y cómo los cambios socia-les afectan a las comunicaciones digitales y a las for-mas de transmitir mensajes. Tuvimos la suerte de con-tar con la presencia de figuras como Matt Bagwell,Giles Colborne, August De Los Reyes, CatrionaCampbell, Phil Gerrard, Wolfgang Henseler, Fre-derick Fuchs, Pete Barr-Watson y James Deeley, todosellos expertos reconocidos internacionalmente en sus áre-as. Para más información sobre los ponentes, visitehttp://www.envision-event.com/agenda/bios.aspx.

Durante el evento se pudieron vislumbrar tenden-cias como el diseño simplista, estilo “KISS –Keep ItSimple, Stupid–”; el análisis del impacto emocional dedeterminados diseños, psicoanalizándolos literalmen-te; el análisis de lo verdaderamente relevante; la evo-lución de las interfaces y la nueva moda “multitouch”,adaptando las interfaces a nuevas formas de interactuarmucho más naturales; la definición del diseño como unnuevo lenguaje, y con él, cómo reacciona el ser huma-no al mismo, evaluando la respuesta emocional de laspersonas; y lo que se define como emotional designer,

que busca un diseño motivado casi exclusivamente porsu impacto emocional en las personas.

También se expusieron los procesos de diseño quebuscan que éste provoque un impacto en el público, cau-sando fuertes experiencias con el resultado de una reten-ción de información mucho más efectiva. Y tuvimos elplacer de ver otras líneas de diseño que han aparecidodebido a las nuevas tecnologías, como el diseño mini-malista, derivado de las nuevas necesidades de interfa-ces “mínimas” para dispositivos móviles, o cómo afectael fenómeno Web 2.0 al diseño. Por último, se expusoel roadmap de la nueva línea de productos Microsoft paradiseñadores y cómo el gigante informático pretendepotenciar todas estas líneas de negocio y facilitar su inte-gración con el mundo, a veces opuesto, del desarrollo.

Sin duda, todo apunta a una nueva era, en la que eldiseño y todas las aplicaciones del mismo van a ocuparun lugar primordial, haciendo mucho más agradablenuestra forma de percibir e interactuar con la tecnología.Un nuevo diseño que nos sea emocionalmente muchomás agradable y extremadamente natural y fácil de usar.

Sin duda, toda una visión de futuro... ¿o debería decir“de presente”?

José Luis Latorre

ENVISION Influencing digital communication

eventoseve

ntos

dotN

etM

anía

<<

8

Page 9: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 10: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Marino Posadas

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

rrollo para Españay Portugal de Solid

Quality Mentors.Puedes leer su blog

en http://www.elavefenix.net.

entrevista

En el pasado Tech-Ed se hablaba mucho de unnuevo lenguaje de la familia #. Ya son 4 ó 5(F#, S#, P#, etc.), pero éste en concretodispone de características para el cálculomatemático que cualquier científico valorará.Su artífice principal es Don Syme, investigadoren Microsoft Research Cambridge (ReinoUnido), cabeza del equipo de investigación deaspectos avanzados del CLR en su versión2.0, amable persona y excelente demostradorde las cualidades de “su lenguaje”.

Aunque lo hemos comentado enprivado, ya es proverbial que el entre-vistado se introduzca a sí mismo…

Claro, mi nombre es Don Syme,trabajo en Cambridge, y podría decir-se que tengo dos áreas de interés: unarelacionada con la División de Desa-rrollo, y otra como investigador. Mi tra-bajo en los últimos 10 años ha sido elde aportar novedades al paisaje de ofer-tas que constituye .NET, y que luegoson implementadas en lenguajes comoC#, Visual Basic, y ahora también enF#.

Respecto a mi pasado, bueno, soyDoctor en Informática, y quizás la par-

entrevista a Don Syme

Page 11: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

te más conocida de mi obra es algo quemuchos desarrolladores utilizan todoslos días: los tipos genéricos, que seintrodujeron en la versión 2.0 de .NET.De hecho, ese proyecto comenzó hacemuchos años, en 1999.

Además, ha sido una de las carac-terísticas de la versión 2.0 que, por unlado, era la más solicitada, y por otro,la más ampliamente aceptada y utili-zada, cuando ha estado disponible.

Los genéricos fueron un trabajo liga-do, en sus inicios, a los lenguajes exclusi-vamente, y luego hicimos un gran esfuer-zo para incorporarlos al CLR de formatransparente, en la forma que pueden uti-lizarse desde la versión 2.0.

Sin embargo, respecto a los nue-vos cambios en los lenguajes .NET3.5, hay una variedad de opiniones.La mayoría piensa que son muy inte-resantes y aportan productividad,pero también hay voces detractorasde algunas novedades como losmétodos extensores, que para másde uno rompen con los principios dela programación orientada a objetos.

Interesantísimo el tema. Verás, yomismo no soy un defensor de ese tipode extensiones, digamos que no es mifavorita. Y supongo que, al final, será

una cuestión de buenas prácticas en laforma en que se utilicen. Pero es indu-dable que podemos encontrar escena-rios donde los métodos extensores sontotalmente requeridos si queremos darcon una solución sencilla.

Y, además, como investigadoresestuvimos trabajando en la forma dehacer que estas extensiones no rom-pieran en ningún momento la extraor-dinaria arquitectura sobre la que estábasada el CLR. Eso era un objetivo pri-mordial, y algunas de las limitacionesimpuestas para su uso vienen de esasconsideraciones. Es lo mismo que ocu-rre con LINQ. Creo que son carac-terísticas muy poderosas, muy intere-santes de cara al desarrollador, pero quees responsabilidad del usuario usarlas

en el escenariocorrecto y en el sitiocorrecto.

Mi respuesta esno, pero quierosaber la tuya. Y estoviene a tenor dealgunos comenta-rios que leí en tuWeb. ¿Programaren un lenguajeseguro es hacer pro-gramación segura?

Es muy impor-tante la seguridad detipos, es muy impor-

tante que el lenguaje y la plataformaofrezcan características programablesde seguridad, y es muy importante laseguridad que ofrece la ejecución en unentorno como el CLR, con sus carac-terísticas de verificación, que son amplí-

simas. Pero –efectivamente– por muchoque haga la plataforma, la programa-ción segura es una decisión de los ana-listas, planificadores y codificadores.Siempre habrá prácticas incorrectas deprogramación si el código no tiene encuenta la seguridad.

Como vamos a hablar del len-guaje nuevo dentro de nada, quierocomenzar por una pregunta que–desde los desarrolladores, hastaalumnos míos de post-grado en uni-versidades– me han hecho con res-pecto a los lenguajes: ¿hacía faltaotro lenguaje nuevo, ahora que pare-ce que, en esta materia, está todoinventado?

Pues creo que sí, porque –una vezmás– depende de la tarea que quierashacer. Cuando veo a gente trabajar enF# porque quieren abordar cierto tipode problemas, y los veo avanzar muyrápidamente en la solución, me con-venzo de que sí. De que cada tipo de pro-blemática tiene, idealmente, su lengua-je; aquel en el que el problema a resol-ver se expresa con más sencillez y ofre-ce un mejor tiempo de respuesta.

Una de las contradicciones de lasituación es ésa: por un lado, hay unaconvergencia clara en los lenguajes, yla mayoría de usuarios se decanta porlas opciones C# o VB.NET en .NET,e incluso tenemos Java (similar sintác-ticamente a C#) en otras plataformas,

dotN

etM

anía

<<

11

dnm.directo.entrevista<<

Page 12: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

12

dnm.directo.entrevista<<

y por otro, también puedes programaren lenguajes funcionales, cosa que noera posible hace 10 años en la forma enque lo es hoy en día. Y estamos notan-do que incluso desarrolladores de otrasplataformas se están sintiendo atraídospor F#, por lo que pueden aprender ahacer con el lenguaje y porque es unaexperiencia gratificante observar cómoeste lenguaje soluciona algunos pro-blemas clásicos del cálculo, su elegan-cia, su simplicidad y su potencia.

De hecho, para su diseño nos fija-mos en características de muchos len-guajes, desde Prolog, pasando por len-guajes funcionales, a muchos otros detipo más experimental. Incluso en elpropio lenguaje SQL, con toda supotencia expresiva.

Bueno, pues vamos a hablar deF# como lenguaje…

Tenemos un equipo de trabajo enCambridge, dedicado al desarrollo deeste lenguaje, y también contamos condos personas en Redmond. Y la formaen que yo lo veo tiene mucho que vercon la programación funcional. Es cru-cial en los tipos genéricos, en LINQ,en los lenguajes funcionales, claro, ytambién lo es aquí.

Debido a las características propiasque tiene, F#, junto a otros lenguajesde la plataforma, convierten a .NET enuna plataforma multi-paradigmática,donde manteniendo los criterios fun-damentales, contamos con una varie-dad enorme de posibilidades para rea-lizar las tareas. En F#, por ejemplo,podemos abordar la representación grá-fica de funciones (tanto en 2D como en3D) de una manera simplísima y con unrendimiento espectacular. Esto permi-te eliminar muchas complicaciones pro-pias de lenguajes que no han sido pen-sados para esto, sino para representarentidades, y conseguir un código sucin-to, que te permite empezar a jugar conel lenguaje, obtener inmediatamenteresultados de esas pruebas, y acabar,como si acabas un juego, con una apli-cación completa que resuelve un pro-blema concreto.

Desde el punto de vista de lasnovedades, por decirlo así, ¿cuál diríasque es la oferta de F# como lenguaje?

Supongo que es una combinación defactores muy productivos desde el puntode vista operativo (Don echa mano desu portátil y comienza a hacernos unademo del lenguaje). Como ves, la sin-taxis del lenguaje es muy bella, y solonecesita plantear como sentencias losobjetivos que se persiguen. Si te das cuen-ta, estamos obteniendo resultados de for-ma rapidísima, con muy poco código, queademás resulta muy fácil de comprender,precisamente por la misma razón. Y larapidez es una de las cosas que más llamala atención. La gente no puede creer queoperaciones como la que estamos plan-teando ahora (era un cálculo matricialcon matrices de 10000 elementos),puedan dar una respuesta tan inmediata.

Y además, F# puede combinarse conotros lenguajes, de forma que F# ofrezcala solución que podamos necesitar desdeun punto de vista de cálculo numéricomientras el resto de nuestra aplicaciónestá hecha en C# o VB.NET o lo que nosparezca bien. Podemos disfrutar de lasventajas que ofrece cada lenguaje, sinabandonar ninguno de los pilares sólidosque nos da la plataforma, y haciendo quecada lenguaje se ocupe de aquello quehace más eficazmente. Por ejemplo, hacerlo que estamos haciendo ahora en C++(estaba representando gráficamentelos contenidos de la matriz inversa de

una dada, en una superficie tridimen-sional) no solo nos llevaría muchísimomás tiempo de codificación, sino que no

tendríamos la inme-diatez de la represen-tación gráfica, y muchomenos este tiempo derespuesta.

Además, en todoslos procesos de re-cál-culo, cuando cambia-mos las condicionesoriginales, como pue-des ver (y lo podíamosver; créame el lector,que no salíamos denuestro asombro),todo el proceso es casiinstantáneo…

Desde luego, ya me hubiera gus-tado tener algo así cuando estudia-ba Física en la universidad…

De hecho estoy escribiendo un libro–junto a Jon Harrop– titulado preci-samente “F# para científicos”, en el quetratamos cómo resolver la mayor par-te de los problemas matemáticos rela-cionados con el cálculo: desde las carac-terísticas que has visto, hasta transfor-madas de Fourier, implementación deoperadores especiales como lagrangia-nos, hamiltonianos, etc.

Pues vamos a recomendar lossitios Web de ambos, si te parece,para los lectores que quieran intro-ducirse en el lenguaje. El oficial deMS-Research (http://research.micro-soft.com/fsharp/fsharp.aspx), el tuyo(http://blogs.msdn.com/dsyme) y el deJon (http://fsharpnews.blogspot.com).Desde el punto de vista bibliográfi-co, también he visto un libro en laeditorial APress…

Sí, se llama “Expert F#”, y –aparte demí– colaboraron en él Adam Granicz yAntonio Cisternino. Creo que es unabuena introducción al tema. Y además,ya hay mucha gente haciendo eco de lascaracterísticas del lenguaje en numero-sos blogs, y pensamos seguir incorpo-rando gente al equipo a medida que elproyecto siga creciendo.

Page 13: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 14: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Si juntáramos en una misma sala a un programa-dor de algún lenguaje orientado a objetos y a unDBA para modelar un determinado sistema, elmodelo de clases y el modelo relacional genera-do por cada uno de ellos seguramente distaríanmuchísimo uno de otro. El programador mode-laría el proceso teniendo en cuenta conceptoscomo la herencia de clases, el polimorfismo, laagregación de tipos y el uso de contratos comolas interfaces; además, tendría en cuenta distintasmétricas para valorar la calidad del modelo: pro-fundidad de la herencia, complejidad del código,etc. y procuraría aplicar patrones de diseño pararesolver problemas ya conocidos. Por otra parte,el DBA crearía su modelo relacional teniendo encuenta factores muy distintos a los anteriores;algunos de estos factores podrían ser el estudiode las formas normales, la integridad referencialy el uso de índices apropiados. Ambos tendríanargumentos de sobra para defender los modeloscreados, y sin lugar a dudas ambos tendrían razón.Esta impedancia entre ambos mundos es la quese lleva mucho tiempo intentando resolver, tenien-do como objetivo que ambas partes puedan tra-bajar sobre sus modelos e intentando que ningu-no tenga que realizar demasiadas concesiones alotro.

El Marco de entidades de ADO.NET v3.5 nospermitirá crear de una forma relativamente sen-cilla una capa de abstracción sobre el modelo rela-cional, posibilitando así el desarrollo de un mode-lo acorde con un lenguaje orientado a objetos comoC# o Visual Basic. En esta entrega y las siguien-tes veremos cómo, a partir de un modelo relacio-nal, podemos crear un modelo de objetos que hagauso de la herencia, la agregación de tipos y la cre-ación de tipos complejos o entidades.

Al igual que en el anterior artículo de esta seriesobre el Marco de entidades, partiremos del mode-lo relacional FUTBOL2006, que a pesar de serun modelo sencillo, nos permitirá jugar con

El Marco de trabajo de entidades de ADO.NET v3.5 (II)

Unai Zorrilla esDevelopment Team

Leader de Plain Conceptsy tutor de campusMVP.

MVP desde 2004,colabora activamente con

Microsoft en eventos dearquitectura y

desarrollo, así como engiras de productos. Autor

del libro "Modelandoprocesos de negocio con

Workflow Foundation".

Octavio Hernández esMentoring Team Leader

de Plain Concepts, editortécnico de dotNetManía y

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

Autor del libro "C# 3.0 yLINQ".

En nuestro anterior artículo [1] hicimos una introducción al Marco deentidades de ADO.NET 3.5, en la que se trató de dar especial impor-tancia a la capacidad de éste para crear una capa de abstracción sobreel modelo relacional. Esta abstracción, a la postre, nos permitirá cen-trarnos en una programación más conceptual, enfocada en el dominiodel negocio que deseamos modelar. En esta entrega y las siguientes vere-mos cómo modelar nuestro dominio de trabajo y cómo mapear el mis-mo contra el almacén relacional sobre el que estemos trabajando.

Figura 1. Modelo lógico de FUTBOL2006

plataforma.netUnai ZorrillaOctavio Hernández

Page 15: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

15

dnm.plataforma.net<<

muchos de los conceptos antes men-cionados. En la figura 1 puede verseparte de este modelo relacional.

La herramienta visual de diseñoComo comentamos la vez anterior, elMarco de entidades se apoya en tresficheros XML de metadatos: el mode-lo relacional del almacén se especificaen el fichero SSDL y el modelo con-ceptual en el fichero CSDL, mientrasque el fichero MSL define un mapea-do entre los dos modelos. Precisamen-te estos dos últimos son los que debe-mos modificar para reflejar nuestrosconceptos, y esas modificaciones pue-den realizarse de dos maneras:a) Editando manualmente los ficheros,

para luego validar su contenido ygenerar los ficheros de códigocorrespondientes utilizando EDM-Gen.EXE. Presentamos las posibilida-des que ofrece esta herramienta delínea de comandos en nuestra entre-ga anterior.

b) Utilizando las herramientas visua-les integradas en Visual Studio2008 (actualmente parte de EntityFramework Tools CTP). Ésta es lavía que utilizaremos a partir deaquí.

Para crear un modelo de datos delMarco de entidades se deberá, sobre elnodo correspondiente al proyecto en elExplorador de soluciones, seleccionarla opción “Add…” | “New item” |“ADO.NET Entity Data Model”. Apa-recerá un asistente que nos permitiráelegir la base de datos de origen (tam-bién se puede generar un modelo a par-tir de cero, si se desea). El modelo ini-cial generado en nuestro caso se mues-tra en la figura 2.

Mapeando la herencia de tipos

Los modelos relacionales no sopor-tan de forma directa el concepto deherencia de tipos. El Marco de entida-des, por su parte, prevé tres mecanis-mos diferentes para modelar la heren-cia, que son:• Tabla por jerarquía (Table per Hie-

rarchy, TPH).• Tabla por tipo concreto (Table per

Type, TPT).• Tabla por subclase (Table per Sub-

class, TPS).

En esta entrega y las siguientes vere-mos cómo modelar las relaciones deherencia utilizando cada uno de estostres mecanismos.

Tabla por jerarquía

Esta técnica consiste en mapear todala jerarquía de tipos dentro de una mis-ma tabla de nuestro modelo relacional.

Dentro de esta únicatabla tendremos unacolumna, conocidacomo discriminador,que nos permitirá dife-renciar según su valora qué tipo concretocorresponde cada unade las filas de la tabla.Mediante esta estrate-gia, las consultas sobretipos distintos se reali-zan de una forma ópti-ma, puesto que sola-mente tendremos querealizar un filtro sobrela columna que actúacomo discriminador.

La entidad Futbolistadel modelo de la figura 2 es un ejemploen el que puede aplicarse una herenciapor jerarquía, en la que la propiedadPosicion nos permite discriminar losdistintos tipos de futbolistas que se pue-den establecer dentro de nuestro mode-lo de dominio. En el modelo relacional,la columna Posicion es de tipo nchar(1)y toma valores como ‘P’ para indicar queel jugador es un portero, ‘D’ para indi-car que se trata un defensa o ‘M’ paraindicar que la posición del futbolista esla de mediocentro. Este conocimientosobre el discriminador nos permite cre-

ar una jerarquía de clases en nuestromodelo conceptual.

El primer paso a realizar será el deeliminar de la entidad Futbolista la pro-piedad Posicion, para que posterior-mente pueda ser utilizada en las condi-

Figura 3. Agregando entidades al modelo conceptual

Figura 2. Modelo conceptual inicial de FUTBOL2006

Cuando se crea un modelo de entidades mediante el asistente, VisualStudio genera un fichero .EDMX que “condensa” en un único esquemalos contenidos de los ficheros .SSDL, .CSDL y .MSL. Al generar el proyec-to, el contenido de este fichero se “desdobla” en las tres partes corres-pondientes en el directorio de salida.[ ]

NOTA

Page 16: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

16

dnm.plataforma.net<<

ciones de mapeado de nuestras entida-des lógicas al modelo relacional subya-cente. De acuerdo con nuestro discri-minador, crearemos dentro del mode-lo conceptual las entidades Portero,Defensa, Mediocentro y Delantero; paraello es suficiente con usar el menú con-textual del modelo conceptual, como semuestra en la figura 3.

La ventana de creación de entida-des nos permitirá indicar si la nuevaentidad creada es una herencia de algúntipo de entidad ya existente en el mode-lo; en nuestro caso, seleccionamos Fut-bolista como tipo base para esta nue-va entidad (figura 4).

Una vez creada la nueva entidad,deberemos establecer qué valor de dis-criminador permite establecer que unFutbolista es un Portero. La ventana dedetalles de mapeado nos permitirá indi-car la tabla del modelo relacional a la

que se asocia esta entidad (por supues-to, la tabla Futbolista), y la condiciónpor la cual se establecerá que una fila

de esta tabla corresponde a una entidadde tipo Portero (figura 5).

Si realizamos el mismo proceso paralas entidades Defensa, Mediocentro yDelantero, obtendremos un modeloconceptual similar al que se puedeobservar en la figura 6.

Por supuesto, todo este trabajo rea-lizado sobre el diseñador tiene su con-trapartida en los ficheros CSDL yMSL. Por un lado, dentro del modeloconceptual tendremos definidas nuevasentidades, como se puede ver en el frag-mento XML del listado 1. El fichero demapeado, por su parte, contendrá nue-vos elementos de tipo Condition,

Figura 4. Creando la entidad Portero con un tipo base

Figura 5. Mapeando la entidad Portero.

Figura 6. Modelo de herencia con tabla por jerarquía.

Figura 7. Diagrama de clases resultante

Page 17: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

17

dnm.plataforma.net<<

mediante los cuales se especifican losvalores que debe tomar la columna dis-criminador para cada una de las nuevasentidades creadas con tipo base Futbo-lista (listado 2).

Utilizando el modelo obtenidoUna vez terminado el trabajo anterior, ten-dremos nuestro modelo conceptual y lajerarquía de clases tal como nos los mues-tra el diagrama de clases de la figura 7.

Como la semana anterior, no quisié-ramos terminar la columna sin mostrarun pequeño ejemplo de código, para queel lector vaya familiarizándose con el esti-lo de programación que promueve el

Marco de entidades. El listado 3 muestraun programa en el que se crea un Porte-ro y se persiste en la base de datos; a con-tinuación, se ejecuta una consulta paracomprobar que la inserción ha sidocorrecta.

El próximo mes continuaremos pre-sentando los mecanismos que ofrece elMarco de entidades para modelar laherencia.

<EntityType Name=”Portero” BaseType=

”FUTBOL2006Model.Futbolista” />

<EntityType Name=”Defensa” BaseType=

”FUTBOL2006Model.Futbolista” />

<EntityType Name=”Mediocentro” BaseType=

”FUTBOL2006Model.Futbolista” />

<EntityType Name=”Delantero” BaseType=

”FUTBOL2006Model.Futbolista” />

<EntityTypeMapping TypeName=”IsTypeOf(FUTBOL2006Model.Portero)”><MappingFragment StoreEntitySet=”Futbolista”><ScalarProperty Name=”Id” ColumnName=”Id” /><Condition ColumnName=”Posicion” Value=”P” />

</MappingFragment></EntityTypeMapping><EntityTypeMapping TypeName=”IsTypeOf(FUTBOL2006Model.Defensa)”><MappingFragment StoreEntitySet=”Futbolista”><ScalarProperty Name=”Id” ColumnName=”Id” /><Condition ColumnName=”Posicion” Value=”D” />

</MappingFragment></EntityTypeMapping><EntityTypeMapping TypeName=”IsTypeOf(FUTBOL2006Model.Mediocentro)”><MappingFragment StoreEntitySet=”Futbolista”><ScalarProperty Name=”Id” ColumnName=”Id” /><Condition ColumnName=”Posicion” Value=”M” />

</MappingFragment></EntityTypeMapping><EntityTypeMapping TypeName=”IsTypeOf(FUTBOL2006Model.Delantero)”><MappingFragment StoreEntitySet=”Futbolista”><ScalarProperty Name=”Id” ColumnName=”Id” /><Condition ColumnName=”Posicion” Value=”L” />

</MappingFragment></EntityTypeMapping>

Listado 1. Nuevas entidades en el fichero CSDL

namespace DNM{using FUTBOL2006Model;

class Program{static void Main(string[] args){FUTBOL2006Entities ctx = new FUTBOL2006Entities(metadata=.\\Futbol2006.csdl|.\\Futbol2006.ssdl|.\\Futbol2006.msl;”

+ “provider=System.Data.SqlClient;”+ “provider connection string=”+ “\”Data Source=.;Initial Catalog=FUTBOL2006;Integrated Security=True\””);

// a new kid in town...Portero p = new Portero();p.Nombre = “PABLO PELAEZ”;p.Sexo = “V”; p.FechaNacimiento = new DateTime(1973, 2, 18);p.Club = ctx.Club.First(c => c.Codigo == “RMA”);p.Pais = ctx.Pais.First(x => x.Codigo == “ES”);// ¡observe que no hay propiedad Posicion!ctx.AddToFutbolista(p);ctx.SaveChanges(true); // persistir los cambios

// porteros de equipos madrileñosvar q = from c in ctx.Futbolista

where c is Portero && c.Club.Ciudad == “MADRID”select c.Nombre;

// ejecutar la consultaforeach (var s in q) Console.WriteLine(s);

Console.ReadLine();}

}}

Listado 3. Programa de ejemplo.

Listado 2. Condiciones en el fichero C-S

ReferenciasHernández, Octavio y Zorrilla,Unai “El Marco de trabajo deentidades de ADO.NET 3.5”, endotNetManía nº 44, enero de2007.

Blog del equipo de ADO.NETEntity Framework, en http://blogs.msdn.com/adonet.

[1]

[2]

Page 18: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Introducción

En nuestro anterior artículo vimos cómo VisualStudio 2005 Team Edition for Database Profes-sionals (DataDude para los amigos) nos propor-ciona interesantes funcionalidades para hacer nues-tro trabajo diario más cómodo. En esta segundaparte vamos a continuar abordando otros reque-rimientos habituales en nuestro día a día:

• “Necesito desplegar la base de datos en un nue-vo entorno, a partir de los últimos cambios ycon un conjunto de datos listo para utilizar”.

• “Hay que renombrar unos objetos de basesde datos y encargarse de todas sus depen-dencias. No está bien que tengamos colum-nas telfono, farturas, lineafracturas u otrasperlas similares”.

• “Necesitamos garantizar que los nuevos cam-bios realizados en el modelo no produzcanerrores en la capa de datos”.

• “El sistema en producción contendrá 1 millónde clientes y 10 millones de facturas. Debescomprobar que el rendimiento no se dete-riora en exceso”.

Despliegue de cambiosEl despliegue de cambios en los modelos de datoses un proceso que se realiza frecuentemente deforma bastante artesanal. Probablemente tenga-mos definido nuestro propio procedimiento dedespliegue, y siguiéndolo paso a paso nos asegu-

ramos que se cumplen ciertas condiciones como:disponer de una copia de seguridad actual de labase de datos, no tener usuarios conectados, etc.Acto seguido suele venir un conjunto de scriptsordenados o un largo script que deberemos lanzarpara realizar las modificaciones pertinentes. Final-mente, se suelen realizar algunas comprobacionesbásicas y se da el despliegue por finalizado.

Este proceso tiene varios inconvenientes y pue-de acabar siendo demasiado lento para las necesi-dades actuales, bastante propenso a fallos y con unavuelta atrás complicada. DataDude nos ofrece lageneración automática de un script de despliegueunificado que tendrá en cuenta todos los cambiosaplicados a los objetos, así como varios scripts depre-despliegue y post-despliegue que pueden serpersonalizados. Por citar algunos, los scripts de pre-despliegue son responsables de generar o modifi-car los servidores enlazados y los logins creados, ylos de post-despliegue de los cambios en roles ypermisos. Adicionalmente podemos añadir nuevosscripts, por ejemplo para actualizar un registro enuna tabla de estado. De esta forma indicaríamos alas aplicaciones que estamos realizando una ope-ración de mantenimiento en la base de datos.

Utilizando la funcionalidad de despliegue deDataDude, cuando lo realicemos contra un servi-dor en el que ya teníamos desplegado nuestromodelo de base de datos, se nos advertirá de cual-quier situación que pueda producir pérdidas dedatos. Para mayor seguridad, tenemos la opciónde que se realice una copia de seguridad automá-ticamente como paso previo al despliegue, evi-

VS 2005 Team Edition para profesionales de bases de datos (y II)

plataforma.net

Rubén Garrigós es unarquitecto de soluciones

Microsoft certificadocomo MCT, MSCD .NET

y MCITP SQL Server2005. Es experto en e-

Commerce B2C y B2B yen plataformas de datos

sobre SQL Server enSolid Quality Mentors.

Junto a EEladio Rincón yCarlos Sacristán escribeen “El rincón del DBA”:

http://blogs.solidq.com/ES/ElRinconDelDBA

Visual Studio 2005 Team Edition for Database Professionals es la herramientapara profesionales de base de datos de la plataforma Visual Studio. Desplegarnuevos entornos de datos, refactorizar objetos, realizar pruebas unitarias de labase de datos... todo se vuelve sencillo con DataDude.

Rubén Garrigós

Page 19: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

19

dnm.plataforma.net<<

tando así la posibilidad de un olvido en este punto.Algunas veces no será viable realizar la copia de segu-ridad de esta forma, y entonces deberá ser realizadamanualmente en los scripts de pre-despliegue paraadaptarse a las peculiaridades del sistema destino.Además, si nuestro modelo de recuperación es com-pleto, el proceso de despliegue nos generará un pun-to de restauración, por lo que ante cualquier proble-ma nos revertirá al estado anterior al despliegue.

Finalmente, indicar que este proceso de compila-ción y despliegue del modelo de datos puede ser auto-matizado mediante el uso de scripts y MSBuild de for-ma que éste se realice contra varios servidores, cadadía o de forma sincronizada con las compilaciones ydespliegues de nuestras aplicaciones.

Refactorización

Una nueva funcionalidad que aparece con DataDu-de es la posibilidad de realizar cambios a los objetosde nuestro modelo (tablas, procedimientos, funcio-nes, vistas…) de forma que las referencias a éstos seactualicen y se transmitan en cascada por el resto delmodelo.

Hasta ahora, la alternativa habitual del profesio-nal de base de datos pasaba por el uso del socorridoprocedimiento almacenado sp_depends o alguna estra-

tegia similar, pero siempre se requería de una granintervención manual por nuestra parte. Con la nue-va herramienta de refactorización de DataDude, alrenombrar un objeto se replicará el cambio en todoslos objetos afectados. Por ejemplo, para cambiar elnombre de una columna tan solo tendremos que selec-cionar la opción “renombrar” en el objeto del esque-ma deseado, previsualizar los cambios a aplicar y apli-carlos (figuras 2 y 3).

Comparado con el tedioso proceso de tener querealizar esta labor manualmente, deshaciendo los cam-bios en cada uno de los objetos, la ventaja es eviden-te. Como medida de seguridad adicional, se registranadicionalmente en ficheros de log los cambios reali-zados por la refactorización.

Previa aplicación del script de despliegue (que será elque reflejará los cambios de nuestro proyecto en la basede datos), debemos tener en cuenta algunas considera-

Figura 1. Scripts de despliegue

Figura 3. Actualización automática de losobjetos afectados por el cambio

Figura 2. Renombrar objetos.

Page 20: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

20

dnm.plataforma.net<<

ciones adicionales. La primera de ellas esque los cambios en tablas por defecto seaplican previo borrado del objeto afecta-do. Otro problema que nos podemosencontrar es que no se realice el renom-brado de forma correcta en scripts perso-nalizados pre-despliegue, post-desplie-gue, tests unitarios, etc. El motivo en estecaso suele ser que los objetos referencia-dos no utilizan el nombre cualificado deéstos. En estos casos es posible que algu-nas referencias queden sin actualizar, ypor ello una buena práctica consiste en eluso siempre del nombre totalmente cua-lificado (por ejemplo Adventure-

WorksLT.SalesLT.ProductDescription envez de ProductDescription).

Tests Unitarios Los test unitarios nos proveen de una for-ma de testear componentes individualesen un sistema. Su naturaleza está desti-nada a comprobar el funcionamientocorrecto o incorrecto de cada compo-nente de forma individual. El valor decontar con una batería de tests que nospermita asegurar el funcionamiento anivel unitario correcto crecerá con eltiempo, con el aumento de la compleji-dad del modelo y con la cantidad de cam-bios que se introduzcan durante las ite-raciones del ciclo de desarrollo.

Los tests unitarios suelen ir destina-dos a comprobar el buen funcionamien-to de un componente con una funciona-lidad muy concreta, como podría ser ennuestro caso un procedimiento almace-nado. Uno de los principales problemascon los que nos encontramos a la hora deimplementar los tests unitarios de formamanual es el coste de su realización ymantenimiento. La creación de los esque-letos que realicen la llamada a los proce-dimientos, comprueben los valoresdevueltos y validen ciertas condicionesrequiere algunas veces más esfuerzo quela codificación del propio procedimien-to. En este apartado, DataDude nos faci-lita la generación de forma automática deesqueletos para procedimientos, funcio-nes y triggers y nos soporta directamentela evaluación de las condiciones que semuestran en la tabla 1.

Cuando creemos un nuevo test anuestro proyecto, se añadirá un nuevoproyecto de tests asociado a la solución ydeberemos indicar la conexión principala la base de datos y, de forma opcional, laprivilegiada. Es muy interesante el que sedisponga de esta diferenciación, pues nospermitirá comprobar que la ejecución dela prueba se realizará en un contexto deseguridad adecuado y no en el de unadministrador de base de datos. La cone-xión privilegiada se utilizará en los scriptsde pre y post-ejecución y nos permitirá,por ejemplo, acceder directamente aaquellas tablas a las que el usuario que eje-cuta el procedimiento no debería teneracceso directamente para comprobar queel funcionamiento del procedimiento hasido el esperado.

Un ejemplo de esqueleto autoge-nerado de prueba para un procedi-miento sería el siguiente:

En este caso, podría ser suficientecomprobar que el valor devuelto es 0, locual indicaría una ejecución correcta. Enotros casos deberemos realizar compro-baciones adicionales que podemos codi-ficar en T-SQL y lanzar un error en casode no superarlas de esta forma:

Una característica de los tests unita-rios bien diseñados es que garantizan surepetibilidad, siendo los resultados idén-ticos en distintas ejecuciones dado un mis-mo entorno de prueba. Para conseguir-lo, es necesario garantizar que se cum-plen ciertas pre-condiciones antes de lan-zar un test. Un ejemplo claro para el testde un procedimiento almacenado deinserción de cliente sería comprobar pre-viamente que el cliente que va a insertar-se no existe ya. Este test unitario del pro-cedimiento contendrá a su vez los tests oacciones necesarios para garantizar su fun-cionamiento acorde a lo especificado. En

Condición Descripción

Empty Resultset Comprueba que se devuelve un resultset vacío. Se debe precisarel resultset a evaluar si se devuelven varios como resultado.

Execution Time Comprueba que se ejecute la prueba en menos de un umbral detiempo seleccionado. Esto puede ser útil para detectar proble-mas de rendimiento tras un cambio o como complemento paracumplir un SLA.

Inconclusive Indica que el test aún no está completo, que tenemos pendientedefinir cuál es el comportamiento esperado.

Not Empty Resultset Comprueba que se devuelve un resultset no vacío. Se debe pre-cisar el resultset a evaluar si se devuelven varios como resultado.

Row Count Comprueba que se devuelve un número exacto de registros enel resultset indicado.

Scalar Value Comprueba que el valor devuelto en un resultset, en la fila ycolumna indicada, coincide con un valor dado. También puedeconfigurarse para aceptar o no nulos.

Tabla 1. Condiciones soportadas

— database unit test for dbo.uspLogError

DECLARE @RC INT,@ErrorLogID INT

SELECT @RC = 0EXEC @RC = [dbo].[uspLogError]

@ErrorLogID OUTPUTSELECT RC=@RC,

ErrorLogID=@ErrorLogID

if (@RC=2 and @ErrorLogID>25)RAISERROR(

‘El identificador del error está fuera de rango’, 12, 1 )

Page 21: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

21

dnm.plataforma.net<<

este caso necesitaríamos, al menos, otrotest que garantizara que cuando el clien-te ya existe se devuelva el error esperado.Por otra parte y para garantizar la repe-tibilidad, deberíamos borrar dicho clien-te al finalizar el test para dejar el entornolisto para la próxima ejecución.

Para llevar a cabo estas tareas comen-tadas disponemos de varios scripts aso-ciados a los scripts de prueba. Dispone-mos de los scripts “pre-test”, “post-test”,“Test initialize” y “Test cleanup”. Los dosprimeros se ejecutan antes y después decada test específico y son específicos paracada test, mientras que los segundos sellaman antes y después de cada uno delos tests de la clase de pruebas. Indicarque finalmente estos tests se implemen-tan con clases del nuevo espacio de nom-bres Microsoft.VisualStudio.TeamSys-tem.Data.UnitTesting, con lo que es posi-ble modificar el comportamiento de lasclases generadas para adaptarlo a nues-tras necesidades más allá de la ejecuciónde scripts T-SQL. Por ejemplo, podría-mos modificar en el servidor de pruebasun fichero XML que se utilice en nues-tros procedimientos con OPENROWSET. Estonos permitiría fijar y comprobar pre-condiciones que no sean directamenteparte del motor relacional.

Planes de generación de datosde pruebaMuy relacionada con la repetibilidadestá la preparación de datos de prueba.En muchos casos las pruebas requierende un contexto más o menos complejopara poder ser lanzadas. Por ejemplo,en el ejemplo comentado anteriormentede creación de un cliente podemosrequerir de una tabla de países, otra decódigos postales y otra de tipos de clien-tes. No resultaría nada convenientetener que preparar el entorno de datoscompleto y deshacerlo al finalizar cadaprueba unitaria.

Un plan de generación de datos per-tenece a un proyecto de base de datos,aunque un mismo proyecto puede con-tener diferentes planes de generaciónde datos. Un ejemplo típico consiste entener un plan de generación orientado

a las pruebas, otro a las pruebas de ren-dimiento y otro para despliegues denuevos entornos.

Cuando añadimos un plan de gene-ración nuevo, se nos muestran las tablasque componen nuestro modelo para queindiquemos cuáles queremos que parti-cipen en este plan de generación dedatos. Para cada tabla podremos confi-gurar el número de filas a generar y siqueremos mantener proporcionalidadcon alguna tabla relacionada. Si estamosgenerando datos para una tabla que nosrelaciona un cliente con sus direccionesde correo, podemos determinar un ratiode 3:1 para que por cada cliente se gene-ren 3 direcciones asociadas. Esto es espe-cialmente relevante cuando generamosplanes de generación de datos para prue-bas de carga, pues el rendimiento pue-de variar extraordinariamente si un sis-tema debe soportar 100 facturas porcliente o 100.000 facturas por cliente.

Una vez hemos determinado la can-tidad de registros a generar, debemosindicar cómo vamos a generar dichosdatos columna a columna. Las colum-nas que tengan definido un identifica-dor autoincremental asociado a la cla-ve primaria o sean columnas calculadasaparecerán deshabilitadas, pues se gene-rarán los datos acorde a su definición.Para el resto disponemos de generado-res de dos tipos principalmente: gene-

radores basados en el tipo del dato ygeneradores basados en la extracciónde datos de una fuente de datos.

Entre los primeros nos encontramosgeneradores de enteros, de números encoma flotante, de booleanos o de cade-nas, y todos ellos parametrizables. Algu-nos de los parámetros son: valor mínimoy máximo, longitud del dato, tipo de dis-tribución para la generación aleatoria,semilla a utilizar en el generador, por-centaje de nulos a generar... De estos pará-metros hay que destacar la importanciade la semilla utilizada. Será ésta la que nospermitirá asegurar la repetibilidad deldato generado entre distintas ejecucionesdel plan de generación de datos.

Entre los segundos contamos conel Data Bound Generator, que nos per-mite obtener los datos a partir de unaconsulta. Respecto a los datos devuel-tos podremos especificar un porcenta-je de nulos a generar, así como unasemilla. En este caso la semilla no seutilizará para inicializar un generadorde datos aleatorio, sino para seleccio-nar, de entre los registros devueltos porla consulta, cuáles utilizar. Obviamen-te, para garantizar la repetibilidad, laconsulta que utilicemos deberá devol-ver siempre los mismos datos.

Para aquellos casos en los que estosgeneradores no sean suficientes y nece-sitemos de generadores específicos,

Figura 4. Plan de generación de datos

Page 22: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

22

dnm.plataforma.net<<

contamos con la posibilidad de crearnuestros propios generadores (MyData-Generator), al igual que hacíamos conlos comprobadores de los tests unita-rios. Estos generadores es posible obte-nerlos por composición de generado-res ya existentes, por ejemplo combi-nando el generador de expresionesregulares con el Data Bound Genera-tor, o bien crearlos desde cero de for-ma que se ajusten a nuestras necesida-des específicas.

Otra vida es posibleComo colofón a estos artículos, vamosa indicar qué funcionalidades pode-mos utilizar de DataDude para ayu-darnos en la resolución de los reque-rimientos planteados al inicio de losartículos.

Utilizando la herramienta decomparación de esquemas podremosobtener de forma rápida las diferen-cias existentes y el script en caso deser necesario. Podemos realizar lacomparación bien seleccionandodirectamente la base de datos de pro-ducción como origen, o bien un pro-yecto de Visual Studio que tengamossincronizado. Como destino selec-cionaremos la base de datos de desa-rrollo del equipo o un proyecto debase de datos sincronizado con ésta.Si existen diferencias, tan solo ten-dremos que generar el script, revisar-lo y entregarlo.

Mediante la herramienta de compa-ración de datos comprobaremos si es cier-ta o no la sospecha. Utilizaremos comoorigen la base de datos de la sucursal ycomo destino la base de datos central.

Indicaremos ignorar los datos que exis-tan solo en destino para centrarnos enaquellos datos que existen en origenpero no en destino. Seleccionaremoslas tablas que contengan los datos yobtendremos las diferencias y el scriptde inserción si lo necesitamos para sin-cronizar los datos.

El primer paso será obtener la últi-ma versión del modelo del SourceSa-fe o de la herramienta de control decambios utilizada. Una vez hecho esto,compilaremos el modelo para asegu-rarnos de que no existen errores en elproyecto. Modificaremos el destino deldespliegue, revisaremos el script de des-pliegue generado y lo ejecutaremos.En estos momentos sería buena ideatambién pasar la batería de tests uni-tarios si disponemos de ellos. Para elloejecutaremos previamente el plan degeneración de datos para dejar la basede datos desplegada y probada, listapara su uso.

Utilizando refactorización realiza-remos los cambios uno a uno y super-visaremos los objetos a los que afectan.Aplicaremos los cambios y compilare-mos el modelo de nuevo para compro-bar que no existen errores. A conti-nuación, desplegaremos en nuestroentorno de pruebas y pasaremos laspruebas unitarias para contrastar queen tiempo de ejecución todo sigue fun-cionando como esperamos.

Tras aplicar los cambios en el mode-lo, lanzaremos nuestras pruebas unita-rias previamente diseñadas. Rápidamen-te comprobaremos si alguna de éstas hafallado y en dicho caso analizaremos elorigen del error. Daremos el ok cuandotodas las pruebas unitarias se superen sinerrores.

Crearemos un plan de generación dedatos especial para la realización de laprueba de carga. Dicho plan generarálas tablas con tantos registros como losesperados en producción. A continua-ción, bien manualmente o bien median-te un test de carga de VS2005, lanzare-mos las diferentes pruebas unitarias paracomprobar el grado de desempeño ydeterminaremos si es necesario tomarmedidas como la creación de nuevosíndices, particionado, reescritura de códi-go T-SQL, etc.

Figura 5. Generadores de datos

“DataDude, necesito conocer las dife-rencias del modelo de datos de desa-rrollo respecto al modelo de produc-ción. También un script para sincroni-zar nuestro entorno de desarrollo”.

“DataDude, parece que hay algún pro-blema en la sincronización de datoscon una de nuestras sucursales. Nece-sitaría comparar los datos de factu-ras y clientes para confirmar que estátodo correcto“.

“DataDude, necesito desplegar la basede datos en un nuevo entorno, a partirde los últimos cambios y con un con-junto de datos listo para utilizar”.

“DataDude, hay que renombrar unosobjetos de bases de datos y encar-garse de todas sus dependencias. Noestá bien que tengamos clientes con“telfono”, “farturas”, “lineafracturas”u otras perlas similares”.

“DataDude, necesitamos garantizar quelos nuevos cambios realizados en elmodelo no produzcan errores en lacapa de datos”.

“DataDude, el sistema en produccióncontendrá 1 millón de clientes y 10millones de facturas. Debemos com-probar que el rendimiento no se dete-riora en exceso”.

Page 23: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 24: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

plataforma.net

En este trabajo vamos a ver cómo definir un con-trol personalizado pero desde cero, es decir, cuan-do no basta con retocar uno ya existente. El con-trol a definir es para que haga las veces de un calen-dario, y puede verse como un control de ediciónde valores de tipo DateTime, como el que se usa enmuchas aplicaciones de Windows pero que lamen-tablemente no está presente entre los controlesbásicos que ofrece WPF. La figura 1 nos muestrael gadget Calendario de Windows Vista, al cualpretendemos acercarnos mostrando cómo sepudiera implementar en WPF. Note que un calen-dario no se limita a presentar los valores enterosque conforman un DateTime, sino que visualizatodos los días del mes de dicha fecha y los distri-buye por días de la semana, lo que nos propor-

ciona mayor utilidad y funcionalidad en el traba-jo con fechas.

En la jerarquía de tipos básicos de WPF nohay un tipo Calendar ni un tipo DateTimePicker,como sí los hay en Windows Forms, con los quepoder hacer edición o selección de fechas. ¿Dón-de encajar un tal Calendar dentro de la jerarquíade WPF? Tómese un tiempo antes de seguir ypiense en una respuesta. Un tal calendario podríaconsiderarse como control de rango (un herede-ro de RangeBase) ya que, al igual que los valoresnuméricos, los valores DateTime son totalmenteordenables en un rango entre un valor mínimo yun valor máximo. Sin embargo, lamentablemen-te RangeBase no es un tipo genérico (por ejemplodefinido con parámetro restringido a IComparable)y solo está definido en base a tipos numéricos, loque impediría usarlo con una fecha (DateTime)como valor componente.

Heredero de ControlPor otra parte, un calendario no puede verse sola-mente como una figura para visualizar, ni tampo-co como un panel o un decorador. Debe definir-se como un control ya que debe aportar funcio-nalidad, pero a su vez se espera que pueda tenerdiferentes apariencias, acordes con el estilo y temade la aplicación en que se utilice. Recuerde quelos controles en WPF (tipos herederos de Control)

El Calendario que le estabafaltando a WPF

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 ddotNetManía.

Mario del Valle e IskanderSierra son instructores deprogramación en C# dela cátedra de Programa-

ción e Ingeniería de Soft-ware del departamento

de Ciencia de la Compu-tación de la Universidadde La Habana. Son desa-

rrolladores del grupoWEBOO dedicados a la

tecnología .NET.

Con este artículo continúa la saga relacionada con elementos avanza-dos de WPF [1-4]. En el último de estos trabajos [4], vimos cómo defi-nir un control personalizado, al presentar un “scroll circular”. Sin embar-go, en aquel caso realmente bastó con asociarle las plantillas y estilosadecuados al control básico ScrollBar ya existente en WPF.

Figura 1. Gadget Calendario de Windows Vista

Mario del Valle, Iskander Sierra, Miguel Katrib

Page 25: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dnm.plataforma.net<<

tienen una propiedad Template a travésde la cual se le puede cambiar la apa-riencia al control.

Para definir un control personali-zado en VS 2008 hay que crear unproyecto con la opción “WPF Cus-tom Control Library” (figura 2). Estocrea por defecto un fichero Custom Control1.cs, que renombraremos porCalendar.cs, en el cual se incluye unaclase parcial heredera de Control (a laque llamaremos Calendar). Además, secrea también un fichero generic.xamlcorrespondiente al tema por defectode la aplicación. Este código XAMLcontiene un diccionario de recursosWPF donde aparece un estilo defini-do por defecto para el nuevo controlgenerado. El listado 1 nos muestra esteestilo.

Es conveniente detenerse aquí paradestacar algunos aspectos sobresalien-tes de WPF:1. El uso del atributo especial xmlns:local

declarado en el elemento raíz le indi-ca al compilador de XAML que cual-quier elemento con un nombre quecomience con el prefijo local: (en estecaso local:Calendar) se debe loca-

lizar en el espacio de nombres WpfCustomControlLibrary1 (como indicael valor del atributo xmlns:local).

2. La utilización de un estilo (Style) pre-sente en el código de generic.xamlhace que todas las propiedades indi-cadas en sus correspondientes Settersse apliquen por defecto a todos losobjetos creados del tipo indicado

en TargetType (Calendar en estecaso).

3. La plantilla del control (ControlTemplate) asignada a la propiedadTemplatemediante el Setter es la quedefinirá la apariencia predetermina-da del control. De modo que cam-biando directamente el valor de lapropiedad Template o utilizando otroestilo para asociar al tipo Calendar,se puede modificar la aparienciacompleta del calendario. Esta carac-terística de separar la apariencia, através de plantillas y estilos, de lafuncionalidad, es una de las noveda-des más honorables de WPF encomparación con el resto de las APIvisuales que le anteceden.

4. La extensión de marcado Template-Binding permite enlazar propiedadesde los elementos contenidos en laplantilla con propiedades del propiocalendario, de modo que la aparien-cia de lo que se visualiza esté aso-ciada a la información del control.

Es decir, cuando usted modifiqueel valor de una propiedad enlazadaen un calendario, como por ejem-plo Background, el valor asignadoautomáticamente se asignará tam-bién al de su propiedad enlazada, o

dotN

etM

anía

<<

25

Figura 2. Creando una biblioteca de controles WPF con VS 2008

Listado 1. Estilo predeterminado generado por Visual Studio para los nuevos controles personalizados.

<ResourceDictionaryxmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”xmlns:local=”clr-namespace:WpfCustomControlLibrary1”>

<Style TargetType=”{x:Type local:Calendar}”><Setter Property=”Template”><Setter.Value><ControlTemplate TargetType=”{x:Type local:Calendar}”><Border Background=”{TemplateBinding Background}”

BorderBrush=”{TemplateBinding BorderBrush}”BorderThickness=”{TemplateBinding BorderThickness}”>

</Border></ControlTemplate>

</Setter.Value></Setter>

</Style></ResourceDictionary>

Page 26: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dnm.plataforma.net<<

dotN

etM

anía

<<

26

sea el Background del Border conteni-do en la plantilla. Estos tipos espe-ciales de enlace hacen la magia demantener la apariencia del control demutuo acuerdo con las propiedadesdel propio control y permitir que estaapariencia pueda cambiar completa-mente de forma dinámica.

Pero claro, esta apariencia prede-terminada que nos pone Visual Studiocuando se define un control solo nosmuestra un rectángulo con el borde yfondo ligados a una instancia del con-trol, que en el caso de ser ubicado den-tro de una ventana, como el caso del lis-tado 2, los toma de la ventana, y el con-trol se visualiza tan anodinamente comose muestra en la figura 3.

Claro que esto no aporta nada anuestro objetivo de aproximarnos a laapariencia de la figura 1. Para ello hayque agregar algunos elementos nuevos,tanto en el código XAML de la plan-tilla como en el código C# de la claseque define al tipo Calendar. El quid delasunto está en saber qué ponemos encada parte. Es importante tener siem-pre presente que todo lo que sea puraapariencia debiera estar en el códigoXAML y que en el código C#1 solo sedebe poner el código que dé soporte ala funcionalidad deseada para el con-trol (por ejemplo, obtener todos losdías del mes para ubicarlos según losdías de la semana). Esta separación es

lo que facilita expresar que se puedahacer un cambio de apariencia (inclu-so usando terceras herramientas, comoExpression Blend) sin perturbar la fun-cionalidad del control.

Funcionalidad

Cuando usted vaya a diseñar cuál es lafuncionalidad que desea tenga un con-trol, es útil que se abstraiga de la ima-gen visual que se pueda tener, o que-rer, de éste. Por ejemplo, para operardesde C# con un tal control calenda-rio es indispensable que éste tenga unvalor DateTime que indique la fecha

sobre la que se concibe el calendario.Para ello le colocaremos una propie-dad Value de tipo DateTime. ¿Algo más?Posiblemente eventos de teclado yratón, propiedades para configuraraccesibilidad, cultura, etc. Pero sobreestas últimas no hay que preocuparse,ya que son todas propiedades que seheredan de Control.

Propiedades de dependencia

El listado 3 muestra la forma clási-ca de incluir una propiedad Value en ladefinición de un tipo cualquiera enNET.

Sin embargo, esta forma directa dedefinir propiedades, a la que estamosacostumbrados en la programación clá-sica con C#, no es suficiente en este casopara hacer valer toda la capacidad deWPF. Para poder aprovechar muchasde las bondades de WPF, como es“ligar” (binding) una propiedad conotras propiedades (del mismo o de otroscontroles) o con fuentes de datos, ypoder con ello animar el valor de unapropiedad, o establecer criterios de apa-riencia asociados con el valor de la pro-piedad (mediante triggers), es necesariodefinir las propiedades como se mues-tra en el listado 4 .

Al definir la propiedad a través deuna variable de tipo DependencyProperty(que en el código del listado 4 se regis-tra en un diccionario que incluye loscontroles personalizados), estamos

Listado 2. Utilizando el calendario en una ventana

<Window x:Class=”WpfApplication1.Window1”xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”xmlns:custom=”clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1”Title=”Window1” Height=”300” Width=”300”>

<Grid><custom:Calendar Background=”LightGray” BorderBrush=”DimGray” BorderThickness=”1”

VerticalAlignment=”Center” HorizontalAlignment=”Center”Width=”100” Height=”100”/>

</Grid></Window>

Figura 3. Aparienciapredeterminada de un controlpersonalizado con su plantilla

generada por VS.

1 Aunque usamos C#, la implementación de controles personalizados está disponible para todos los lenguajes .NET.

Listado 3. Definición de la propiedad Valueal estilo NET

public class Calendar : Control {...private DateTime value;public DateTime Value {get { return value; }set { this.value = value; }

}}

Page 27: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dnm.plataforma.net<<

dotN

etM

anía

<<

27

indicándole en este caso a WPF,mediante los parámetros del métodoRegister, que todos los objetos de tipoCalendar que se declaren en XAMLtendrán una propiedad llamada Value(primer parámetro del método Regis-ter en el listado 4), a la cual se le pue-den asignar valores de tipo DateTime(segundo parámetro que se le ha pasa-do al método Register). Para esta varia-ble, como es DependencyProperty, estándisponibles los mecanismos de binding,animations y triggers. Aunque estos tresparámetros usados en la llamada aRegister son suficientes en la mayoríade los casos, hay otras sobrecargas delmétodo. Por ejemplo, es posible utili-zar un cuarto parámetro (como en ellistado 4) que permite detallar el com-portamiento de la propiedad en ejecu-ción. El tipo PropertyMetadata es unode los aceptados en este cuarto pará-metro, por ejemplo para indicar unvalor predeterminado a asumir (en ellistado 4 se ha utilizado la fecha actual

DateTime.Today). Diversascaracterísticas se puedenin di car me dian te esteparámetro, como la for-ma en que se com-portan los enlaces(bindings), lasanimaciones,o el repinta-do del con-trol. Tambiénes posible inter-ceptar mediante delegados diferentescambios de estado de la propiedad,como el momento en que se va a asig-nar un valor o el momento en que estevalor ya fue asignado, pero analizartodas estas posibilidades se sale del espa-cio disponible para este artículo.

Tanto Control como la mayoría de lostipos de WPF tienen como clase basecomún a DependencyObject. Entre otrasfacilidades, esta clase brinda los métodosGetValue y SetValue, que le permiten asus clases herederas poder acceder direc-tamente al valor de las propiedades dedependencia en la forma siguiente:

DateTime dt = (DateTime)

myCalendar.GetValue(

Calendar.ValueProperty);

myCalendar.SetValue(

Calendar.ValueProperty,

DateTime.Now);

Sin embargo, para facilitar el uso des-de código C# y desde XAML de la pro-piedad de dependencia, en el listado 4 seagregó además la propiedad Value de

acuerdo al estilo acostumbrado en .NET.De este modo, se puede entonces hacer:

DateTime dt = myCalendar.Value;

myCalendar.Value = DateTime.Now;

Aunque no lo crea, esto es todo loque hay que definir dentro del tipoCalendar desde el punto de vista de lafuncionalidad de éste como control. Elresto queda dentro de la apariencia quese le va a asociar a éste, y es lo que severá a continuación. Claro, esto noquiere decir que no haya nada más queescribir en código C#; nos falta tam-bién definir un “convertidor de tipo”,pero esto se verá más adelante.

La aparienciaPara que la apariencia se aproxime a ladel gadget de Windows Vista (figura 1),hay que sustituir entonces el códigoXAML que Visual Studio ha generadopor defecto (listado 1 y figura 3). Hacefalta una plantilla que haga lucir al con-trol como el familiar calendario, inclu-

Listado 4. Definición de un DependencyProperty en WPF

public class Calendar : Control{...public static readonly DependencyProperty ValueProperty =

DependencyProperty.Register(“Value”, typeof(DateTime), typeof(Calendar),new PropertyMetadata(DateTime.Today));

public DateTime Value {get { return (DateTime) GetValue(ValueProperty); }set { SetValue(ValueProperty, value); }

}}

Sí, es cierto, escribir todo estole puede resultar algo incó-modo, pero la buena noticiaes que Visual Studio tiene unsnippet (propdp) que le aho-rrará unos cuantos golpes detecla.[ ]

NOTA

Page 28: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

yendo la repartición de todos los días del mes en unatabla cuyas columnas sean los días de la semana (lista-do 5 y figura 4).

En el segmento (1) del listado 5 puede observarseque se usa un Grid como panel para distribuir los ele-mentos del calendario. En esta rejilla se definen dosfilas. Una fila es para las letras que indican los días dela semana, los cuales han sido distribuidos uniforme-mente por un UniformGrid; la otra fila es un ListBoxpara mostrar los días del mes, distribuidos por sema-nas, donde cada ítem del ListBox es un UniformGrid conlos días de cada semana.

Aunque el lector puede pensar que el Grid es el panelideal para representar una tabla de elementos, su prin-cipal limitante para dar la apariencia del calendario esque en un Grid hay que indicar en qué fila y columnase encuentra cada elemento. Esto da mucho trabajocuando los elementos a ubicar no se pueden indicarexplícitamente en el XAML, sino que hay que calcu-larlos dinámicamente en ejecución, como es el caso delos días del mes, que hay que ubicarlos según el día dela semana (incluyendo los días del mes anterior que for-man parte de la primera semana y los días del messiguiente que forman parte de la última semana). Sinembargo, hay en WPF un panel que sí resulta muy útilpara este caso y es el UniformGrid (ver en listado 5 lossegmentos (2) y (5)). Éste es un panel que, al igual queel Grid, distribuye sus elementos en filas y columnas,pero la diferencia radica en que para el UniformGrid noes necesario indicar las posiciones de los elementos queél distribuye. El propio UniformGrid, al indicarle la can-tidad de columnas, reparte los elementos uniforme-mente, llenando primero la primera fila, poniendo unelemento en cada columna; luego de finalizar con laúltima columna de la fila, entonces el siguiente ele-mento se ubica en la primera columna de la segunda

dnm.plataforma.net<<

dotN

etM

anía

<<

28

Listado 5. Estilo para el calendario.

<Style TargetType=”{x:Type this:Calendar}”><Setter Property=”Template”><Setter.Value><ControlTemplate TargetType=”{x:Type local:Calendar}”><Border Background=”{TemplateBinding Background}”

BorderBrush=”{TemplateBinding BorderBrush}”BorderThickness=”{TemplateBinding BorderThickness}”>

<Border><Border.Background><LinearGradientBrush EndPoint=”1,1”><GradientStop Color=”#8fff” Offset=”0”/><GradientStop Color=”#dfff” Offset=”0.4”/><GradientStop Color=”#dfff” Offset=”0.6”/><GradientStop Color=”Transparent” Offset=”1”/>

</LinearGradientBrush></Border.Background>

(1) <Grid><Grid.RowDefinitions><RowDefinition Height=”Auto”/><RowDefinition Height=”Auto”/></Grid.RowDefinitions>

(2) <UniformGrid Columns=”7” Margin=”0,2”><TextBlock Text=”D”/><TextBlock Text=”L”/><TextBlock Text=”M”/><TextBlock Text=”M”/><TextBlock Text=”J”/><TextBlock Text=”V”/><TextBlock Text=”S”/></UniformGrid><ListBox Grid.Row=”1” BorderThickness=”0” Background=”Transparent”

SelectedItem=”{Binding Value,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}” Foreground=”{TemplateBinding Foreground}”>

(4) <ListBox.ItemsSource><Binding Path=”Value”

RelativeSource=”{RelativeSource TemplatedParent}”><Binding.Converter>

<local: DateToMonthDatesConverter/></Binding.Converter></Binding>

</ListBox.ItemsSource>(5) <ListBox.ItemsPanel>

<ItemsPanelTemplate><UniformGrid Columns=”7”/>

</ItemsPanelTemplate></ListBox.ItemsPanel>

(6) <ListBox.ItemTemplate><DataTemplate><TextBlock Name=”tb” Text=”{Binding Day}” FontSize=”9”

HorizontalAlignment=”Right” TextAlignment=”Right”/>(7) <DataTemplate.Triggers>

<DataTrigger Binding=”{Binding DayOfWeek}” Value=”Sunday”><Setter TargetName=”tb” Property=”Foreground”

Value=”OrangeRed”/></DataTrigger>

</DataTemplate.Triggers></DataTemplate></ListBox.ItemTemplate>

</ListBox></Grid></Border></Border></ControlTemplate></Setter.Value></Setter></Style>

Figura 4. Apariencia del calendario.

Page 29: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dnm.plataforma.net<<

dotN

etM

anía

<<

29

fila y así sucesivamente. Observe en elsegmento (2) del listado 5 que se ha uti-lizado un UniformGrid con 7 columnaspara las letras de los días de la semana.Más abajo, segmento (5) del listado 5, sele indica al ListBox que utilice un Uni-formGrid, también de 7 columnas, paraubicar cada ítem del ListBox, es decir paraque vaya ubicando todos los días porcolumnas de a 7.

Una vez que ya el código XAML dela plantilla se encarga de repartir los ele-mentos en su lugar, solo queda finalmenteenlazar esto con la fecha representada enla propiedad Value de nuestro Calendar.Se ha escogido como elemento contene-dor de los días del mes a un ListBox por-que necesitamos usar un control que per-mita seleccionar un elemento entre varios(ese elemento seleccionado es el día quesuele aparecer destacado cuando se mues-tra e interactúa con un calendario). Parahacer que el ListBox tenga seleccionadoel día actual entre el resto de los días delmes, se podía haber utilizado la extensiónde marcado TemplateBinding del modo:

<ListBox SelectedItem=

”{TemplateBinding Value}” ...>

Esto provocaría que, automática-mente, cuando cambiara la propiedadValue en el calendario la selección delListBox también cambiara en corres-pondencia, pero… ¿y a la inversa? Tem-plateBinding es un enlace que ocurre enun solo sentido, el de cambiar la selec-ción del ListBox al cambiar la propiedadValue. Para lograr que también al cam-biar la selección del ListBox se produzcaun cambio en la propiedad Valuedel obje-to calendario es necesario indicar el enla-ce de manera más verbosa (segmento (3)del listado 5). Note que el enlace se espe-cifica mediante el uso de Binding con lapropiedad Value del elemento que seobtiene de la fuente relativa Templated-Parent, o sea el elemento al cual se le estéaplicando la plantilla. Hasta aquí se tie-ne lo mismo que con TemplateBinding.La diferencia radica en que al hacerlo conBinding se puede además especificar la

dirección del enlace (en este caso, decirque es en ambos sentidos haciendoMode=TwoWay). O sea, de este modo al cam-biar cualquiera de las propiedades Value,sea la del propio control o la del Selec-tedItemdel ListBox contenido en su plan-tilla, la otra debe actualizarse con el mis-mo valor.

Pero el lector puede haber notado queestá faltando algo por explicar. La pro-piedad Value en el control lo que tiene esuna fecha, pero los ítems con los que sequiere rellenar el ListBoxdeben ser todoslos números de los días del mes de dichafecha, unidos a los días del mes anterior ydel mes posterior que hagan falta paracompletar la primera y última semana...

Convirtiendo una fecha entodas las fechas a poner en el calendario del mes

La propiedad ItemsSource con la que se“alimentan” los ítems a visualizar por elListBox, es de tipo IEnumerable, por tan-to mediante esta propiedad se puede“rellenar” el ListBox asociándole unacolección física, o asociándole el resulta-

do de una iteración (que es lo que hare-mos en este caso). Observe en el listado5 (segmento (4)) que se ha puesto sobreesta propiedad un Binding idéntico al quese puso sobre la propiedad SelectedItem(segmento (3)), solo que éste está defini-do de forma explícita, no se aplica enambos sentidos, y además tiene indicadoun convertidor (es decir, un valor asocia-do a su propiedad Converter). Este valorque se asocia a la propiedad Converter esel nombre de un método (DateToMonth-DatesConverter en este ejemplo) que seráel encargado de convertir el valor de lapropiedad Value (un DateTime en esteejemplo) en un IEnumerable, que produ-ce en este caso los valores de tipo Date-Time correspondientes a todos los días delmes en cuestión, incluyendo los días delmes anterior que completan la primerasemana y los días del mes posterior quecompletan la última semana (ver códigoC# del listado 6).

Para definir estos convertidores hayque implementar los dos métodos Con-vert y ConvertBack de la interfaz IVa-lueConverter. Estos son los que hacenla conversión en ambos sentidos. Eneste caso, ConvertBack se ha implemen-

Listado 6. Conversión de una fecha en un iterador que nos dé todas las fechas del mes de esa fecha.

public class DateToMonthDatesConverter : System.Windows.Data.IValueConverter {

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {

DateTime dt = (DateTime) value;return GetDatesOfTheMonth(new DateTime(dt.Year, dt.Month, 1));

}

private IEnumerable<DateTime> GetDatesOfTheMonth(DateTime firstDay){int dayOfWeek = (int)firstDay.DayOfWeek; // Convirtiendo enumerativo en enteroDateTime current = firstDay.AddDays(-dayOfWeek - 1); // Para poder rellenar con los días del mes anteriorint daysInMonth = DateTime.DaysInMonth(firstDay.Year, firstDay.Month) + dayOfWeek;for (int j = 0; j < daysInMonth + 7 - (daysInMonth % 7); j++) {current = current.AddDays(1);yield return current;

}} public object ConvertBack(object value, Type targetType, object parameter,

CultureInfo culture) {return null; // No interesa conversión en este sentido, la práctica en WPF es devolver null

}}

Page 30: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

tado como que devuelve null, ya queno se desea ninguna conversión en esesentido.

Para completar la apariencia delcalendario, en el segmento (6) del listado5 se ha agregado una plantilla de datosque define la apariencia que tendrá cadadía del mes. Observe que esta plantilla hasido asignada a la propiedad ItemTempla-te del ListBox, lo cual indica que estaplantilla será aplicada para cada ítem delListBox. Y observe también que comocada ítem es de tipo DateTime, los enlaces(bindings) de esta plantilla se pueden enla-zar directamente con las propiedades deDateTime (Day, DayOfWeek):

A la plantilla se le ha incorporadoentonces un DataTrigger (segmento (7)del listado 5) que se activa cuando la pro-piedad DayOfWeekde la fecha tome el valor“Sunday”. Cuando esto ocurre, el Triggerindica a su vez a través de un Setter queel color (Foreground) del bloque de textoque muestra al día (de nombre tb) debeser OrangeRed. De esta manera se lograque los días que correspondan a domin-

go aparezcan distinguidos con un colordiferente en el calendario (figura 4).

Una nota finalAunque la plantilla que define la apa-riencia del control Calendar se apoya enel uso de convertidores, y éstos a su vezse programan en C#, no se puede consi-derar que este código forma parte de lafuncionalidad del control. De hecho, eneste ejemplo se necesita este convertidordebido a la apariencia que se ha escogidopara mostrar el calendario (y que quieremostrar todas las fechas del mes al estilodel gadget de Windows). De haber esco-gido un simple TextBox para que el usua-rio escribiese una fecha, o incluso un Text-Block si solo se quisiese visualizar la mis-ma, hubiese sido necesario un converti-dor diferente (o puede que no hubiesesido necesario ninguno). De momentoestos convertidores vienen a suplir unacarencia en el poder expresivo declarati-vo de XAML, sobre lo cual trataremos enun próximo artículo.

Conclusiones

Con lo expuesto hasta aquí hemosquerido darle una panorámica decómo se definen algunos de los ele-mentos básicos para construir uncontrol personalizado desde cero.Siempre recuerde que todo comien-za por escoger la clase base más apro-piada para el control. Luego, esimportante abstraerse de su partevisual para definir las propiedades dedependencia y demás miembros quedefinen la funcionalidad que el con-trol tendrá cuando se opere con éldesde código. Y para finalizar, se defi-ne en generic.xaml la plantilla pordefecto que tendrá el control, utili-zando las novedosas bondades gráfi-cas de WPF.

Claro que comparado con el gad-get Calendario de Windows Vista dela figura 1, este control aún estáincompleto. Habría que añadir unespacio para mostrar y seleccionartanto el mes como el año y comple-tar la funcionalidad esperada de uncalendario (en el que se puede pasarde mes y de año). Pero no hay espa-cio para más. Esperamos que lo mos-trado le sirva de impulso al lector paraterminar por su cuenta este calenda-rio, continuando en este mundo fas-cinante que es WPF. Incluso, aníme-se a animarlo, colóquele un efecto depaso de páginas del almanaque con unefecto 3D como el que se desarrollóen el artículo [3].

dnm.plataforma.net<<

dotN

etM

anía

<<

30

ReferenciasHernández Yamil, Sierra Iskander, Del Valle Mario, Katrib Miguel. Cómo definirnuestros propios paneles personalizados en WPF, dotNetManía No. 35, marzo 2007.

Del Valle Mario, Sierra Iskander, Hernández Yamil, Katrib Miguel. Entran-do en la tercera dimensión, dotNetManía No. 37, mayo 2007.

Sierra Iskander, Del Valle Mario, Hernández Yamil, Katrib Miguel. Paso depáginas en 3D con WPF, dotNetManía No. 38, junio 2007.

Del Valle Mario, Sierra Iskander, Hernández Yamil, Katrib Miguel. Controles per-sonalizados en WPF: un scroll circular, dotNetManía No. 40, septiembre 2007.

[1]

[4]

[2]

[3]

<DataTemplate><TextBlock Name=”tb” Text=”{Binding Day}”

FontSize=”9”HorizontalAlignment=”Right”TextAlignment=”Right”/>

<DataTemplate.Triggers><DataTrigger Binding=”{Binding DayOfWeek}”

Value=”Sunday”><Setter TargetName=”tb”

Property=”Foreground”Value=”OrangeRed”/>

</DataTrigger></DataTemplate.Triggers></DataTemplate>

Esta característica de separar la apariencia, através de plantillas y estilos, de la funcionalidad,

es una de las novedades más honorables de WPF en comparación con el resto de

las API visuales que le anteceden

Page 31: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 32: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Qué es un manejador de eventos,y su relación con los flujos de trabajo

Windows es un sistema operativo que funciona abase de eventos: cada vez que un usuario interactúacon Windows, éste lanza internamente un eventopara anunciar que algo ha ocurrido. Un desarrolla-dor puede capturar el evento y crear software quereaccione de una forma específica. SharePoint es unsistema basado en tecnología Windows, y por lo tan-to permite capturar eventos (un documento ha sidosubido a una librería, un elemento ha sido elimina-do de una lista, etc.), permitiendo crear software quetome las acciones apropiadas.

El concepto de manejador de evento fue introdu-cido en la versión 2003 de SharePoint y fue utilizadoprincipalmente para crear flujos de trabajo. Con la apa-rición de Workflow Foundation y su integración conSharePoint 2007, esta función ha desaparecido mayo-ritariamente; a pesar de esto, el sistema de eventos den-tro de SharePoint ha sido ampliado considerablementey permite realizar tareas que no son posibles de imple-mentar con los flujos de trabajo.

Los nuevos eventos permiten controlar prácti-camente todas las acciones que ocurren dentro deSharePoint: agregar, modificar o eliminar camposen elementos de listas, librerías, Webs y sitios. Pro-

bablemente la mayor diferencia con los flujos de tra-bajo es que los eventos pueden ser lanzados antes deque la acción se ejecute, lo que no es posible (o difí-cil de programar) con flujos; además, las modifica-ciones en la infraestructura de Webs y sitios no sondetectadas por Workflow Foundation pero sí por lainfraestructura de los manejadores.

Y hay una diferencia más: un manejador de even-tos puede iniciar un flujo de trabajo, mientras quelo contrario no es posible. Al otro lado de la mone-da, los manejadores de eventos tienen muy pocasposibilidades para interactuar con el usuario: son ini-ciados automáticamente, sin que el usuario puedahacerlo manualmente, no es posible detenerlos paraaceptar configuración de datos, y los desarrollado-res deben tomar todas las precauciones necesarias sialgo no funciona correctamente, pues no tienenmecanismos de protección como los que tienen losflujos de trabajo.

Arquitectura y nuevas posibilidadesLos manejadores de eventos de SharePoint 2003eran aplicables solamente a librerías de documen-tos, imágenes y formularios, y estaban restringidosa los eventos de proteger/desproteger, copiar, eli-minar, insertar y modificar o cambiar el nombre.

Manejadores de eventos en SharePoint 2007Los flujos de trabajo no siempre son necesarios para hacer

que las cosas funcionen bien

sharepoint

Gustavo Vélez esingeniero mecánico yelectrónico, especiali-

zado en el diseño,desarrollo e imple-

mentación de softwa-re (MCSD) basado entecnologías de Micro-

soft, especialmenteSharePoint. Es creador

y webmaster dehttp://www.gavd.net/servers, y trabaja como

senior developer enWinvision

(http://www.winvision.nl)

Los manejadores de eventos de SharePoint 2007 son más que una heren-cia de la versión 2003: en WSS y MOSS 2007 han sido ampliados y enri-quecidos considerablemente. Ahora pueden ser utilizados a lo largo y anchodel sistema, y su modelo de objetos ha sido mejorado en diferentes direc-ciones. Los manejadores de eventos permiten realizar algunas de las tare-as que los flujos de trabajo están en capacidad de ejecutar, pero de una for-ma mucho más sencilla y efectiva, e inclusive pueden anticiparse a eventos,algo que es difícil de realizar con flujos de trabajo.

Gustavo Vélez

Page 33: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Además, solamente un manejador deeventos se podía utilizar en cada librería.

En SharePoint 2007 (WSS yMOSS), hay cuatro clases que ofreceneventos:1. La clase SPEmailEventReceiver, con

un evento (EmailReceived).2. La clase SPItemEventReceiver, con

eventos para atrapar inserciones(ItemAdding/ItemAdded), eliminacio-nes (ItemDeleting/ItemDeleted), cam-bios (ItemUpdating/ItemUpdated), adi-ción o eliminación de archivosadjuntos (ItemAttachmentAdding/Added, ItemAttachmentDeleting/Dele-ted), protección y desprotección(ItemCheckingIn-Out/CheckedIn-Out,ItemUncheckingOut/UncheckedOut),cambio de sitio (ItemFileMoving/Moved) y conversión de archivos(ItemFileConverted).

3. La clase SPListEventReceiver, parasucesos a nivel de campos de listas(FieldAdding/Added, FieldDeleting/Deleted, FieldUpdating/Updated).

4. La clase SPWebEventReceiver, paraeventos en sitios y Webs (SiteDele-ting/Deleted, WebDeleting/Deleted,WebMoving/Moved).

Como se puede observar, en losnombres de los eventos hay dos tiposprincipales:• Eventos sincrónicos, cuyo nombre

termina en “ing”. Ocurren antes deque la acción del evento sea imple-mentada, suspendiendo el procesohasta que el código del manejador hasido completamente ejecutado. Estopermite modificar la acción, porejemplo, para cancelar la modifica-ción de un documento antes de queel cambio se realice.

• Eventos asincrónicos, cuyo nombretermina en “ed”, que ocurren despuésde que la acción ha tomado efecto.Esta era la única posibilidad con Sha-rePoint 2003; en 2007, de igualmanera, el evento no se ejecuta inme-diatamente, sino que puede tener unretraso de hasta algunos segundos.

Note que no existen eventos paracuando se agregan o modifican sitios oWebs. También es importante mencio-

nar que los valores de las propiedadesBefore y After de los eventos en libreríassiempre mostrarán los valores correctosen las librerías, pero en las listas sola-mente es preservado el valor After.

ProgramaciónLos manejadores de eventos para Share-Point 2007 son programados comolibrerías de clases de código manejado en.NET 2.0 o superior utilizando C# oVisual Basic. El siguiente ejemplo (lista-do 1) muestra cómo crear un manejadorsencillo, que agrega un vínculo en una lis-ta de vínculos cada vez que un documentoes añadido a una librería de documentos.El ejemplo es solamente para mostrar laforma de programación, y para utilizar-lo como código de producción deberíaser ampliado y mejorado.

Inicialmente, debemos crear unabiblioteca de clases en Visual Studio2005, utilizando un nombre único (porejemplo, CreadorVinculos), y asignar unnombre adecuado a la clase creada pordefecto (digamos ClaseCreadorVinculos).Asimismo, hay que agregar una refe-rencia a Windows SharePoint Services(Microsoft.SharePoint.dll) y es conve-niente agregar la sentencia de impor-tación correspondiente (mediante usingen C# o Imports en Visual Basic) en elcódigo.

La nueva clase debe heredar de unade las clases para manejadores de even-tos; en el caso del ejemplo, de SPIte-mEventReceiver. Todos los métodos dela clase base pueden ser sobrescritos,incluso más de uno si es necesario. Enel ejemplo se sobrescribe el métodoItemAdded.

El parámetro properties contienetoda la información sobre el elementoque ha lanzado el evento: una tabla hashcon los valores de las propiedades antesy después del evento, el contexto deSharePoint, información sobre el usua-rio (identificador, nombre, login), la lis-ta (identificador, elemento, título), sitioy Web.

Como los manejadores de eventosno se ejecutan bajo el contexto de Sha-rePoint o IIS, no es posible utilizar elarchivo web.config del sitio para guar-

dar información que pueda ser cambia-da fuera del programa, como es desea-ble para el nombre de la lista de víncu-los del ejemplo; pero el archivo machi-ne.config sí se puede utilizar para talefecto. Este archivo no posee una sec-ción AppSettings por defecto, pero esposible agregar una si es necesario. Porlo tanto, en el fichero machine.config(C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config) añadi-mos una nueva sección debajo del cie-rre del último elemento (</configSec-tions>):

El valor puede ser leído desde elcódigo de la forma tradicional:

Finalmente, utilizando el paráme-tro properties es posible obtener unareferencia a la librería (SPList) en don-de se ha lanzado el evento, y crear el

dotN

etM

anía

<<

33

dnm.sharepoint<<

using System;using System.Collections.Generic;using System.IO;using Microsoft.SharePoint;

namespace CreadorVinculos{public class ClaseCreadorVinculos :

SPItemEventReceiver{public override void ItemAdded(

SPItemEventProperties properties)

{base.ItemAdded(properties);

}}}

<appSettings file = “”><add key = “NombreListaVinculos”

value = “NombreLista” /></appSettings>

base.ItemAdded(properties);string miListaVinculos = System.Configuration.ConfigurationSettings.AppSettings[“NombreListaVinculos”];

Listado 1

Page 34: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

34

dnm.sharepoint<<

vínculo en la lista de eventos. El códi-go completo del método sobrescrito semuestra en el listado 2.

En el código, luego de leer el nom-bre de la lista de vínculos que se haguardado en el archivo machine.config,se crea una instancia de SPSite usandolas propiedades del evento. Luego decrear una instancia de la lista de even-tos, se le añade un nuevo elemento y seconfigura su URL para que apunte aldocumento recién creado en la libreríade documentos.

Como se ha indicado al principio,las posibilidades de interacción con elusuario son muy limitadas. El paráme-tro properties tiene un método Error-Message que se puede utilizar solamen-te en eventos sincrónicos cuando elcódigo cancela la acción iniciada paraenviar un mensaje al usuario. Esto crea

el problema de trasladar la informaciónde los errores hacia el exterior. Existenvarias formas de hacerlo: principal-

mente escribir en el Visor de sucesos oen un archivo. En ambos casos, es nece-sario tener en cuenta que el usuariodebe tener suficientes derechos paraescribir (el usuario utilizado es el quese ha configurado en el Grupo de apli-caciones de IIS para el sitio de Share-Point). Las líneas de código en el blo-que catch del ejemplo graban en unarchivo el mensaje de error cuando ocu-rre algo inesperado.

Los ensamblados que contienenmanejadores de eventos tienen que serinstalados en el GAC (Global AssemblyCache), por lo que es necesario firmar-los con un nombre seguro. Para ello,en la pantalla de propiedades del pro-yecto de Visual Studio vamos a “Firma”

| “Firmar el ensamblado”, en “Selec-cione un archivo de clave de nombreseguro” seleccionamos “Nueva”, defi-nimos un nombre en “Nombre dearchivo de clave” (por ejemplo, Crea-dorVinculos), deseleccionamos “Prote-ger mi archivo de clave mediante con-traseña” y generamos el proyecto. Elensamblado generado puede ser copia-do directamente al GAC, o se puedeutilizar la herramienta gacutil para ello.

Instalación y utilizaciónSharePoint no dispone de pantallas deadministración para configurar mane-jadores de eventos, así que la formarecomendada para instalación es utili-zar una solución de SharePoint quecopie la DLL en el GAC, junto con unacaracterística que configure la libreríao lista. También es posible usar elmodelo de objetos de SharePoint paraconfigura el manejador.

Una característica para instalar elmanejador del ejemplo consta de dosarchivos: uno llamado Feature.xml, conla definición de la característica en sí, yotro llamado Elementos.xml para iden-tificar sus componentes. Entonces cre-amos dos archivos con estos nombresen un nuevo directorio llamado Crea-dorVinculosCaracteristica bajo C:\Archivos de programa\Archivos comunes

\Microsoft Shared\web server exten-

sions\12\TEMPLATE\FEATURES. El conte-nido del archivo Feature.xml se pre-senta en el listado 3, y el de Elemen-tos.xml en el listado 4. En el listado3, “GUID” debe ser sustituido por unidentificador global único, que pue-de ser obtenido mediante la utilidadGuidGen.exe.

public override void ItemAdded(SPItemEventProperties properties){

SPSite miSite = null;SPWeb miWeb = null;base.ItemAdded(properties);

try{

string miListaVinculos = System.Configuration.ConfigurationSettings.AppSettings[“NombreListaVinculos”];

miSite = new SPSite(properties.SiteId);miWeb = miSite.OpenWeb();SPList miLista = miWeb.Lists[miListaVinculos];SPListItem miVinculo = miLista.Items.Add();miVinculo[“URL”] = properties.WebUrl + “/” +

properties.ListItem.Url + “, “ + properties.ListItem.Name;miVinculo.Update();

}catch(Exception ex){

TextWriter miEscritor = new StreamWriter(@”c:\ManejadorEventosError.txt”);miEscritor.WriteLine(ex.ToString());miEscritor.Close();

}finally{

if (miWeb != null)miWeb.Dispose();

if (miSite != null)miSite.Dispose();

}}

<Feature Scope=”Web”Title=”Manejador Eventos CreadorVinculos””Id=”GUID”xmlns=”http://schemas.microsoft.com/sharepoint/”>

<ElementManifests><ElementManifest Location=”Elementos.xml”/>

</ElementManifests></Feature>

Listado 3

Listado 2

Page 35: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

35

dnm.sharepoint<<

En el listado 4, el valor de ListTem-plateId es el número asignado a la lista devínculos por SharePoint, y se puedeencontrar en la respectiva definiciónCAML de la lista (en el archivo C:\Archi-vos de programa\Archivos comunes\Micro-

soft Shared\web server exten-

sions\12\TEMPLATE\FEATURES\Links-

List\ListTemplates\Links.xml, para la lis-ta del ejemplo). El tipo de evento es el quese ha definido en el código (ItemAdded), yel número de secuencia indica el orden enel que son lanzados los diferentes even-tos: de 1.000 a 9.999 están reservados porSharePoint para sus propios eventos, asíque es necesario utilizar un valor superioral límite máximo. El elemento Assemblyes configurado con los parámetros delensamblado utilizado: el nombre delensamblado, su versión y cultura y la cla-ve pública, que se puede encontrar con laherramienta sn.exe de Visual Studio (uti-lizando el parámetro -T). Finalmente, esnecesario indicar el nombre de la clase quese va a utilizar.

Luego de crear los dos archivos enel directorio indicado, la característicase puede instalar utilizando la herra-mienta de administración de SharePointcon la sintaxis:

stsadm -o installfeature -filename

CreadorVinculosCaracteristica\Feature.xml

Y se puede activar utilizando la pan-talla de administración del sitio corres-pondiente, o por medio de la mismaherramienta con la sintaxis:

stsadm -o activatefeature -filename CreadorVinculosCaracteristica\Feature.xml –url http[s]://NombreServidor/NombreSitio

Como el modelo de objetos de Sha-rePoint dispone de todas las clases ymétodos necesarios para configurarun manejador de eventos, la segundaforma para instalarlos es creando unpequeño programa. Además, maneja-dores para Webs o sitios tienen queser instalados de esta manera, pues noes posible hacerlo con características.La aplicación de consola que se pre-senta en el listado 5 configura elmanejador del ejemplo en una lista(NombreDeLista), después de que laDLL haya sido instalada manualmen-te en la GAC.

<Elements xmlns=”http://schemas.microsoft.com/sharepoint/”><Receivers ListTemplateId=”103”><Receiver><Name> Manejador Eventos CreadorVinculos </Name><Type>ItemAdded</Type><SequenceNumber>10000</SequenceNumber><Assembly>CreadorVinculos, Version=1.0.0.0, Culture=neutral,

PublicKeyToken= 96290f904372ba8a </Assembly><Class> CreadorVinculos.ClaseCreadorVinculos </Class><Data></Data><Filter></Filter>

</Receiver></Receivers>

</Elements>

Listado 4

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SharePoint;

namespace InstallTasksCleaner

{

class Program

{

static void Main(string[] args)

{

SPSite miSitio = new SPSite(“http[s]://NombreServidor”);

SPWeb miWeb = miSitio.OpenWeb();

SPList miLista = miWeb.Lists[“NombreDeLista”];

SPEventReceiverDefinitionCollection misReceptoresEventos =

miLista.EventReceivers;

SPEventReceiverDefinition miEvento = misReceptoresEventos.Add();

miEvento.Assembly = “CreadorVinculos, Version=1.0.0.0,

Culture=neutral, PublicKeyToken= 96290f904372ba8a “;

miEvento.Name = “Manejador Eventos CreadorVinculos”;

miEvento.Type = SPEventReceiverType.ItemAdded;

miEvento.SequenceNumber = 10000;

miEvento.Class = “CreadorVinculos.ClaseCreadorVinculos”;

miEvento.Update();

foreach (SPEventReceiverDefinition miDef in misReceptoresEventos)

{

Console.WriteLine(miDef.Name);

}

}

}

}

Listado 5

Page 36: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

36

dnm.sharepoint<<

Cada lista o librería dispone de una colección dereceptores de eventos (SPEventReceiverDefinitionCo-llection), a la que se le puede añadir uno del tipo SPE-ventReceiverDefinition, y luego configurar sus pro-piedades. Note la similitud entre estas líneas de códi-go y las utilizadas en la característica; ambos proce-sos utilizan el mismo código básico en la máquina deSharePoint.

Luego de instalado, un usuario no puede vercómo funciona el manejador de eventos, sino quesolamente puede notar sus efectos (si es que son visi-bles). La figura 1 muestra la librería en la que se haconfigura el manejador y el efecto en la lista de vín-culos luego de agregar un documento. La configu-ración de la lista de vínculos por medio de machi-ne.config es una forma fácil y rápida de cambiar lalista cuando sea necesario. Hay que tener en cuentaque el código del ejemplo es muy sencillo, y que tan-to la librería de documentos como la lista de víncu-los tienen que estar en el mismo sitio; pero modifi-carlo para hacerlo funcionar de cualquier modo dese-ado es fácil, y el modelo de objetos de SharePointprovee todas las herramientas para programar lo quesea necesario.

Cuando se utilizan manejadores de eventos, es muyimportante tener en cuente el impacto del códigosobre la estabilidad y rendimiento de los servidoresde SharePoint. Por ejemplo, crear un manejador querecorra listas con grandes cantidades de elementos es

relativamente fácil de programar, pero si el evento quelo lanza ocurre frecuentemente, se verá disminuir elrendimiento del sistema hasta agotar los recursos delos servidores. Cuando sea necesario utilizar un esce-nario de este tipo, probablemente sea mejor crearalgún mecanismo de almacenamiento en caché, ohacer que el proceso se mantenga en estado de laten-cia hasta que el sistema tenga menos carga de proce-samiento.

Conclusiones

Los manejadores de eventos han existido en Sha-rePoint desde hace ya algún tiempo, y en la últimaversión se han ampliado no solamente en su cam-po de acción, sino también en las posibilidades queofrecen a los desarrolladores y en el alcance de suutilización. Los manejadores pueden sustituir enalgunos casos a flujos de trabajo, pero debido a susreducidas capacidades de interacción con los usua-rios, su ámbito de aplicación se dirige más hacia laautomatización de tareas rutinarias dentro de Sha-rePoint. Las posibilidades de utilización son prác-ticamente ilimitadas, y su facilidad de programa-ción e instalación los convierten en una de las mejo-res herramientas a disposición de los desarrollado-res de SharePoint.

Figura 1

Page 37: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 38: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Si vamos a comenzar a hablar de componentes gené-ricos, es casi obligado empezar por el servicio de acce-so a datos. Nada tan repetido, tan modificado, tan“versionado”… ni tan solicitado. Y aun cuando exis-ten muchos ejemplos completos en Internet acercade mecanismos y componentes de acceso a datos,realmente es probable que ninguno cumpla exacta-mente las necesidades de un caso particular.

Hasta la propia Microsoft, al comenzar con sugrupo PAG, comenzó sus publicaciones precisa-mente con un servicio de acceso a datos, que fuedenominado DAAB (Data Access ApplicationBlock). DAAB forma parte hoy de EnterpriseLibrary, que podrán encontrar navegando un pocopor los sitios de MSDN. No voy a caer en comen-tar que para mí está mal hecho, porque posible-mente me tiraría tierra encima, ya que fui uno delos que aportó para la idea y el diseño, pero sí decirque yo lo hubiese hecho algo distinto.

Como en estas publicaciones pretendo no solo“dar las cosas casi listas para usar”, sino también lle-varos por los caminos del aprendizaje, voy a montarotro, que se parece bastante al que solemos usar.

¿Qué necesitamos?

Hagamos una lista de lo que nos hace falta paraoperar adecuadamente con datos:

• Conectarnos al motor.–Administrar las conexiones.

• Obtener datos del mismo.–Un valor único.–Un conjunto de valores de una sola fila.–Un conjunto de filas.

• Actualizar información.–Insertar.–Actualizar.–Eliminar.–Ejecutar procesos.

• Operar dentro de transacciones.

Y otra lista de lo que deberíamos tener en cuen-ta para tener un componente que realmente seaefectivo y completamente funcional:

• Que disponga adecuadamente de los recursos.• Que optimice en rendimiento y escalabilidad.• Que informe de sus acciones de ser necesario,

para permitirnos evaluar la funcionalidad de unaaplicación y detectar sus cuellos de botella.

• Que pueda operar con distintas versiones debases de datos.

Componentes de uso generalAcceso a datos

plataforma.net

Daniel Seara es mentorde Solid Quality Mentors

y director del área dedesarrollo .NET. Es MVP

desde 2003 y ponentehabitual de INETA y

Microsoft.

Comenzamos aquí el desarrollo del primer componente de funcionali-dad compleja. Dada la importancia que tiene a la hora de desarrollaraplicaciones, comenzaremos con el acceso a datos, explicando según sedesarrolla los fundamentos y consideraciones en los que basa, para quese pueda usar, modificar o repensar completamente y que os pueda serrealmente útil.

No os ilusionéis. No hay modo queesto pueda desarrollarse en unasola nota. Serán, espero, dos.[ ]

NOTA

Daniel Seara

Page 39: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Consideraciones de diseño

Claro, llegados a este punto, comienzan las discusionesacerca de la versatilidad de este tipo de componentes, la“generalización” del código, la funcionalidad contravarias plataformas versus la especificidad de operar apro-vechando las mejores características de un motor de basede datos específico, etc.

Este tipo de consideraciones me persiguen des-de la época de DAO (estoy hablando de la época enque Visual Basic tenía 7 disquetes ☺) o RDO oADO (que todavía era huérfano, hasta que lo adoptó.NET). Bajo esas consideraciones, mucha gentecomenzó grandes desarrollos con ODBC basadosen la premisa “funciona con cualquier motor”. Locual no estaba del todo mal, pero se me hace quees “nivelar hacia abajo”… además de que eso no estan cierto.

Pero, por otra parte, me recuerdo colaborandohace años con una empresa que necesitaba codificarun sistema para que funcionase con al menos dos delas grandes bases de datos, pero una no retornabaregistros si se ejecutaban procedimientos almacena-dos, lo cual alteraba en gran medida la funcionalidadde la aplicación.

Con esto quiero decir que generalizar es bueno,pero sin exagerar, y que a veces, el resultado no sirveen todos los casos.

Volvamos a ODBCNo, no. No voy a usar ODBC. Quiero que volvamosa ODBC para considerar cómo funciona e imple-mentar algo similar. ODBC es la primera implemen-tación de “buenas intenciones”: permitir a desarro-lladores escribir aplicaciones que interactúen con dis-tintos sistemas propietarios.

ODBC no es más que un conjunto de estándarespara que las empresas de bases de datos implementenciertas funcionalidades a las cuales ODBC pueda acce-der, y por el otro lado, un conjunto de llamadas están-dar, para que los programadores “hablen” con las basesde datos siempre de la misma manera que normal-mente llamamos API. O sea, manteniendo una inter-faz común, desentendernos de cómo se implementainternamente; como un conector USB.

Pero hagámoslo en .NETEste tipo de implementaciones en .NET se basan endos características de la plataforma: pueden ser interfa-ces o pueden ser clases que obligatoriamente debanheredarse, comúnmente denominadas abstractas (Mus-tInherit o abstract, dependiendo del lenguaje de pro-gramación).

dotN

etM

anía

<<

39

dnm.plataforma.net<<

Public MustInherit Class BaseDataServerProtected Sub New()End Sub

Protected ReadOnly Property Connection() As _System.Data.Common.DbConnectionGetEnd Get

End Property

Public Property Transaction() As _System.Transactions.TransactionGetEnd GetSet(ByVal value As System.Transactions.Transaction)End Set

End Property

Public Function Execute(ByVal procedureName As String,_ByVal ParamArray parameters As Object()) As Integer

End Function

Public Function GetValue(ByVal procedureName As String,_ByVal ParamArray parameters As Object()) As Object

End Function

Public Function GetValues(ByVal procedureName As String,_ByVal ParamArray parameters As Object()) As Object()

End Function

Public Function GetTable(ByVal procedureName As String,_ByVal ParamArray parameters As Object()) _

As System.Data.DataTableEnd Function

Public Function GetReader(ByVal procedureName As String,_ByVal ParamArray parameters As Object())

As System.Data.Common.DbDataReaderEnd FunctionPublic Sub Fill(ByVal procedureName As String, _ByRef destination As IEnumerable, _ByVal ParamArray parameters As Object())

End Sub

Public Function ExecuteSQL() As IntegerEnd Function

Public Function GetReaderFromSQL(ByVal sql As String)_As System.Data.Common.DbDataReader

End Function

Public Function GetValuesFromSQL(ByVal sql As String)_As Object()

End Function

Public Function GetValueFromSQL(ByVal sql As String)_As Object

End Function

Public Sub FillFormSQL(ByVal sql As String,_ByRef destination As IEnumerable)

End Sub

Public Function GetTableFromSQL(ByVal sql As String)_As System.Data.DataTable

End FunctionEnd Class

Listado 1. Miembros de la clase base abstracta.

Page 40: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

De esta manera, se puede definir toda la interfaz deutilización (la API), a ser llamada desde las aplicacionesque usen este componente; pero en cada caso la imple-mentación será específica por cada clase concreta.

DiseñemosBásicamente, lo que necesitamos en nuestra clase abs-tracta se muestra en el diagrama de la figura 1. Y el

detalle de las firmas de cadamiembro se presenta en ellistado 1.

Algunos comentarios

• Estoy dejando métodospara ejecutar sentenciasSQL simplemente porquesiempre alguien se quejaque no los tiene. Lo lógi-co, seguro y óptimo encuanto a ejecución es quetodo se realice usando pro-cedimientos almacenados.Tanto es así, que en la ver-sión “real” dichos métodosestán decorados con elatributo Obsolete, como semuestra:

• Las propiedades Connection y Transaction sonaccesibles solo por esta clase base y aquellas quela hereden; de esta forma, nadie externamenteaccede “en directo” a la base de datos.

Codificando lo abstractoComencemos pues a codificar lo que implementa laclase base.

La cadena de conexión

Vamos a obtener la misma a partir de dos posi-bles orígenes: o el programador especifica la cadenade conexión cuando crea una instancia, o indica elnombre de la entrada correspondiente en el archivode configuración.

Dado que esta es una clase abstracta, no puedecrearse una instancia directamente. Ese trabajo seráde las clases que hereden de ella. Sin embargo, sí pode-mos almacenar dicha cadena en esta clase base.

Protected mConnectionString As String

Ahora, dependiendo de qué motor de bases de datosse trate, podremos utilizar diferentes objetos Connec-tion (SqlConnection, OracleConnection, OleDbConnec-tion, etc.). Entonces nuestra clase abstracta manipularála conexión como System.Data.Common.DbConnection, yle encargará a quienes hereden de ella que se respon-sabilicen de la creación de la instancia. Eso se logra conun método que tenga definición diferida (o sea, quedeba definirse en las clases que heredan de ésta). Dichométodo se declara con MustOverride (listado 2).

Algo similar, pero sin depender de las clases here-deras, haremos con la transacción del listado 3.

dotN

etM

anía

<<

40

dnm.plataforma.net<<

Private mTransaction As System.Transactions.TransactionPublic ReadOnly Property Transaction() As _System.Transactions.TransactionGetIf mTransaction Is Nothing ThenmTransaction = New System.Transactions.CommittableTransactionEnd IfReturn mTransactionEnd Get

End Property

Este tipo de manejo transaccional es ópti-mo siempre que estemos tratando conbases de datos que entiendan el espaciode nombres System.Transactions, comoes el caso de SQL Server 2005. En otroscasos, tal vez deberá utilizarse los objetosTransaction propios de cada clase de cone-xión a base de datos, o implementar Enter-priseServices, si se requiere manipular dis-tintos orígenes de datos.

[ ]NOTA

Figura 1. Clase base abstracta

<Obsolete(“Sería mejor que uses un procedimiento almacenado”)>_Public Function ExecuteSQL() As IntegerEnd Function

Protected MustOverride Function InternalCreateConnection() As _System.Data.Common.DbConnection

Private mConnection As System.Data.Common.DbConnection = NothingProtected ReadOnly Property Connection() As _System.Data.Common.DbConnectionGet

If mConnection Is Nothing ThenmConnection = internalCreateConnection()

End IfReturn mConnection

End GetEnd Property

Listado 2

Listado 3

Page 41: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

41

dnm.plataforma.net<<

De los comandos a ejecutarUno de los temas importantes acerca dela utilización de los comandos de eje-cución para procedimientos almacena-dos es que existen distintas formas decrearlos. En una de ellas, se va a la basede datos a buscar cuáles son los pará-metros que dicho procedimiento alma-cenado utiliza. Dinámico, simple decodificar…, pero que consume muchosrecursos del motor de base de datos.Conceptualmente, este componente deacceso a datos se basa en ese mecanis-mo, ya que recibe siempre el nombredel procedimiento almacenado, con locual este componente debe encargarsede investigar acerca de sus parámetros.

Por ello, y para disminuir los “via-jes” al servidor de datos para simple-mente obtener metadatos, implemen-taremos un mecanismo de persistenciade objetos comando, que almacene losmismos con todos sus parámetros. Laprimera vez que se utiliza un comando,se investigan sus parámetros y se guar-da el objeto Command correspondiente encaché.

Aquí podemos entonces utilizar lacolección especializada de nuestraentrega anterior, utilizándola como basede una clase específica para nuestrosobjetos comando:

Nuestra clase abstracta expondráuna instancia de esta colección, comouna propiedad que solo ella y aquellasque la hereden puedan utilizar:

Cuando se requiera hacer algo conla base de datos, o sea, cuando se nece-site un objeto Command, se buscará endicha colección. En caso que el coman-do aún no esté, la clase hija deberá cre-ar la instancia y obtener los parámetrosque le correspondan.

Ahora bien, una de las diferenciasentre los motores de bases de datos es quecada uno maneja los parámetros de dis-tintas maneras. Por ello, asignar valoresa dichos parámetros puede diferir entremotores. Entonces, cuando hay diferen-cias, que cada quien se haga cargo de loque le toca. Nuestra clase abstracta exi-girá que sus hijas implementen un méto-do que retorne un objeto comando listopara usar. Como además la forma de obte-ner los parámetros, etc. puede cambiar,también las clases hijas serán responsa-bles de manipular la colección.

Nuestra clase abstracta solo exigirá ladefinición del método, y hará uso de él.

Cada uno de los demás métodos uti-lizará entonces el miembro GetCommand.Como un ejemplo, veamos el métodoExecute:

En los casos de los métodos queobtienen valores, el código de ejecu-ción será algo distinto (listado 4).

Al igual que cuando deba retornarreaders o tablas (listado 5).

Los métodos que utilizan sen-tencias SQL (mal hecho, insisto)harían cosas similares, con la excep-ción que, al no haber posibilidad deestar seguros de que son los mismoscomandos que en la llamada anterior,habrá que crear el comando cada vez.Entonces, nuestra clase abstracta exi-girá que exista un creador de coman-

Public Class DbCommandCollectionInherits Solid.Tools.SpecialCollection( _Of String, System.Data.Common.DbCommand)

End Class

Protected MustOverride Function _GetCommand( ByVal procedureName As String,_ByVal ParamArray parameters() As Object)_

As System.Data.Common.DbCommand

Public Function Execute(_ByVal procedureName As String, _ByVal ParamArray parameters As Object())_

As IntegerUsing c As DbCommand = _GetCommand(procedureName, parameters)Return c.ExecuteNonQuery

End UsingEnd Function

Protected mColCommands As _DbCommandCollection

Protected ReadOnly Property _CommandColection() As DbCommandCollectionGetIf mColCommands Is Nothing ThenmColCommands=New DbCommandCollectionEnd IfReturn mColCommandsEnd GetEnd Property

Si no se necesita manipular la transacción, sino simplementeutilizar la que exista en el entorno (como ocurriría en elcaso de componentes de tipo ‘reglas de negocio’ que con-trolen por ellos mismos la transacción), en lugar de crearuna instancia de CommitableTransaction se puede usar la quese maneja automáticamente, utilizando en el método de lec-tura la siguiente instrucción:

mTransaction = System.Transactions.Transaction.Current

NOTA

[ ]Public Function GetValue(_ByVal procedureName As String, _ByVal ParamArray parameters As Object())_

As ObjectUsing c As DbCommand = _GetCommand(procedureName, parameters)

Return c.ExecuteScalarEnd Using

End Function

Public Function GetValues(_ByVal procedureName As String, _ByVal ParamArray parameters As Object())_

As Object()Using c As DbCommand = _GetCommand(procedureName, parameters)With c.ExecuteReader( _System.Data.CommandBehavior.CloseConnection)

.Read()Dim retValues(.FieldCount-1) As Object.GetValues(retValues)Return retValues

End WithEnd Using

End Function

Listado 4

Page 42: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

42

dnm.plataforma.net<<

dos a partir de sentencias SQL y haráuso de él (listado 6).

Haciendo las cosas de la mejor manera

A veces, esto de preguntarle a labase de datos por los parámetrospuede ser útil, pero no es la mejormanera de hacer las cosas. Por eso,vamos a tener los mismos métodos,pero que reciban objetos comandocomo parámetros. De esta forma,serán los componentes que usen esteservicio quienes creen y definan losparámetros en cada caso. Y más queeso, nuestro servicio de datos reco-nocerá una clase abstracta para quetodos los objetos comando se “parez-

can” entre sí, y que podamos, porejemplo, manipular los parámetros

como propiedades u otras funciona-lidades especializadas.

De momento, solo me queda espa-cio para sentar las bases. Primero,nuestra clase comando. Definimosuna clase nueva, que implemente Sys-tem.Data.IDbCommand.

Public Class Command

Implements System.Data.IDbCommand

End Class

Al pulsar [Intro] en la línea quedetermina la herencia, apareceránmuchos métodos que deberemoscodificar.

Para ello, definiremos una variablede tipo DBCommand, y utilizaremos losmismos miembros de dicha variable,por ejemplo:

Private mCommand As _

System.Data.Common.DbCommand

Public Sub Cancel() Implements _

System.Data.IDbCommand.Cancel

mCommand.Cancel()

End Sub

Y así con el resto, que esperopodáis completar para el próximonúmero.

Luego, en nuestra clase de acceso adatos, agregamos variantes de los mis-mos métodos que reciban esta clase comoprimer argumento (figura 2).

Protected MustOverride Function CreateCommand( ByVal sql As String) As DbCommand

<Obsolete(“Sería mejor que uses un procedimiento almacenado”)> _Public Function ExecuteSQL(ByVal sql As String) As Integer

Using c As DbCommand = CreateCommand(sql)Return c.ExecuteNonQuery

End UsingEnd Function

Public Function GetTable(ByVal procedureName As String, _

ByVal ParamArray parameters As Object()) As System.Data.DataTable

Dim dt As New DataTable

Using c As DbCommand = _

GetCommand(procedureName, parameters)

dt.Load( _

c.ExecuteReader( _

System.Data.CommandBehavior.CloseConnection))

End Using

Return dt

End Function

Public Function GetReader(ByVal procedureName As String, _

ByVal ParamArray parameters As Object()) As System.Data.Common.DbDataReader

Using c As DbCommand = _

GetCommand(procedureName, parameters)

Return c.ExecuteReader( _

System.Data.CommandBehavior.CloseConnection)

End Using

End Function

Figura 2. Diagrama de clases hasta el momento

Listado 5

Listado 6

Page 43: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 44: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Empezando por el principio (o casi)Y qué mejor que empezar esta nueva sección con algu-nos consejos. No es que vayamos a tratar solo de cosasde iniciación, pero como soy consciente que muchosde los que se deciden a usar Visual Basic para .NETson desarrolladores que antes han usado Visual Basic6.0, qué mejor que empezar comentando cosas quesirvan para ir deshaciéndose de viejas costumbres ypreparando el terreno para lo que .NET nos ofrece,porque no debemos olvidar que Visual Basic 2008(VB9 para los amigos) utiliza todo lo que las clases de.NET ofrecen, así que mejor acostumbrarnos a usaresas clases, al menos en la medida de lo posible.

Sobre nombres y versionesEmpecemos aclarando nombres y versiones, ya quealgunos se confunden con la forma de llamar al len-guaje. Visual Basic 9.0 es el nombre “oficial” del com-pilador que se incluye con .NET Framework 3.5,que es el que se distribuye con Visual Studio 2008.

Esta versión de .NET Framework en el fondousa la versión 2.0 del runtime o motor de ejecución

(CLR), aunque añade nuevas funcionalidades en for-ma de librerías (ensamblados DLL), que nos permi-ten usar cosas como LINQ y otras de las novedadesde Visual Studio 2008 (para más información, ver ellibro que los suscriptores de dotNetManía recibiráncon el número de marzo de 2008).

Con el entorno de desarrollo de Visual Basic 2008(ya sea desde Visual Studio 2008 o desde la versiónExpress) podemos crear aplicaciones para cualquierade las tres versiones de .NET Framework que se basanen el CLR 2.0, que son: .NET Framework 2.0, el mis-mo que se incluye con Visual Basic 2005 (o VB8); .NETFramework 3.0, que es el que permite crear aplicacio-nes basadas en Windows Presentation Foundation(WPF) y que se distribuye con Windows Vista; y final-mente, para .NET Framework 3.5.

Al crear un nuevo proyecto, podemos seleccionarla versión de .NET que usaremos como “destino”, esdecir, qué características queremos que estén a nuestradisposición. En la figura 1 podemos ver que al crear unnuevo proyecto tenemos la posibilidad de elegir la ver-sión de .NET que queremos usar; por supuesto, depen-diendo de qué versión usemos, tendremos disponibleslos tipos de proyectos “soportados” por esas versiones.

Una isla para Visual Basic en dotNetManíaO cómo hacer las cosas mejor con Visual Basic

Isla VB

Guillermo “Guille”Som

Es Microsoft MVP deVisual Basic desde 1997.Es redactor de ddotNet-Manía, mentor de SolidQuality Mentors, tutor

de campusMVP, oradorde Ineta Latam, y autor

de los libros “ManualImprescindible de Visual

Basic .NET” y “VisualBasic 2005”.

http://www.elguille.info.

Con el quinto año de dotNetManía estrenamos una nueva columna en la revis-ta dedicada exclusivamente a los que gustan desarrollar con Visual Basic. No esque antes no hubiera nada para Visual Basic, pero ya iba siendo hora de que tuvié-semos nuestro propio rincón. En esta isla tendremos ocasión de ver muchascosas relacionadas con Visual Basic, particularmente con la versión 9.0, que es laque se incluye en Visual Studio 2008, aunque muchos conceptos serán válidostambién para las versiones anteriores.

Guillermo «Guille» Som

Page 45: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

45

dnm.isla.vb<<

El compilador de Visual Basic9.0 sabe más que los ratonescoloraosNo, no estamos en el programa deCanal Sur que dirige Jesús Quintero,pero esa expresión nos viene como ani-llo al dedo, ya que lo que debemos saberes que independientemente de la ver-sión de destino, las novedades del com-pilador de Visual Basic 9.0 estarán anuestra disposición. Es decir, el que eli-jamos .NET 2.0 como destino noquerrá decir que solo podamos usar lasinstrucciones que había en la versiónanterior de Visual Basic; lo que quieredecir es que no podremos usar nada queesté en las librerías que se distribuyencon versiones posteriores.

Para que quede claro, el compila-dor que siempre se usa con los proyec-tos creados con Visual Studio 2008 esel compilador de esta nueva versión, esdecir, el compilador de Visual Basic 9.0,independientemente de que usemos ono los nuevos ensamblados distribuidoscon las versiones posteriores a la elegi-da al crear el proyecto.

Por ejemplo, con Visual Basic 2008(que usa el compilador de VB9) podemosusar todo lo relacionado con la inferen-cia de tipos (ya veremos con detalle estode la inferencia, pero por ahora solo decirque el compilador de Visual Basic usaráel tipo de datos adecuado para una varia-ble, dependiendo del tipo que se le asig-

ne). Lo mismo es aplicable a la creaciónde tipos anónimos; es decir, con VisualBasic 2008 podemos escribir un códigocomo el del listado 1 y después de com-pilarlo, ejecutar ese programa en un Win-dows que solo tenga elruntime de .NET 2.0instalado.

¿Cómo es posibleque esto funcione en.NET Framework 2.0?Por la sencilla razón deque esas “novedades”de Visual Basic 9.0están en el compiladory ese compilador gene-ra el código IL (el usa-do por el runtime de.NET para compilar elcódigo en tiempo deejecución) adecuadopara la versión de.NET que se ha elegi-do como destino, (ennuestro ejemplo el.NET Framework 2.0),y por tanto, el códigofuncionará en cualquierequipo que solo tengainstalado el runtime dela versión 2.0.

Aclarar que el códi-go del listado 1 utilizaOption Strict On; esdecir, que todas lasvariables deben tener

un tipo de datos adecuado, y por tantono se permite que se asigne a una varia-ble un valor que no sea adecuado. Deesta opción “estricta” hablaremos en unmomento.

Este código también usa Option InferOn, que es la opción que permite al com-pilador “inferir” el tipo que debe teneruna variable. Por ejemplo, en el bucle ForEach se usa la variable n, que no tiene untipo definido, pero que el compiladordeduce (acertadamente) que debe ser detipo Integer, ya que se utiliza para reco-rrer los valores de un array de ese tipo.Lo mismo ocurre con la asignación a lavariable dnm, en la que el valor asignadoes un valor de tipo anónimo, es decir, untipo de datos creado al vuelo.

Por supuesto, si el código del listado1 lo usamos con Visual Studio / Basic 2005no funcionará, ya que el compilador deesa versión, aunque también use .NET2.0, no sabe qué hacer con “esas cosasraras”; el resultado es un montón de erro-

Figura 1. Las versiones de .NET disponibles al crear un nuevo proyecto.

Dim nums As Integer() = {1, 2, 3, 4, 5, 6, 7, 8}

For Each n In numsConsole.WriteLine(n)

Next

Dim dnm = New With {.Nombre = “dotNetManía”, .Año = 2008}

Console.WriteLine(“dnm.Nombre = {0}, dnm.Año = {1}”, _dnm.Nombre, dnm.Año)

Listado 1. Código de Visual Basic 2008 que se ejecutará con .NET 2.0.

Figura 2. Visual Basic 2005 no reconoce las novedades de Visual Basic 2008.

Page 46: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

46

dnm.isla.vb<<

res, tal como vemos en la figura 2, empe-zando por la definición de Option Infery continuando con la variable n, o por eluso inadecuado de With, para finalizar conla variable dnm, ya que se intenta accedera miembros inexistentes de una variableque teóricamente sería de tipo Object,aunque, en realidad, el error producidopor el uso de With no le ha dado tiempoal compilador de indicarnos que OptionStrict On requiere que todas las variablesse declaren usando un tipo.

Aunque VB9 sea muy listo, no hace milagrosLo que no podrá hacer el compiladorde Visual Basic 2008 es usar caracterís-ticas que no están disponibles, salvo por-que haya otras librerías (o extensiones)que le permitan usarlas. Por ejemplo,en el listado 2 tenemos un código queusa las extensiones de LINQ, que estándefinidas en una librería que se distri-buye con .NET Framework 3.5; portanto, ese código no podrá compilarsepara una versión de .NET anterior.

Es posible que piense: vale, no pue-do usar esa característica porque el com-pilador necesita una referencia a la libreríaSystem.Data.Linq.dll, ¿y si la añado?Bueno, puede intentarlo, pero no lo per-mitirá, tal como vemos en la figura 3, enla que se nos indica que esa librería no escompatible con la versión de .NET quehemos elegido como destino.

Por tanto, si queremos usar esaslibrerías “especiales” de .NET Frame-work 3.5, podemos hacerlo, pero paraello debemos cambiar la versión de.NET para la que queremos compilar,en este caso a .NET 3.5. Ese cambio lopodemos hacer en la ficha de compila-ción (en las propiedades del proyecto),

pulsando en el botón de opcionesavanzadas de compilación, y eli-giendo en el cuadro de diálogomostrado (ver la figura 4) la ver-sión de .NET que queremos usar.

Por supuesto, si elegimoscomo destino .NET Framework

3.5, el equipo enel que vayamos ausar este ensam-blado tendrá quetener instalada esaversión del runti-me de .NET. Aun-que, dependiendode la alineación delos planetas, pue-

de que no sea necesario. En serio(el VB9 no sabe nada de astro-

nomía), el que indique-mos una versión de .NETsuperior a la 2.0 solo nosobligará a tener esa mis-ma versión instalada en elequipo en el que desple-guemos la aplicación siusamos alguna de lascaracterísticas incluidas enesa versión. Por ejemplo,si compilamos el códigodel listado 1 con .NETFramework 3.5 como des-tino, también funcionaráen sistemas que no tenganinstalado el runtime de.NET 3.5, ya que el códi-go no usa ninguna carac-terística de esa versión de.NET Framework. Sin

embargo, para que funcione el códigodel listado 2, el equipo en el que se uti-lice esa aplicación deberá tener insta-lado el runtime de .NET 3.5.

Recomendaciones para unbuen uso de Visual BasicPara terminar este primer artículo dela nueva sección de dotNetManía dedi-cada a Visual Basic, voy a dar una seriede consejos que nos facilitarán la pro-gramación con Visual Basic 2008 (algu-nas también son válidas para las ver-siones anteriores).

‘ Esto no se podrá usar en .NET 2.0‘ porque no están las referencias a LINQDim q = From n In nums _

Where n > 3 _Select New With {.Numero = n, _

.Descripcion = “El número es “ & n}

Listado 2. Un código que usa las instrucciones para LINQ.

Figura 3. El diálogo “Agregar referencia” sólo muestracomo disponibles las librerías adecuadas para laversión de destino de .NET Framework elegida.

Figura 4. En cualquier momento podemos cambiar la versión de .NET que queremos usar

en nuestro proyecto

En el código de ejemplo queacompaña al artículo, el pro-yecto dnm.vb.console2 utili-za .NET Framework 3.5,pero también funcionará enun sistema con .NET 2.0,aunque la llamada al métodoque utiliza característicasespecíficas de .NET 3.5 nofuncionará.

[ ]NOTA

Page 47: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

47

dnm.isla.vb<<

Una de las recomendaciones quesiempre hago es que dejemos activadala opción de comprobación estricta delcódigo, es decir, dejar siempre en On laopción Option Strict. Al usar OptionStrict On en nuestro código, el compi-lador de Visual Basic hará ciertas com-probaciones de buen uso de las varia-bles y las conversiones que realicemos.

Algunos verán que tener activadaesta opción es... ¡un peñazo!, ya que nosobliga a pensar un poco antes de hacerlas cosas. Con esa opción estricta acti-vada, tendremos que declarar todas lasvariables con un tipo de datos adecua-do, además de que al realizar las con-versiones entre tipos diferentes de datossiempre tendremos que hacer la con-versión (cast, que dice la gente que pre-fieren usar lenguajes de la familia C)adecuada. Pero en realidad esto no esun impedimento, y a la larga saldremosganando, particularmente porque nosevitaremos quebraderos de cabeza enerrores (bugs) que en el otro caso seríandifíciles de detectar.

Cuando Option Strict está desco-nectado, el compilador hará las con-versiones que estime oportunas, quealgunas veces pueden ser erróneas. Peroesa no es la peor parte, ya que si defi-nimos una variable sin un tipo especí-fico, el compilador usará el tipo Objectcomo tipo de datos (siempre que notengamos activado Option Infer), conlo cual el rendimiento final puede queno sea el mejor.

En cualquier caso, el entorno de tra-bajo de Visual Basic (IDE) utiliza lo quese conoce como compilación en segun-do plano; es decir, cada vez que escribi-mos una línea de código, el IDE com-prueba si esa línea de código es correc-ta, y en caso de que no lo sea, nos mues-tra opciones para rectificarla. Por ejem-plo, si queremos asignar a una variablede tipo entero el valor de una variable (oconstante) de tipo cadena, nos avisará deque Option Strict no lo permite, y nosofrecerá una alternativa, que no es otracosa que la conversión de la cadena enun entero, por medio de la función CInt.Vale, muy bien, pero eso mismo es loque hará el compilador en tiempo de eje-cución. Sí, pero la ventaja de que sepa-

mos que se hará una conversión es queeso nos dará pistas para saber que es posi-ble que esa cadena no contenga en rea-lidad un valor adecuado para un tipoentero (para más detalles, ver mis artí-culos en dotNetManía 43 y 44 relacio-nados con la depuración en .NET).

Option Strict está desactivadaal instalar el Visual StudioCuando instalamos Visual Studio (oVisual Basic Express), el valor prede-terminado de Option Strict será Off(desactivado); por tanto, recomiendoencarecidamente que la dejemos acti-vada para todos los nuevos proyectos.Esa activación la haremos seleccionan-do “Opciones” (“Options”) del menú“Herramientas” (“Tools”) y del cuadrode diálogo mostrado, en la rama “Pro-yectos y soluciones” (“Projects and Solu-tions”) tendremos la opción “Valorespredeterminados de VB” (“VBDefaults”) en el que podremos elegir elvalor On para Option Strict, tal comovemos en la figura 5, que está captura-da de una instalación en inglés de VisualStudio 2008, ya que a la hora de escri-bir este artículo la versión en españolaún no está disponible.

Una vez modificada esta opción,cada vez que creemos un nuevo pro-yecto se usará el valor On de forma pre-determinada.

Usar adecuadamente OptionStrict (y el resto de opciones)Una de las ventajas que tiene VisualBasic es que estas opciones las podemospersonalizar a nivel de fichero de códi-go. Es decir, si en nuestro proyectotenemos activada Option Strict (o cual-quier otra de las opciones mostradas enla figura 5) y necesitamos usar una deesas opciones de forma desactivada enun fichero concreto (por ejemplo, enuna clase que use COM –ver dotNet-Manía número 22–, y que por las cir-cunstancias queramos usar esos objetosCOM mediante lo que se conoce comoenlace tardío –late binding–), podemosutilizar la instrucción Option Strict Offen ese fichero en concreto; de esta for-ma, “todo” el código que usemos en esefichero de código tendrá desactivada lacomprobación estricta.

Figura 5. Predeterminar Option Strict On para los nuevos proyectos

Si queremos “mezclar” códigoque use diferentes valores deOption Strict, lo podemos hacercreando clases parciales, de for-ma que el código que use elvalor desconectado (Off) estéen un fichero independiente,con idea de que no perdamoslas ventajas de usar esa opciónen modo On.

[ ]NOTA

Page 48: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

48

dnm.isla.vb<<

Sobre la inferencia automáti-ca de tipos (Option Infer)Como hemos visto en el código de loslistados mostrados anteriormente,Visual Basic 9.0 es capaz de “adivinar”el tipo de datos que tendrá una varia-ble dependiendo del valor que le asig-nemos. Esto es posible solo si tenemosactivada Option Infer, que es el estadopor defecto que tendrán todos los pro-yectos creados con Visual Basic 2008.Esto supone que si por olvido (o como-didad) no indicamos el tipo de datos deuna variable, el tipo será el que el com-pilador crea que debe ser.

Por ejemplo, si declaramos estavariable:

Dim saludo = “Hola, Visual Basic”

El tipo de datos que tendrá la varia-ble saludo será String, ya que es eso loque estamos asignando, una cadena.

La inferencia automática de tipos esindependiente del valor que tengaOption Strict, y solo la podemos usarsi usamos Option Infer On. En cualquiercaso, no debemos abusar de la inferen-cia automática de tipos, y mi recomen-dación es usarla solo en casos muy con-cretos, como puede ser el uso de varia-bles en bucles o cuando estemos hacien-do pruebas; pero no es recomendableusarla en todas las ocasiones, ya que lalectura de nuestro código se puede com-plicar más de lo deseado.

Como excusa o justificación, decirque siempre nos queda el recurso depasar el cursor del ratón sobre unavariable y averiguar de qué tipo de datosesa variable es, tal como vemos en lafigura 6, donde a pesar de estar desac-tivada la comprobación estricta de tipos,el tipo de la variable es String y no elque tendría de forma predeterminada(Object) si no tuviésemos activadoOption Infer.

Lo que sí debemos saber es que lainferencia automática de tipos solo seaplica a variables locales, es decir, a lasvariables declaradas “dentro” de unprocedimiento (método, propiedad,constructor, etc.). Por lo tanto, nopodremos usar esta característica para

los parámetros de esos procedimientosni como valor devuelto por los mismos,y tampoco podremos declarar variables“inferidas” a nivel de módulo.

En este último caso, si tenemosdesactivada Option Strict, la variableserá de tipo Object, y si tenemos acti-vada la comprobación estricta, recibi-remos un error indicándonos que esono es aceptable, ya que todas las varia-bles deben declararse con la cláusula As.

Como recomendación, yo siempreprocuro indicar en cada fichero quéopciones uso, independientemente decómo las tenga configuradas en lasopciones del proyecto (o del IDE), asílas opciones estarán claras para todoslos que lean mi código. También pro-curo añadir las importaciones de losespacios de nombres que uso en cadafichero, pero esto son más bien maníasmías..., aunque en muchos casos mefacilita la lectura del código, particu-larmente el que he escrito tiempo atrás;esa es otra de las características quesiempre ha tenido Visual Basic para.NET, la de importar automáticamen-te los espacios de nombres que el com-pilador “cree” que debemos usar ennuestros proyectos. Y si después quie-ro reutilizar ese fichero de código enotro proyecto que no tiene la importa-ción adecuada, pues... no es que pasemucho, ya que el IDE de Visual Basic2008 me “asiste” y me da la opción deagregar la importación del espacio denombres adecuado; al menos si eso esposible, tal como podemos ver en lafigura 7, en la que en el proyecto notengo agregada de forma automática laimportación del espacio de nombresSystem.Diagnostics, que es el que defi-

ne la clase Process (y que Visual Basicsiempre importa automáticamente).

Por supuesto, para que esta asisten-cia funcione, debemos tener agregada lareferencia correspondiente; es decir, siqueremos usar la clase MessageBox des-de una aplicación de consola, solo podre-mos hacerlo si previamente hemos agre-gado una referencia al ensamblado Sys-tem.Windows.Forms.dll, ya que el editorde Visual Basic 2008 es bueno, pero,como dije antes, no hace milagros.

ConclusionesY esto es todo para este primerencuentro con la nueva sección dedi-cada exclusivamente a Visual Basic.Quisiera aclarar que aunque el códi-go que mostraré en estos artículosserá para Visual Basic 2008 (o VB9),en la medida de lo posible tambiéncrearé proyectos para C# que usen loque trate en estos artículos; así los quehan seguido mi sección “Inicio” enesta revista (desde que se inició, en elnúmero 16, de Junio de 2005) no sesentirán abandonados. Por supuesto,muchas de las cosas que veremosusarán características propias deVisual Basic; en esos casos es posibleque no haya código equivalente paraC#, pero siempre nos quedará elrecurso de crear un ensamblado deVisual Basic y usarlo desde otro pro-yecto de C#, que esa es una de lasventajas de la interoperabilidad de.NET.

Lo importante es que... ¡nos segui-mos viendo en dotNetManía!

Figura 6. La inferencia automática de tipos es independiente del valor

de Option Strict.

Figura 7. El IDE de Visual Basic 2008permite agregar las importaciones

que necesitemos.

Page 49: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

49

El objeto Cache de ASP.NET es específico delDominio de Aplicación, y, por supuesto, no pue-de ser compartido entre múltiples CPU y servi-dores. Las técnicas de caché en ASP.NET pier-den mucho cuando la aplicación se escala a unmodelo de jardín de servidores (un servidor ymúltiples CPU) o de granja (múltiples servido-res y una CPU cada uno).

En ASP.NET, se crea una instancia de Cachepara cada aplicación y cada aplicación se asocia aun Dominio de Aplicación en su proceso. La cla-se Cache se implementa como un wrapper (envol-torio administrado) en torno a una clase internaque es un contenedor del tipo IEnumerable. Laclase real usada para implementar el objeto Cachevaría dependiendo de las CPU implicadas. Si solohay una disponible, el sistema usa una clase inter-na llamada CacheSingle; en otro caso, utiliza laclase CacheMultiple. De cualquier manera, sealmacenan ítems de datos en una tabla hash (una

estructura de datos extremadamente rápida en suacceso, y con un tiempo de acceso prácticamen-te constante). Existirá una tabla hash por cadaCPU. En su operativa, lo que sucede es queCacheSingle opera sobre una sola tabla hash,mientras que CacheMultiple maneja un array detablas hash.

Asumido este modelo, no sorprende que enuna máquina multiprocesador en la que se ha vin-culado más de una CPU con el procesoASP.NET, cada procesador acaba teniendo supropia copia del objeto Cache para cada dominiode aplicación (léase, aplicación ASP.NET) ges-tionado. Estos objetos Cache no están sincroni-zados. En un jardín no puede garantizarse quelos usuarios harán sus peticiones a la misma CPU(y proceso) en distintas solicitudes de páginas. Asíque el estado de la caché no garantiza una cohe-rencia con lo que la última página hizo en la últi-ma petición.

Cachés globales y Silverlight

Dino Esposito

Recientemente, hemos escalado una aplicación Web grande a múltiples servidores Web, organi-zados en una granja. La mayoría de las páginas hacen uso intensivo de la caché de ASP.NET. En lanueva configuración, experimentamos algunos problemas menores relativos a la caché. Era comosi los mismos datos fueran descargados y puestos en la caché varias veces y no siempre apare-cieran en sincronía. Después de alguna investigación, hemos determinado que se debe a la nue-va arquitectura multi-servidor, donde la caché no parece estar compartida entre los servidores.La pregunta es ¿cuál es la mejor forma de crear un sistema global de caché en ASP.NET?

todonet@qa

En este artículo cubriremos las características relacionadas con la configuración deun sistema global de caché que abarca todas las máquinas de una granja de servi-dores Web y desvelaremos un sencillo truco para detectar la versión del plug-in deSilverlight instalado, para construir páginas Silverlight dependientes de la versión.

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)

tod

otN

et.q

a@

dot

netm

ania.c

om

Page 50: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

50

dnm.todonet@qa<<

Lo mismo es válido para granjas de servidores. Enun escenario así, cada servidor Web tiene su propioobjeto Cache por Dominio de Aplicación. Pero nopuede asumirse que los usuarios volverán al mismoservidor en peticiones subsiguientes. Y si una peti-ción que debe consumir datos alcanza un servidordonde no hay datos en la caché, se necesita una nue-va lectura. Como consecuencia adicional, cualquiercambio realizado a un dato en el servidor A no serávisible en el B.

Mientras que habrá ocasiones en que todo pare-ce ir bien, se acabará produciendo una falta de sin-cronía entre los datos de diferentes servidores quepuede originar anomalías en algunas páginas de laaplicación. Esto es difícil de abordar y debe ser resuel-to de una forma u otra. Así que la pregunta es: ¿exis-te un objeto similar a Cache que funcione a través deuna arquitectura múltiple? ¿O existe alguna configu-ración que permita al objeto Cache soportar escena-rios remotos? La respuesta, desafortunadamente, esque no, y si necesitamos uno, tenemos que cons-truírnoslo nosotros mismos.

Para construir un contenedor global de datos quefuncione en estos escenarios, necesitamos recurrira un recurso remoto y compartido, tal como una ins-talación de Microsoft SQL Server (u otra base dedatos). Alternativamente, podemos considerar la cre-ación de una capa de servicios (por ejemplo, un ser-vicio WCF o un Servicio Web) que almacene losdatos en una copia local de la base de datos, o usesu propia memoria para almacenarlos. En otras pala-bras, se necesita replicar el modelo de extensibili-dad que Microsoft ha creado para el estado de lasesión.

El acceso a datos en caché de forma remota requie-re serialización y deserialización y es una operaciónsujeta a los efectos de latencia de red. Francamente,no puede esperarse obtener el mismo nivel de res-puesta que se obtiene en un escenario simple. El coro-lario de esto es que el modelo general para una cachéglobal y multiservidor es lo suficientemente comple-jo como para invalidar las ventajas obtenidas del usode la caché.

La dicotomía a estudiar, a efectos de este proble-ma, es la del acceso a datos semipreparados en con-traposición a la obtención de nuevos datos mediantela ejecución de otra consulta. ASP.NET ofrece unainfraestructura efectiva de caché en servidor simple,porque eso es lo que se necesita en la mayoría de lasocasiones. Extender la infraestructura para soportarotros escenarios es decisión propia, pero puede guar-dar desagradables sorpresas en el rendimiento.

Dicho esto, ¿qué puede hacerse? Reescribir la apli-cación no es una opción. Puedo imaginar que la mayorparte de los datos en caché son de solo lectura, o, al

menos, que cambien con poca frecuencia. Esa la razónde su uso, la mayor parte de las veces. También asu-mo que la aplicación tiene la facultad de rellenar lacaché si encuentra que está vacía. El comportamien-to del objeto Cache asegura que cada servidor de lagranja obtiene sus datos de la fuente original y losubica en la caché local. Esto quiere decir que se rea-lizan varias consultas para rellenar las cachés de todoslos servidores. Para este comportamiento, no se nece-sitan cambios en el código.

A mí no me importaría acceder a la base de datosdirectamente siempre que se necesite. Manejar fiche-ros XML requiere algún trabajo de administracióncon el que podría ser complicado operar. Y la pre-gunta clave aquí es ¿cómo puedo notificar a otros ser-vidores que ha tenido lugar un cambio en los datosalmacenados en la caché de un servidor concreto?

En un escenario de granja de servidores, apro-vecharía el mecanismo de dependencia del objetoCache de ASP.NET: añadimos los datos consultadosal objeto Cache usando dependencia de ficheros. Deesta forma, cuando el sello temporal (timestamp) delfichero se modifica, el contenido de la caché es inva-lidado y se carga nuevamente en el siguiente acce-so. Si se utiliza un fichero ubicado en una zona com-partida de red, se pueden invalidar simultáneamen-te todas las cachés de todos los servidores. Lasiguiente petición lanzará una nueva consulta sobreel servidor solicitado. Si el cambio que invalida lacaché se refleja inmediatamente en la base de datos,no hay problema. Si el cambio está limitado a lacaché del servidor donde sucede la petición, y se per-siste a la base de datos posteriormente, entonces

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

ASP.NET ofrece una infraestructura efectiva de caché en servidor simple, porque eso

es lo que se necesita en la mayoríade las ocasiones

Page 51: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Cualquier página Web equipada con una versión deSilverlight debe enlazar el fichero Silverlight.js,que es parte actual del SDK. No se puede decirdemasiado acerca del futuro, pero, actualmente, estefichero es el mismo para las versiones 1.0 y 1.1 (quese denominará 2.0 en la versión final). En ese fiche-ro se encuentra un objeto llamado Silverlight conalgunos métodos estáticos. El más típico es create-Object, que se usa para instanciar el motor de Sil-verlight en una página Web. Otro método intere-sante, que es justo lo que buscas, es isInstalled.Este método determina si una versión concreta delproducto está actualmente instalada en la máquinadel usuario:

if (!Silverlight.isInstalled("1.0"))alert("Please, install version 1.0.");

El número de versión consta de 4 valores: ver-sionMajor.versionMinor.buildNumber.revisionNum-

ber. Sin embargo, normalmente, tú solo usarás ver-sionMajor.versionMinor. El método devuelve ver-dadero igualmente si la versión instalada es supe-rior a la comprobada. Así que, en el ejemplo ante-rior, la pregunta real es ¿tienes al menos la versión1.0 instalada?

Claramente, este método está diseñado para per-mitir deshabilitar algunas características en unapágina que requiera una nueva versión del plug-inde Silverlight. Es interesante notar que, sin embar-go, no hay una forma directa de saber –a partir delcomplemento– de qué versión se trata, ni puedeleerse directamente la versión mínima que fue soli-citada por la página. El siguiente fragmento de códi-go muestra una forma simple de averiguar cuál esla versión instalada. La figura 1 muestra un ejem-plo en acción cuando se implementa esta carac-terística.

var results = "Unknown";var versionToCheck = "2.0";var v = Silverlight.isInstalled(versionToCheck);if (v)

results = versionToCheck;else{

versionToCheck = "1.1";v = Silverlight.isInstalled(versionToCheck);if (v)

results = versionToCheck;else{

versionToCheck = "1.0";v=Silverlight.isInstalled(versionToCheck);if (v)

results = versionToCheck;}

}

dnm.todonet@qa<<

dotN

etM

anía

<<

51

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

puede ser necesario crear un fichero (o tabla) tem-poral en la ubicación compartida, y modificar el códi-go existente para rellenar la caché para que utiliceeste recurso. El mecanismo de dependencia informaal código que hace la llamada acerca de la razón por

la que los datos expiraron: usando esta informaciónpodemos discernir si es necesario rellenar la caché apartir de la base de datos, porque es el primer acce-so, o acceder al recurso temporal, dado que algunosdatos han cambiado.

Traducido al castellano por Marino Posadas

Estoy haciendo una aplicación en Silverlight 1.0 para nuestra Intranet. A causa del soporte limitado deWPF en esta versión, estoy usando un montón de Javascript para añadir capacidades de introducción dedatos y un mínimo de posicionamiento en pantalla. Tenemos planes de migrar esta primera aplicación aSilverlight 2.0 tan pronto como podamos. ¿Hay forma de introducir algún tipo de control de versión enel código de una aplicación Silverlight? ¿Se puede escribir código para las dos versiones y discriminar laversión instalada?

Figura 1

Page 52: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

¿Qué nos ofrece Visual Guard?

Visual Guard simplifica enormemente tareas comolas siguientes:

Gestionar los usuarios y roles de una aplicación ysus posibilidades de acceso

El producto permite realizar la autenticaciónde usuarios (creados especialmente o provenien-tes de un Directorio Activo o una base de datosde SQL Server u Oracle) y su autorización parael acceso a una aplicación o partes de ella en basea un conjunto de roles y permisos creados pornosotros y almacenados en una base de datos decualquiera de los tipos anteriores o en un ficheroencriptado. Toda esa información de seguridad se

almacenará en un repositorio que podrá o no com-partirse entre diferentes aplicaciones. El formu-lario de autenticación puede ser personalizadosegún nuestros deseos.

Permitir o impedir el acceso a aplicaciones o par-tes de ellas.

En base a los datos suministrados durante lafase de autenticación, el motor de Visual Guardautorizará o no el acceso del usuario a una aplica-ción o a partes específicas de ella, como menús oformularios.

Filtrar y proteger los datos confidenciales

En dependencia de la identidad del usuario,ciertos elementos de la aplicación que muestrendatos confidenciales podrán ser ocultados o hechosde solo lectura para impedir su visualización y/omodificación.

Personalizar la interfaz de usuario

También en función de la identidad del usua-rio, será posible (y muy fácil) modificar la inter-faz de usuario de los formularios que componenla aplicación, por ejemplo mostrando u ocultan-do botones, campos, pestañas de un cuaderno,etc.

Visual Guard .NET

Octavio Hernández

El reciente caso aparecido en la televisión nacional, donde una factura recibida por unusuario mostraba los apellidos de éste cambiados por palabras ofensivas, ha puestoen evidencia una vez más la importancia de que las aplicaciones a través de las cualeslos empleados manipulan los datos con que las empresas operan realicen una correc-ta autenticación y registro de actividad de sus usuarios. Este mes presentamos VisualGuard .NET, un cómodo y útil marco de trabajo que permite gestionar de una mane-ra eficiente y centralizada los usuarios, roles y permisos de una aplicación y asegurarel acceso de los usuarios a cada uno de los elementos de la misma.

Nombre: Visual Guard .NETVersión: 2.6Fabricante: NovalysSitio Web: http://www.visual-guard.comCategoría: Marcos de trabajo, seguridadPrecio: solicitar cotización a través de la

página Web (ddescuento del 15% alectores de dotNetManía)

Ficha técnica

Octavio Hernández esMentoring TeamLeader de Plain

Concepts, editortécnico de

dotNetManía y tutorde campusMVP.

Es MVP de C# desde2004, MCSD y MCT.

Laboratorio.net

Page 53: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Parametrizar la lógica de negocio de la aplicación

Otra cosa que puede ser necesaria y que VisualGuard hace muy sencilla es la parametrización de lalógica de negocio en función de los usuarios y roles.Por ejemplo, es común que un vendedor “corriente”tenga fijado un importe máximo de pedido inferior alde sus jefes. Visual Guard ajustará la regla de valida-ción correspondiente en función del usuario actual.

¿Cómo funciona Visual Guard?Visual Guard consta de dos componentes funda-

mentales:• La Consola de administración de Visual Guard (figu-

ra 1), una herramienta para la edición visual de losusuarios, mecanismos de autenticación a utilizar, roles,permisos, acciones a llevar a cabo en casos de que un

usuario no tenga ciertos permisos, etc. La Consolade administración permite actuar sobre un reposito-rio de seguridad, en el que se almacena toda esa infor-mación para una aplicación o grupo de aplicacionesespecífico. Este repositorio podrá almacenarse enuna base de datos SQL Server u Oracle o en un fiche-ro encriptado.

• El motor de ejecución de Visual Guard, un con-junto de ensamblados a los que harán referencia lasaplicaciones y que modificará el comportamientode éstas en función de la identidad del usuario actualy de los permisos que tenga asignados en el reposi-torio de seguridad de la aplicación. Como parte delmotor se incluye un proveedor de membresía (mem-bership), mediante el cual los desarrolladores podrángestionar programáticamente los usuarios y roles.La tabla 1 muestra los ensamblados que componenel motor.

dotN

etM

anía

<<

53

dnm.laboratorio.net<<

Figura 1. Consola de administraciónFigura 2. Diálogo de autenticación

estándar

Ensamblado Contenido

Novalys.VisualGuard.Security Las clases principales de Visual Guard. La referencia a esteensamblado es obligatoria.

Novalys.VisualGuard.Security.File Clases necesarias para acceder a un repositorio almacenado enun fichero.

Novalys.VisualGuard.Security.Oracle Clases necesarias para acceder a un repositorio almacenado enuna base de datos de Oracle (8i o superior).

Novalys.VisualGuard.Security.SQLServer Clases necesarias para acceder a un repositorio almacenado enuna base de datos de SQL Server (2000 o superior).

Novalys.VisualGuard.Security.WebForm Clases necesarias para integrar Visual Guard en una aplicación o servicio ASP.NET.

Novalys.VisualGuard.Security.WinForm Clases necesarias para integrar Visual Guard en una aplicación Windows Forms.

Tabla 1. Ensamblados que componen el motor de Visual Guard

Page 54: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

54

dnm.laboratorio.net<<

En tiempo de ejecución, el motor de VisualGuard: 1. Gestiona la autenticación del usuario. La figu-

ra 2 muestra el diálogo de autenticación están-dar, utilizado en la aplicación de ejemplo queacompaña al producto. Como hemos comenta-do anteriormente, usted puede suministrar supropio diálogo, si lo prefiere.

2. Se conecta al repositorio y recupera los permi-sos del usuario.

3. Ajusta dinámicamente la aplicación en funciónde esos permisos. Por ejemplo, cuando se abreun formulario, el motor de Visual Guard ocul-ta controles y filtra datos según sea necesario.Las figuras 3 y 4 muestran la aplicación de ejem-plo mientras está siendo utilizada por un admi-nistrador y un empleado del departamento deRecursos humanos de la oficina del Reino Unido,respectivamente. En el segundo caso, solo están

visibles los clientes británicos, y no se permite alusuario la inserción o borrado de clientes.

El proceso de integraciónEl proceso de integración del motor de Visual

Guard dentro de cualquier proyecto que estemos desa-rrollando constará típicamente de los siguientes pasos:1. Agregar los ensamblados de Visual Guard al pro-

yecto y activar la seguridad.2. Implementar el formulario de autenticación de

Visual Guard (o definir uno propio).3. Crear un repositorio de seguridad y registrar el

proyecto dentro de ese repositorio.4. Los desarrolladores, utilizando la Consola, añaden al

repositorio los permisos asociados al proyecto. 5. El proyecto es compilado y desplegado.6. Una vez desplegado el proyecto, el administrador:

a) Define roles y les asocia permisos de entre losexistentes en el repositorio.

b) Crea usuarios y los asocia a roles específicos.

Observe que no se requieren conocimientos o habi-lidades técnicas especiales para administrar la seguridad.

ConclusionesA lo largo de este artículo hemos intentado mos-trar las principales posibilidades que nos ofreceVisual Guard para ayudarnos a crear aplicacionesseguras y personalizables en función de la identi-dad del usuario que las utiliza en cada momento. Seinvita al usuario a descargar la versión de evalua-ción y probar las aplicaciones de ejemplo que seincluyen con el producto.

Figura 4. La aplicación de ejemplo, utilizada por un empleado de recursos humanos británico

Figura 3. La aplicación de ejemplo, utilizada por un administrador

ReferenciasSitio Web de Visual Guard: http://www.visual-guard.com[1]

El motor de ejecución de VisualGuard modificará el comportamientode las aplicaciones en función de la

identidad del usuario

Page 55: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Silverlight 1.0 UnleashedAdam NathanEditorial: Sams PublishingPáginas: 272Publicado: octubre de 2007ISBN: 978-0672330070Idioma: inglés

Ya hemos hablado en ocasiones anteriores del autor dentro de esta sección; la última,a propósito de su “WPF Unleashed”, considerado uno de los mejores libros en su temá-tica. Hay que añadir que Nathan es Senior Software Development Engineer en Micro-soft Redmond y también el arquitecto jefe de Popfly, el primer producto construido direc-tamente sobre Silverlight. No necesita, pues, más presentación en cuanto a su conoci-miento del tema.

Esta es una obra que, abordando todo lo necesario para la construcción de páginasen Silverlight, se limita a la versión actual en producción: la 1.0. No hay referencias a lapróxima versión (todavía en fase alfa). Pero la cobertura es excelente, los ejemplos sen-cillos y directos de utilizar, y los tips o trucos propios del SDK, de un valor excepcional.Muchos problemas cotidianos que se presentan durante el trabajo con esta versión seresuelven a través de estas ayudas. Hay mejores introducciones, no obstante, pero ésta esabsolutamente recomendable.

Silverlight 1.0Devin Rader, Jason Beres, J. Ambrose Little y Grant HinksonEditorial: WroxPáginas: 288Publicado: octubre de 2007ISBN: 978-0470228401Idioma: inglés

Lo ideal sería tener –al menos hasta que aparezcan otras obras en preparación– laobra anterior junto a la que presentamos aquí. En esta ocasión, hay que resaltar dos aspec-tos que no son abordados –o no lo son con esta profundidad– por el libro de Nathan: laintroducción y explicación de la parte estructural y arquitectónica en la que se basa Sil-verlight, junto al uso correcto de las herramientas para desarrollar en esta versión y, espe-cialmente, la parte de Silverlight 1.1 (que se llamará 2.0, cuando se produzca su apari-ción oficial).

Los ejemplos son muy explicativos de la funcionalidad ofrecida por el SDK, y no hayparte de éste que no se encuentre citada en la obra. Hay, además, un capítulo interesan-te sobre el CLR y Silverlight 1.1 que sirve para vislumbrar las inmensas posibilidades queofrecerá la nueva versión, y otro dedicado a explicar un caso de ejemplo, muy ilustrativodel abordaje de una aplicación.

biblioteca.net

nove

dad

es Microsoft ASP.NET 3.5 Developer Reference

Dino Esposito. Editorial: Microsoft Press. Páginas: 992. Publicado: febrero de 2008. ISBN:

978-0735625273. Idioma: inglés.

Pro Silverlight 1.1Matthew McDonald. Editorial: APress. Páginas: 400. Disponible: abril de 2008. ISBN: 978-

1590599495. Idioma: inglés.

TEXTO: MARINO POSADAS

Page 56: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

56

Esta pasión por las ganas de aprender,de enseñar, de poner lo mejor de cadauno en hacer las cosas bien, de trans-mitir conocimientos… ¡Qué diablos!,me dije, ¿por qué no iba a tenerla encasa?, ¡al fin y al cabo frikis amantes deldesarrollo hay en todas partes!

Después de hablarlo con Pep LluísBaño, fundador de Spain.Net y poraquel entonces compañero de viaje (yde habitación) empecé a verlo más claro,y gracias a su ayuda inicial y a la de otramucha gente, al final este proyecto se

ha hecho realidad: el próximo día 1 de febrero serealizará el primer evento del grupo de usuarios,en el que a petición popular hablaremos de Share-Point como plataforma de servicios para el desa-rrollador.

Desde entonces hasta aquí ha habido un largocamino, ya que la creación de un grupo de usua-rios tal vez no parezca gran cosa, pero os aseguroque conlleva mucho trabajo. Primeramente debe-mos encontrar gente que tenga los mismos intere-ses y esté dispuesta a compartir el trabajo, hay quedefinir unos estatutos, buscar patrocinadores y cola-boradores, crear el sitio portal del Web del grupo,visitar universidades y escuelas, y no hay que olvi-darnos de la planificación de los eventos… Sinembargo, cuando existen ganas e ilusión en tirarun proyecto hacia adelante, no hay trabajo quevalga, y si por ende contamos con miembros de lujocomo Jorge Serrano (MVP ex-residente en el país),Carlos Segura (MVP fundador del Navarra UserGroup), el propio Pep Lluís Baño, o Miquel Vila-drich (profesor en la universidad de Andorra), laverdad es que todavía resulta mucho más sencillo.

Así pues, el objetivo de AndorraDotNet es elde realizar eventos periódicamente, en los que los

AndorraDotNetGrupo de usuarios .NET de Andorra

comunidad.net

AndorraDotNet nace como el primergrupo de usuarios de .NET en Andorra,el pequeño país de los pirineos. La ideaempezó a formarse en mi cabeza duranteel MVP Summit realizado en Seattle en2005, entre sesiones técnicas, barbacoasy alguna que otra visita a la CompanyStore. Allí, en medio de todo ese gentíoempecé a pensar en el gran espíritu de lacomunidad que flotaba por allí, y en quelo realmente bonito de estos eventos esel altísimo nivel de comunicación entrela gente y la pasión que trasmiten todosy cada uno de ellos.

Page 57: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

miembros del grupo (y todoel que quiera mientras notengamos problemas deaforo) nos reuniremos para hablar delo que mueve nuestra pasión: el desa-rrollo de software y todo lo relacio-nado con él. Desde arquitecturahasta metodologías de gestión deproyectos, pasando por nuestros len-guajes favoritos de .NET Frame-work, innovaciones tecnológicas, y

cualquier cosa que se nos pase por lacabeza.

Todo el mundo es bienvenido.Tanto si eres un profesional consoli-dado como si todavía estás estu-diando, da lo mismo que residas en elpaís, en las cercanías, o simplementeestés de paso porque has venido a

sacar brillo a los esquíes. ¡Lo real-mente importante es que sientas esapasión!

dnm.comunidad.net<<

Lluis Franco

Eventos de OnobaNET

El pasado 14 de diciembre, Bruno Capuano y Juan Luis Guerrero visi -taron Huelva para un evento. Bruno presentó MS Robotics y Lego Mind-storms, y mostró las cosas que se pueden hacer con ellos. Por su parte,Juan Luis Guerrero mostró algunas de las novedades que trae el nuevoVisual Studio 2008. Este evento contó con gran afluencia de público (50asistentes), entre los que destacaron dos pequeñines que vinieron a vercómo funcionaba el robot :-).

El 16 de enero de este nuevo año, nos visitó Eladio Rincón, del grupode usuarios GUSENET, quien dió una magnífica charla sobrerendimiento de SQL Server 2008, junto con Miguel Rodríguez deOnobaNET, que realizó varias demos de Inteligencia de Negocio enMOSS (Form Server, Excel Services y KPI).

Ambos eventos acabaron con preguntas a los ponentes acerca de lostemas expuestos. Luego, para terminar los eventos, “unas tapitas” en elbar de la amiga Elvira, mientras su dueña conversaba con los ponentes y algunos asistentes.

eventos.eventos.eventos.eventos.eventos

AndorraDotNet• ubicación: Andorra• fecha de fundación: octubre 2007• fundador: Lluís Franco• miembros: 20• página web: http://www.andorradotnet.com• email de contacto: [email protected]

Page 58: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

dotN

etM

anía

<<

58

desvánMás allá de Windows Vista

Stephen Sinofski, Windows Senior Vice-President ha anticipado recientemente algu-nas novedades sobre el sistema operativo queseguirá a Vista. Inicialmente nombrado comoBlackComb y posteriormente como Vien-na, parece que estas nomenclaturas vuelvena un estado de pureza y se habla de Windows7. Y se dice que no estará disponible hasta2010 (aunque ha surgido últimamente algu-

na voz indicando la segunda mitad de 2009). Dispondrá de dosversiones de procesador: 32 y 64 bits. Mientras tanto, los grandesService Pack para Vista serán Windows Vista Service Pack 1(actualmente en beta pública) y un nuevo tipo de actualizaciónque se denomina Microsoft Desktop Optimization Pack, que esmás bien un mecanismo de optimización del sistema, configura-ble por el usuario.

Respecto al diseño y aspecto visual delsistema, el éxito obtenido en Office 2007ha movido a Microsoft a reclutar a JulieLarsen-Green, una de las artífices princi-pales del cambio de aspecto y modo ope-rativo de la suite, para repensar –especial-mente— “el modo en que a los usuarios lesgustaría utilizar el sistema”. Caben esperargrandes cambios, a tenor de su labor para

la actual versión de Office. Pero, ¿habrá grandes cambios enla arquitectura interna del sistema? Se dice que no. Que lacalidad y el rendimiento serán el objetivo primordial. Perotambién hay quien apunta ideas de primera mano salidas dela propia casa central (o eso afirman): todas las aplicacionesejecutándose como no-Administrador, nueva estructura dedrivers gráficos (para evitar las caídas por esta vía, ya que laqueja por parte de Microsoft es que las compañías son muyproclives a cuidar al máximo el rendimiento de sus driversgráficos, pero no su estabilidad), y la imposibilidad de quecualquier servicio del sistema tenga la facultad de crear unainterfaz de usuario. Es llevar el concepto de ejecución enmáquina virtual hasta las últimas consecuencias en aras de laseguridad. Otras características anunciadas son la posibilidadde afinar la instalación para que cada fabricante o similar pue-da personalizar el sistema según sus necesidades (ComponentDelivery Platform), y StrongBox, mecanismo ideado paraminimizar el impacto que algunas aplicaciones tienen sobreotras. De cara al usuario, Windows Live estará tan integra-do con el sistema, que simplemente será como una extensiónnatural de éste. Y es que Redmond se ha dado cuenta de unagran verdad: si el usuario de una aplicación no se siente cómo-do con ella, si su uso supone una pesadilla en lugar de un pla-cer, o si tiene que leer largos manuales para empezar a serproductivo, de poco sirve que la infraestructura y arquitec-tura sean excelentes. Al usuario no le interesa el código fuen-te, le interesa su propia experiencia (de usuario).

Marino Posadas

Configuring Visual Studio to Debug .NET FrameworkSource Code. Es un excelente artículo sobre cómo pode-mos cambiar la configuración del IDE de forma que poda-mos ver cómo se ejecuta el propio código fuente de laslibrerías de .NET Framework. Algo más que una curiosi-dad, cuando encontremos algún bug que se resista. Ver elblog de Shawn Burke (http://blogs.msdn.com/sburke/archi-ve/2008/01/16/configuring-visual-studio-to-debug-net-frame-work-source-code.aspx), no es menos recomendable. (Graciasa Daniel Seara por el enlace).

Visual Studio 2008 Learning Guide. ¿Quiere ponerse aldía en las novedades de VS 2008, y no tiene tiempo para una

formación adecuada?Puede intentar descar-gar los documentos dis-ponibles en WinDeve-

lopment, bajo el epígrafe “Visual Studio 2008 Learning Gui-de” (http://searchwindevelopment.techtarget.com/gene-ric/0,295582,sid8_gci1280711,00.html?track=NL-150&ad=612250&asrc=EM_USC_2568652&uid=6264165). Com-prendemos que no tenga muchas ganas de teclear todo eseenlace. Así que quizá prefiera buscarlo en http://searchwinde-velopment.techtarget.com.

El blog de David Salgado. Trepidante. En constan-te cambio, como los service packs. Aparte de bue-nos y profundos comentarios sobre una de susespecialidades (la depuración a bajo nivel),

veremos noticias, trucos, anuncios de eventos de desarrollo,y hasta un diario-gadget muy “á-la-mode”. Disponible enhttp://blogs.msdn.com/davidsalgado.

Developer Fusion. Un sitio excelente, ubi-cado en el Reino Unido, y con una can-tidad ingente de información sobre desa-

rrollo (no solo en .NET). Me gustaría recalcar un artículo sobreSilverlight, escrito por un buen amigo (Dave Wheeler, del equi-po de desarrollo del SDK de NewsReaders, en Redmond). Conmontones de código fuente y artículos sobre programación(http://www.developerfusion.co.uk).

ClipX. Para los que –muchas veces- hemos echado demenos utilidades extra asociadas al comportamiento delPortapapeles de Windows. Ocupa más o menos 100K, esgratis, y permite funcionalidades extendidas como hacerbúsquedas en Internet sobre el contenido del Portapa-peles, o comandos para abrir una sesión nueva del nave-gador con la URL contenida en él. Descargable dehttp://www.bluemars.org/clipx.

documentos en la red

utilidades del mes

sitios del mes

noticias.noticias.noticias

Page 59: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada
Page 60: dotNetManía - Tecnología, Tips de Programación y … · entrevista Don Syme Investigador ... Comenzamos aquí el desarrollo del primer componente de funcionalidad compleja. Dada

Porque tú eres nuestro verdadero protagonista, no puedes faltar.

Ven a {The Evolution Show}, todo un acontecimiento y una experiencia inolvidable

donde te presentaremos las nuevas versiones de Windows Server 2008, Visual Studio 2008

y SQL Server 2008. Premier técnica, demos, laboratorios, Steve Ballmer en directo desde

Los Ángeles,... ¡No te lo puedes perder!

Regístrate ya en www.microsoft.es/lanzamiento2008Mucho más que una evolución. Una revolución…

Y el 26 y 27 de febrero en Madrid

Palacio Municipal de Congresos

(Campo de las Naciones)

Microsoft TechDays

{The Evolution Show}

Con la colaboración de: