Qué es WSE 2.0? - Tecnología, Tips y Programación por Sergio

Transcripción

Qué es WSE 2.0? - Tecnología, Tips y Programación por Sergio
nº16 junio 2005 • 6,00 € (España)
Visual Basic.NET • C# • Delphi • ASP.NET • ADO.NET • .NET Framework • Windows Server System
dotNetManía
www.dotnetmania.com
Dedicada a los profesionales de la plataforma .NET
¿Qué es WSE 2.0?
Una visión de alto nivel de qué es WSE y cómo se integra con .NET
Entrevista a Nuria Oliver
Investigadora de Microsoft Research en EEUU
Comunidad.net
El sitio de “El Guille”, un sitio con
más de ocho años de historia
ToDotNet Q&A
Acceso a datos y contenedores de datos
MVP Online
Aviso para navegantes
Legal
De igual a igual: ¿es legal el intercambio de ficheros en la Red?
Generando hojas Excel
con ASP.NET • Creación
de complementos en
Visual Studio .NET •
Interfaces • Herencia:
¿To be or not to be?
dnm.editorial
dotNetManía
Hawaii
Vol. II •Número 16 • Junio 2005
Precio: 6€ (España)
Editor
Paco Marín
([email protected])
Administración
Pilar Pérez
([email protected])
Asesor Técnico/Coordinación
Marino Posadas
([email protected])
Redactores
Antonio Quirós, Dino Esposito, Guillermo
'guille' Som, Jorge Serrano, José Manuel
Alarcón, Luis Miguel Blanco, Miguel
Katrib (Grupo Weboo) y Pedro Pozo.
Colaboradores habituales
Ángel Esteban, Braulio Díez, Eladio
Rincón, Erich Bühler, Fernando Nogueras,
Jorge Crespo Cano, José Miguel Torres,
Miguel Egea, Octavio Hernández, Pablo
Abbate, Pepe Hevia, Rodrigo Corral y
Salvador Ramos.
Además colaboran en este número
Carlos J. Quintero, César de la Torre, José
Antonio Suárez Lozano y Reyes García
Edición y Suscripciones
.netalia
c/ Robledal, 135
28529 Rivas-Vaciamadrid (Madrid)
Tf. (34) 91 666 74 77
Fax (34) 91 499 13 64
Publicidad
Mediadev
Sophie Mancini ([email protected])
Tf. 93 426 22 57 - 670 99 74 64
Fax. 93 423 11 40
Imprime
Gráficas Vallehermoso
www.graficasvallehermoso.com
ISSN
1698-5451
Depósito Legal
M-3.075-2004
<<
Ya es público: Hawaii es el nombre en clave de la “segunda siguiente versión” de Visual
Studio, o sea, la que seguirá a Orcas, que es el
nombre en clave de la que seguirá a Whidbey
que, a su vez, siguió a Everett y ésta a Rainier...
¡Cómo me gustan los codenames! ¿No me dirá
que Hawaii no suena bien? Para SQL Server
aún no sabemos cuál será el codename de la
“segunda siguiente versión” de SQL Server
2005. Sólo sabemos que el de la siguiente versión será Acadia, y que muy probablemente
se llamará SQL Server 2007. Y un triste adiós
a Magneto porque a partir mayo es Windows
Mobile 5.0. Me pregunto por qué no dejarán
estos codenames como definitivos, ¡a mí me gustan más!
Bienvenidos al número 16 de junio de
2005 de dotNetManía.
En este número entrevistamos a la primera mujer –será difícil llegar a la paridad
en esto por ahora–: Nuria Oliver, una joven
investigadora española que realiza sus trabajos de investigación para Microsoft
Research en EEUU.
Éste es un mes de estrenos: de caras nuevas, de nuevos autores que aportarán también
cosas nuevas y de una nueva sección: dnm.inicio.*, dirigida por “El Guille” y dedicada a
difundir las bases de .NET Framework desde
un punto de vista teórico (dnm.inicio.fundamentos), y desde un punto de vista práctico
(dnm.inicio.taller) y que no sólo vendrá bien
a los que están empezando –¿a estas alturas?
se preguntará; pues sí, aún hay muchas personas que están empezando o que no lo han
hecho todavía–, sino también a algunos profesionales que a pesar de serlo y ejercer como
tales, tienen algunas lagunas y que nos vienen
demandado artículos de este tipo. Ojo, que no
será una sección para dummys ni mucho menos.
Empezamos por dar la bienvenida a una
mujer: Reyes García, la primera también,
quien empieza colaborando con Braulio Díez,
con el artículo “Generando hojas Excel con
ASP.NET”, siguiendo éste con su visión práctica que, al menos a mí, tanto me gusta.
Tengo que dar la bienvenida igualmente a César de la Torre, de uno de los
Microsoft Gold Partner: Renacimiento,
quien nos escribe el artículo “¿Qué es
Microsoft WSE?”. Espero que podamos
contar más con él para que nos cuente más
en profudidad sobre las especificaciones
WS-* y, sobre todo de Indigo.
Y también doy la bienvenida a Carlos J.
Quintero, autor de las MZTools y MVP de
Visual Developer .NET quien nos escribe de lo
que más sabe, de cómo crear complementos
en Visual Studio .NET en su artículo “Creación
de complementos en Visual Studio .NET”.
Espero que Carlos quiera seguir escribiendo
sobre estos temas que de seguro le interesará.
En la sección arquitectura y metodologías Daniel Mazzini escribe un buen artículo
sobre los patrones Delegado y Superclase
Abstracta. Tenemos planes para continuar
hablando de patrones básicos, de creación, de
UI y UIP, de estructura y de comportamiento.
Dino Esposito, como siempre explicando cosas complejas con sencillez, toca temas
como el acceso a datos, remontándose a los
oscuros tiempos del RDO hasta ADO.NET
y también nos ayuda a elegir entre la gran
cantidad de clases de colecciones que hay en
el .NET Framework.
No se pierda el próximo mes que tenemos un extenso monográfico de SQL Server
2005, donde han colaborado muchas personas para hacerle llegar la mejor información.
Espero que le guste.
<<dotNetManía
Dedicada a los profesionales de la plataforma .NET
3
16
dnm.sumario
De igual a igual: ¿es legal el intercambio de ficheros en la Red?
10-11
La legalidad de las copias de las obras de creación, y especialmente de las musicales y
cinematográficas, efectuadas por usuarios finales mediante el recurso a las redes de
intercambio de ficheros de igual a igual (p2p) ha sido defendida y contradicha en numerosas
ocasiones en España. Tal vez sea el momento para hacer una aproximación al fenómeno
con una cierta mayor distancia y, especialmente, dejando al usuario la opción de elegir
cual debe ser su conducta al respecto.
Entrevista a Nuria Oliver
12-14
Nuria Oliver es investigadora en Microsoft Research en Estados Unidos. Previamente
estuvo en el mítico Media Lab del MIT (Massachusetts Institute of Technology). Su
trabajo se basa fundamentalmente en la interacción de las máquinas con el ser humano
a través de la percepción de éstas del mundo que les rodea.
Generando hojas Excel con ASP.NET
15-19
Hoy en día las hojas Excel se han convertido en un estándar para representar información
financiera, de control de stock, etc. Cuando hablamos de ASP.NET solemos tener asociado
el HTML como formato de representación de la información, otras alternativas nos hacen
pensar en problemas de rendimiento, o herramientas con un coste elevado, ¿existe alguna
forma sencilla de hacer esto con .NET?
dnm.sumario
¿Qué es Microsoft WSE?
20-26
Microsoft WSE es un nuevo módulo de componentes .NET que permite extender el
marco de trabajo de .NET Framework 1.1 para poder desarrollar servicios Web
XML con características avanzadas. WSE es algo que, sin embargo, al no tenerlo
disponible directamente con Visual Studio 2003 no es muy conocido por el momento,
pero si se quiere desarrollar un servicio Web XML complejo, hoy en día, la única
opción es basarse en WSE 2.0. La intención de este artículo es simplemente dar una
visión de alto nivel de qué es WSE y cómo se integra mediante SOAP con .NET 1.1
y Visual Studio 2003.
Creación de complementos en Visual Studio .NET
28-34
Aunque Visual Studio .NET es uno de los mejores entornos de desarrollo jamás creados,
siempre habrá funcionalidades que echemos en falta. Afortunadamente Microsoft ya pensó
en ello y nos permite añadir nuestras propias funcionalidades a medida mediante
complementos, que aprenderemos a crear en este artículo.
Interfaces.Yo implemento, tu implementas,... ¡implementemos todos!
36-39
En este primer artículo de esta nueva seccción explicamos los Interfaces. Los interfaces son
unos de esos elementos de .NET Framework que juegan un papel bastante importante,
pero que, a pesar de estar por todas partes, aparentemente pasan desapercibidas...
Herencia: ¿To be or not to be?
41-46
En este artículo se demuestra por medio de patrones cuando la herencia es una buena
opción y algunos síntomas que nos pueden indicar cuando usarla se puede convertir en un
problema y cómo resolverlo.
dnm.mvp.online
47-48
Aviso para navegantes
dnm.comunidad.net
50-51
El sitio de “El Guille”, un sitio con más de ocho años de historia
dnm.todotnet.qa
52-54
Acceso a datos y contenedores de datos.
dnm.biblioteca.net
57
ADO.NET and System.Xml 2.0 (Alex Homer, Dave Sussman y Mark Fussel)
C# 2.0: Practical Guide for Programmers (Michel de Champlain y Brian Patrick)
dnm.desvan
58
dnm.noticias
6
noticias.noticias.noticias.noticias.noticias.noticias
<< dotNetManía
<<
dnm.noticias
Microsoft celebró el Developer Days de Madrid
Microsoft reunió a cerca de mil desarrolladores a los que hizo partícipes de
las novedades tecnológicas deVisual Studio Studio 2005 y SQL Server 2005
el entorno de ejecución .NET
2.0”, una de las más esperadas,
en la nos habló del soporte para
64 bit del nuevo CLR y de la
librería de clases, así como de la
depuración, con las nuevas
características, como la tan
demandada “editar y continuar”
a la que estaban acostumbrados
los desarrolladores de Visual David Salgado,David Carmona y Fernando Guerrero
Basic 6 y que ahora volveremos a
profiles como una de las novedades más
tener, incluso los desarrolladores de C#,
difundidas y también solicitadas por los
así como de otras mejoras del depuradesarrolladores, así como un breve repador. Además habló, cómo no, de los
so a los nuevos controles. Pero no menos
genéricos (generics), y de sus venimportante, por no decir que más, era
tajas y desventajas. Terminó con
aprender sobre el acceso a datos y comun extenso resumen de las noveponentes de negocio. Con los nuevos
dades de los lenguajes VB.NET
controles como el GridView o el
y C#.
DetailsView y, sobre todo, cómo traDespués de un merecido
bajar
en dependencia de la caché de
descanso, vino la ponencia
SQL.
Por último, un vistazo a los nue“Desarrollo de clientes intelivos
servicios
de seguridad y Webparts.
gentes: Windows Forms 2.0 y
Después de la comida, Fernando
Visual Studio Tools for Office”
Guerrero, de Solid Quality Learning,
que expuso Pablo Peláez, de
que como Regional Director estuvo en
Visual Programming y Regional
su primer DevDays. Su conferencia
Director de Microsoft, en la que
“SQL Server 2005 para desarrolladores”
nos explicó cómo desarrollar
Mauricio Ulargui para MS Office 2003 desde
en la que hizo un repaso a todas las novedades de SQL Server 2005 que al menos
.NET con esta nueva versión, desde las
Este año, las conferencias tuvieron
nos sirvió para tener una visión genérinovedades, como la integración del disecomo denominador común las nuevas
ca de las principales novedades:
ño, el soporte para controles adminiscaracterísticas y mejoras de Visual Studio
Integación del CLR, mejoras de T-SQL,
trados, las mejoras del modelo de pro2005 y SQL Server 2005.
XML y SQL Server 2005, especialmengramación, las nuevas capacidades de la
Después de la pequeña charla de prete del Service Broker (del que hablará más
caché, el soporte ClickOnce, etc.
sentación de Mauricio Ulargui, director
extensamente en el próximo número de
Entonces intervino César de la
de desarrolladores .NET de Microsoft
dotNetManía) y algunas de las mejoras
Torre, de Renacimiento, uno de los
Ibérica, empezaron las charlas técnicas
de ADO.NET.
profesionales que más sabe de Web
con Alejandro Mezcúa, de byteabyte.net
Enseguida nos relajamos un poco
Services en este país y que, sin embarcon su sesión “Dispositivos móviles en
con la ponencia “Gestión del ciclo de
go, nos habló de ASP.NET 2.0 :-). Su
Visual Studio 2005”. En esta sesión se
vida completo de un proyecto software:
charla fue “Novedades en el desarrollo
vieron las principales novedades y difeVisual Studio Team System”, también
de aplicaciones Web ASP.NET 2.0”. Por
rencias de .NET Compact Framework
muy esperada y en la que Pablo Peláez,
supuesto, tuvo que hablar sobre las nue2.0 con respecto a la versión anterior. De
David Salgado y David Carmona (estos
vas master pages, los themes y skins y los
la misma forma, se mostró cómo se ha
últimos de Microsoft Ibérica)
mejorado Visual Studio para
nos explicaron de una forma
incorporar nueva funcionalidad
divertida la utilidad de las ediorientada al desarrollo para disciones Team System.
positivos. Por último, se hizo hinPara finalizar, Pablo
capié en las mejoras con respecto
Motos,
un cómico español,
al acceso a datos y se demostró
consiguió hacernos reír un rato
cómo crear y utilizar bases de datos
con uno de sus monólogos y así
SQL Mobile desde dentro del
relajarnos un poco después de
entorno de desarrollo de Visual
una jornada maratoniana.
Studio 2005.
Sirve este DevDays como
En la siguiente ponencia,
aperitivo de su hermano mayor:
Leonardo Díez, de Danysoft,
Tech-Ed 2005.
expuso su charla “Novedades en
Microsoft organizó el día 17 de
mayo en los cines Kinépolis, el
Microsoft Developer Day de Madrid al
que asistieron alrededor de 1000 personas. Éste es un evento gratuito que
organizan también en otros muchos
lugares del mundo, las oficinas locales
de Microsoft con el apoyo de los
Regional Directors y otros partners,
donde se reúne a la comunidad de desarrolladores, para hacerles partícipes de
las novedades tecnológicas y que pretende ser un punto de encuentro entre
Microsoft y los desarrolladores.
<< dnm.noticias
dotNetManía nº 17 julio/agosto: Monográfico SQL Server 2005
Estamos
preparando
para el próximo número,
el del verano,
un monográfico sobre
Microsoft
SQL Server
2005, en un
número que
tendrá más
páginas de lo habitual y con el que esperamos poder repartir entre los suscriptores la última versión CTP de SQL Server
2005 (aún por confirmar). Por supuesto,
contaremos con algunos de los mejores
profesionales.
El borrador del índice es el siguiente:
- Una nueva generacion de sistemas de gestión de la información (Fernando
Bocigas).
- Entrevista a Paul Flessner (vicepresidente senior de aplicaciones de servicdor en
Microsoft)(aún por confirmar) y a César
Galindo-Legaria (del equipo de desarrollo
de SQL Server 2005 en Redmond)
(Marino Posadas).
- Alta Disponibilidad en SQL Serveer 2005
(Miguel Egea).
- Business Intelligence en SQL Server 2005
(Salvador Ramos)
- Introducción a SMO: SQL Server 2005
como modelo de objetos programable
(Marino Posadas)
- Service Broker (Fernando Guerrero)
- Soporte XML en SQL Server 2005
(Eladio Rincón)
- Integración del CLR en SQL Server 2005.
Ejecutando código administrado desde el
núcleo del motor de datos.(Luis Miguel
Blanco)
- T-SQL 2005, más productivo que nunca
(Pepe Hevia)
- SQL Server 2005 Mobile Edition, continúa la evolución (José Miguel Torres)
- SQL Server 2005 Express Edition, el
menor de la familia (Pedro Pozo).
Además de algunos contenidos extras
en algunas de las secciones habituales,
como:TodotNet Q&A, MVP online,
biblioteca, desván, opinión, etc.
Avalon e Indigo Beta1 RC pública
Microsoft acaba de hacer pública el conjunto de herramientas para el desarrollador
de Longhorn WinFx que comprende por
ahora a Avalon, el próximo susbsitema de
presentación e Indigo, el próximo subsistema de comunicaciones, y que actualmente
estaban sólo disponibles para suscriptores a
MSDN o betatester.
Estas tecnologías están disponibles para
ser ejecutadas desde Windows XP o
Windows Server 2003 y están pensadas para
que los desarrolladores podamos empezar a
experimentar con estas nuevas tecnologías
antes de la aparición del sistema operativo
Windows Longhorn.
Esta beta 1 RC soporta Visual Studio
2005 Beta 2 y .NET Framework 2.0 Beta 2.
Al conjunto se le ha llamado “Avalon”
and “Indigo” Beta1 RC, y puede descargarse de la página de descargas de
Microsoft o llegar desde los centros de
desarrollo de Avalon (http://msdn.microsoft.com/longhorn/understanding/pillars/avalon) o Indigo (http://msdn.microsoft.com/
Longhorn/understanding/pillars/Indigo) donde además podrá encontrar toda la información que precise.
Más información sobre Indigo en este mismo número en el artículo “¿Qué es WSE?”
Solid Quality Learning University celebró su primer SQLU
Summit en Madrid
Durante los días 25 al 29 de mayo pasados, Solid Quality Learning organizó de común
acuerdo con Microsoft Ibérica, el primer SQLU Summit en España
para enlazar sin fricciones con la temática general de los seminarios de SQL Server.
Este evento, que va a tener una periodicidad anual en cada
ciudad, se trasladará tras el verano al otro lado del Atlántico, para
volver a España de nuevo el año 2006. Mientras tanto este mismo tipo de evento va a ser organizado en los Estados Unidos de
Norte América y otros países de habla inglesa.
dnm.noticias
<< dotNetManía
Estos seminarios los impartieron un total de
12 mentores de Solid Quality Learning, expertos en diferentes especialidades, llegados hasta
Madrid tanto desde diferentes lugares de España como desde
varios países de América. Estos mentores son en su gran mayoría MVP y Directores Regionales de Microsoft, y enfocaron el evento desde una vertiente puramente práctica y tendente a ofrecer
consejos concretos a los asistentes al mismo.
El objetivo de este summit era el de ofrecer formación avanzada y de calidad a los usuarios avanzados de SQL Server y .NET
de España. Un total de 75 profesionales asistieron a este evento,
desde importantes empresas y entidades públicas, formando un
grupo de sumo interés por la variedad de sistemas y necesidades
específicas que reunía, enriqueciendo enormemente el evento
con sus experiencia particulares.
El evento cubrió temas de .NET pero fundamentalmente en
lo que se refiere a técnicas de acceso y representación de datos,
7
<< dnm.noticias
Nuevo Microsoft Windows Mobile 5.0
Hawaii, sucesor de Orcas
Microsoft presentó Windows Mobile 5.0 (Magneto) en
el Mobile & Embedded DevCon
Hawaii es el nombre en clave del
nuevo Visual Studio que sucederá
a Orcas, sucesor de Visual Studio
2005, todavía en beta2
Desde el año 2000 que apareció el primer Pocket PC 2000
y más tarde 2002, hasta los
Windows Mobile 2003, 2003
Second Edition y finalmente
5.0 (¿por qué no le habrán llamado Windows Mobile 2005?) han pasado sólo 5 años en los que hemos asistido
a un avance y aceptación increíble de
estos dispositivos.
Bill Gates hizo público el anuncio de
la disponibilidad, a partir del 10 de mayo,
de Windows Mobile 5.0, la nueva plataforma para dispositivos móviles en la conferencia Microsoft Mobile & Embedded
DevCon, donde destacó algunas de las mejoras y nuevas características introducidas,
muchas de ellas a petición de los partners,
entre las que se encuentran: Versión de
Windows Media Player 10 Mobile; una
nueva versión de Office Mobile, que incluye un nuevo Powerpoint Mobile; soporte
nativo para redes de alta velocidad 3G, WiFi y mejoras en el soporte Bluetooth; soporte para teclado QWERTY; orientación de
la pantalla en modo panorámico; mayor
capacidad de almacenamiento y soporte adicional para dispositivos USB 2.0; nuevas
mejoras en la seguridad, cumpliendo con el
estándar FIPS 140-2 del gobierno de
EEUU; un nueva aplicación de fotografía
y vídeo, soporte de ActiveSync 4.0, el uso
de la tecnología gráfica D3DMobile, etc...
Además de estas nuevas características y mejoras para los usuarios de este sistema, también incluye novedades para los
desarrolladores tanto de código nativo
como de código administrado. El nuevo
SDK de Windows Mobile 5.0 está diseñado para Visual Studio 2005 y SQL
Server 2005 y puede funcionar con las
betas actuales de ambos productos. De
hecho ya pueden descargarse los correspondientes SDK, tanto para Pocket PC
como para SmartPhone desde la página
de descargas de Microsoft.
Windows Mobile 5.0 soporta código
administrado, en tanto que todos los dispositivos que lo lleven, tendrán el .NET
Compact Framework 1.0 SP 3 instalado
en la ROM, y aporta un conjunto de nuevas API accesibles desde el código administrado de .NET.
Más información
- Página de Microsoft para desarrolladores de
Windows Mobile 5.0: http://msdn.microsoft.com/
mobility/windowsmobile.
- Instrucciones para la instalación con la beta 2
de Visual Studio 2005: http://msdn.microsoft.com/
mobility/windowsmobile/howto/windowsmobile5/install.
- Página independiente donde encontrará una
revisión exhaustiva de Windows Mobile 5.0:
http://www.mobile-review.com/pda/articles/
wm2005-magneto-en.shtml.
Según publica Darryl K. Taft de
eWEEK en su artículo “'Hawaii': A Visual
Studio Paradise for Developers?”, la nueva versión que sucederá a Orcas se llama en
clave Hawaii. Quizá lo menos importante
sea lo del nombre, sobre todo si tenemos
encuenta que en el citado artículo se asegura que será una versión totalmente remodelada de Visual Studio.
Según la citada fuente, mientras que
Whidbey nos ayudará a acercarnos a
Longhorn, Orcas será la versión que nos
permitirá “cabalgar” en lo que la compañía
llama “la ola de Longhron” y conectar con
las nuevas características de dicho sistema
operativo. Hawaii vendrá poco después de
Orcas, para aportarnos más funcionalidad
específica de Longhorn.
Según Tony Goodhew, product manager de Microsoft, “estamos sentando las
bases para una completa rearquitectura de
Visual Studio post Orcas”. Sin determinar
la fecha, se piensa que Microsoft tiene pensado tener en el mercado estas dos versiones antes de 2010.
Sin embargo, largo nos lo fían, estaremos pendientes de Orcas, como hace
Anders Hejlsberg, que está trabajando
duramente en la mejora de los compiladores para la siguente versión.
Si está interesado, puede leer el artículo completo (en inglés, eso sí) en:
(http://www.eweek.com/article2/0%2C1759%
2C1815855%2C00.asp)
Se inaugura campusMVP
<< dotNetManía
Campus MVP es una iniciativa de formación eLearning con contenidos de alta calidad en
tecnologías Microsoft impartidos por los mejores expertos del sector.
8
Desde mediados del pasado mes de
mayo inició su andadura campusMVP,
el nuevo proyecto de formación online de Krasis.
Realizado con la colaboración de
algunos de los Más Valiosos Profesionales (MVP) de
Microsoft, ofrece formación en-línea de calidad en tecnologías de Microsoft.
campusMVP ofrece cursos cortos, especializados y asequibles dirigidos especialmente a profesionales de la informática y departamentos técnicos de empresas que necesiten mantenerse al día en su trabajo o ampliar conocimientos
dentro de su plan de progresión profesional o de formación continua.
En la Web de campusMVP (www.campusmvp.com)
encontrará toda la información sobre el proyecto, el catálogo de cursos en los que se podrá matricular directamente on-line, un boletín de novedades, así como importante
información acerca de cómo conseguir los cursos de manera gratuita si es usted un trabajador en activo de una empresa española.
También dispone de la posibilidad de realizar un primer curso gratuito. Se trata de “Seguridad avanzada de
Internet Information Server”.
dnm.noticias
dnm.legal
José Antonio Suárez
De igual a igual: ¿es legal el intercambio
de ficheros en la Red?
La legalidad de las copias de las obras de creación, y especialmente
de las musicales y cinematográficas, efectuadas por usuarios finales
mediante el recurso a las redes de intercambio de ficheros de igual
a igual (p2p) ha sido defendida y contradicha en numerosas ocasiones en España.
<< En la polémica, que ya tiene una cierta antigüedad, en tér-
José Antonio Suárez
es socio director de Suárez
de la Dehesa Abogados,
despacho especializado en
Propiedad Intelectual e Industrial
y Nuevas Tecnologías.
minos de lo que los usuarios de la Red entienden como
antiguo, ha prevalecido el ruido mediático de quienes
defienden, muchas veces con más voluntad que conocimiento jurídico, lo que llaman la legalidad de la copia
en red. Y la prueba de ello es que en tales defensas se
han manejado conceptos sociales y políticos, y casi
nunca jurídicos.
Tal vez sea el momento de hacer un análisis de
la cuestión empleando exclusivamente los argumentos que se han descartado, es decir, los argumentos los jurídicos. Y hacerlo empleando un lenguaje que haga el discurso accesible a quien simplemente sepa leer.
Para que el intercambio de ficheros que contienen obras de creación (música, películas) sea posible,
es preciso que una persona acceda al soporte de fijación de dichas obras (grabadas en CD o DVD), reproduzca (copie) dicha obra en un sistema de almacenamiento (por ejemplo un disco duro fijo o removibles
de su ordenador) y permita a terceros el acceso, libre
o condicionado, a tal reproducción. Acceso que se
produce a través de una red, como es el caso de
Internet. Una vez que la obra fijada es accesible desde la red, cualquier tercero que tenga acceso a dicho
sistema de almacenamiento podrá hacer una nueva
reproducción de ella en su propio sistema.
Almacenamiento que, a su vez, puede ser accesible a
otros terceros que cumplan sus mismas condiciones,
con lo que el número de posibles copias crece de forma exponencial, como lo acredita el dato de que las
copias en red sólo de obras cinematográficas sobrepasan los cinco millones de ejemplares diarios.
La copia de una obra de creación contenida en un
soporte es un acto de reproducción, que, como norma general, requiere de la autorización de su titular.
El artículo 31.1º del español Texto Refundido de la
Ley de Propiedad Intelectual, como los sistemas jurídicos de nuestro entorno, reconocen al propietario de
un soporte legítimo, la posibilidad de copiar la obra
que contiene para su uso personal, y siempre que dicha
copia no sea objeto de utilización colectiva ni lucrativa. Se trata, en definitiva, de un límite al derecho del
titular; o, si se quiere, de una excepción al derecho de
autorizar la reproducción. Pero lo que nunca será es
Es evidente, más allá de toda duda, que
cuando la copia realizada para uso
privado se expone al uso, y en este
caso la reproducción, de terceros,
pierde su carácter de copia privada,
pues incumple el requisito de que no
sea objeto de uso colectivo
<< dnm.legal
...la difusión al público de una obra de creación
sin autorización de su titular, el acto es ilegal
Es más, tanto quienes ponen a disposición como
quienes copian en la redes de intercambio no sólo
obtienen una ganancia (aunque sea en forma de no
gasto), sino que causan un perjuicio a terceros, desde los autores a los intérpretes, pasando por los productores. Y cuando en una conducta defraudadora
de los derechos de propiedad intelectual concurren
ánimo de lucro y perjuicio de tercero, nos estamos
adentrando en un territorio verdaderamente peligroso, como es el del Código Penal.
Bien es verdad que en Derecho, como en todas las
ciencias sociales, y en las exactas desde Einstein, todo es
relativo, pero lo cierto es que pocas veces la letra de la
Ley es tan clara. Por ello, quien ponga a disposición ficheros conteniendo obras protegidas, aunque las copie para
su uso personal, debe ser consciente del riesgo que ello
conlleva, en caso de ser descubierto.
<<dotNetManía
un derecho del propietario del soporte, ya que quien
compra tal soporte no adquiere derecho de propiedad
alguno sobre la obra que contiene, como claramente
indica el artículo 3º del Texto Refundido de la Ley de
Propiedad Intelectual, algo que, por cierto, dice, desde 1888, el artículo 377 del Código Civil.
Es evidente, más allá de toda duda, que cuando la
copia realizada para uso privado se expone al uso, y en
este caso la reproducción, de terceros, pierde su carácter de copia privada, pues incumple el requisito de que
no sea objeto de uso colectivo. Por ello, tal copia debe
calificarse de ilegal, y a quien la ha confeccionado de
infractor de los derechos de propiedad intelectual.
Cuando el sistema de almacenamiento en el que
se ha alojado dicha copia ilegal se abre a terceros a través de una red de comunicaciones, se está haciendo
posible el acceso a las personas que emplean dicha red
a las obras copias; sin que para ello haya sido necesario entregar a cada una de dichas personas un ejemplar del soporte de la obra. Conducta ésta que nuestro sistema legal (artículo 20.1 del Texto Refundido
de la Ley de Propiedad Intelectual), y los de más de
ciento ochenta países, califican de acto de comunicación pública, y, por tanto, también sujeto a la autorización de su titular, y no sujeto a límite alguno de uso
privado, pues la limitación o excepción del artículo
31.1º sólo se refiere al copiado, y no a la comunicación pública. Por ello, la difusión al público de una
obra de creación sin autorización de su titular, el acto
es ilegal.
En este preciso punto podemos concluir que el
copiado de música o películas cinematográficas contenidas en soportes (CDs o DVDs) y su posterior puesta a disposición de terceros a través de redes de intercambio de igual a igual, supone la comisión de dos
tipos de infracciones perfectamente identificadas en
nuestro Texto Refundido de la Ley de Propiedad
Intelectual.
La persona que a través de una red de intercambio
accede a la obra y es sorprendida puede pretender ignorar todo lo anterior, y alegar en su defensa que ignoraba
la ilegalidad tanto de la copia como de
la puesta a disposición del promotor de
tal cadena. A priori no hay razones para
no respetar el principio de presunción
de inocencia, pero ésta no parece que
concurra en quien, a su vez, pone a disposición de terceros las obras que ha
copiado, aunque dicha copia se haya
hecho de las obras puestas a disposición
por otros. O en quien, sin pago alguno,
obtiene copias de aquellas obras de
reciente aparición en el mercado musical o cinematográfico, y no precisamente
de forma gratuita. Aunque tales copias
sean para su exclusivo uso personal.
Uno de los argumentos más utilizados para excusar estas conductas, que, como
vemos, inciden en la ilegalidad, es declarar que en
tales conductas no hay ánimo de lucro. Declaración
que sólo quiere evitar que el problema se traslade
al ámbito penal. Sin pretender entrar en el análisis
de lo que por ánimo de lucro entienden nuestros
Tribunales, es preciso recordar que “ánimo de lucro”
no es equivalente a buscar y obtener una ganancia
económica directa para sí, sino que en Derecho es
sinónimo de cualquier provecho, beneficio, ventaja o utilidad que se obtenga por el propio individuo, incluido el ahorro de costes, o que éste consiga para un tercero, aún en el caso de que él mismo
no se beneficie en forma alguna.
11
Por Marino Posadas
MVP Visual Developer C#
Alhambra-Eidos www.elavefenix.net
Entrevista a Nuria Oliver
Nuria Oliver es investigadora en Microsoft Research en Estados Unidos.Previamente
estuvo en el mítico Media Lab del MIT (Massachusetts Institute of Technology). Su trabajo se basa fundamentalmente en la interacción de las máquinas con el ser humano a través de la percepción de éstas del mundo que les rodea.
<< Revisando tu currículo, veo que tus comienzos en la ciencia fue-
Marino Posadas es
asesor técnico y
redactor de
dotNetManía, MVP de
C# y formador de
Alhambra-Eidos
ron en la Universidad Politécnica de Madrid. El año
pasado, coincidí precisamente con la profesora
Carmen Costilla en unas conferencias que dimos
para la Universidad de Santiago de
Compostela, donde yo hablaba de
Longhorn y ella de la Web semántica. ¿La conoces? ¿y crees que la Web
semántica, -como ella lo ve- es la Web
inevitable dentro de pocos años?
Me parece buena idea y probablemente necesaria para garantizar la
supervivencia del World Wide Web. El
objetivo es crear un modo eficiente
de representar los datos en el World
Wide Web como una base de datos
conectada globalmente. De esa manera, la información podría ser procesada fácilmente por máquinas en todo
el mundo. Tim Berners-Lee, el
inventor de WWW, URLs, HTTP
y HTML, propuso el concepto de la
Web semántica y hay un equipo en el
consorcio W3C dedicado a mejorar,
extender y estandarizar la Web.
Antes de pasar a temas más próximos a tu trabajo, una cosa más
sobre Internet: Si el objetivo es que
el usuario estándar tenga cada vez
más ancho de banda, en un largo
viaje hacia Internet2, ¿cómo va cambiar nuestras
vidas cuando eso sea así? Tú misma, comentas que
ahora realizas una buena parte de tu trabajo en
casa...
<< dnm.directo.entrevistas
Una consecuencia obvia es que estaremos conectados a Internet todo el tiempo, desde cualquier lugar:
la oficina, casa, el teléfono móvil, etc… El mundo digital y el mundo físico estarán más interconectados que
nunca. Podremos trabajar desde cualquier lugar.
Estaremos conectados no sólo a toda la informacion
del WWW, pero también a familiares y amigos; podremos ver, transmitir y recibir vídeo y audio en tiempo
real… hay tantas posibilidades… al mismo tiempo,
creo que es muy importante para nuestra salud mental y física el saber y poder desconectar. El exceso de
informacion causa ansiedad y confusión.
Háblanos algo de tu experiencia en MIT
(Massachusetts Institute of Technology). En un artículo
tuyo para El Heraldo de Aragón lo defines como centro mítico... ¿Es cierto? ¿En MIT se ve el futuro antes
que en ninguna otra parte? Y, ¿conoces a otros españoles que estén allí en labores de investigación? Te lo
pregunto, por un artículo tuyo: “El modelo educativo del Media Lab”.
El MIT es una de las mejores universidades del
mundo –si no la mejor—para las ingenierías y la informática. Tanto los estudiantes como los profesores de
MIT son excepcionales. La vida en MIT es muy intensa, una experiencia única. Yo estuve investigando
durante cuatro años y medio en el Media Lab de MIT,
que es un centro muy especial. Fue fundado por
Nicholas Negroponte en 1985 y la idea era crear un
centro de investigacion multi-disciplinar que innovara y, en cierto sentido, delineara el futuro en áreas tan
diversas como la música, el arte digital, la educacion,
la comunicación hombre-máquina, el cine, la informática cuántica, etc… En ese sentido, el Media Lab
es único. En los últimos años parece haber sufrido un
cierto declive y creo que ahora están reinventando cuál
es el futuro papel del centro dentro de MIT y de la
comunidad científica. En cualquier caso, todavía se
respira esa energía creativa que lo caracteriza y estoy
segura de que seguirá innovando como hasta ahora.
Una característica importante del estilo de investigación americano es la de asumir riesgos e intentar
cosas que van en contra del status quo y que parecen
estar destinadas al fracaso. Pienso que no se puede
innovar sin arriesgarse. Es importante analizar los riesgos y ser realista, pero también con cierto optimismo.
Tú ya tienes experiencia como investigadora en
España, y en EE.UU, dentro y fuera de la Academia.
¿Cuál es mejor? ¿La empresa privada -Microsoft-, o
un centro como MIT, rodeada de monstruos como
Marvin Minsky y otros?
El principal motivo por el que estoy en EEUU es
laboral: hasta ahora no he encontrado el modo de
poder realizar mi trabajo en España con condiciones
similares a las que tengo en EEUU. Soy consciente
de que el Gobierno actual esta proponiendo nuevas
iniciativas para fomentar la investigacion en ciencia y
tecnologia en España. Me encantaría poder regresar
a mi país y contribuir con mi trabajo a la mejora de la
calidad de vida de las personas. Pero de momento,
pienso que donde mejor puedo realizar mi trabajo es
aquí, en EEUU.
Con respecto a Academia versus empresa privada,
hay aspectos similares y diferencias. El aspecto más
importante para mí, que son los proyectos de investigación en los que trabajo, es básicamente igual en una
empresa privada que en una universidad. En los laboratorios de investigacion de Microsoft tenemos total
libertad para trabajar en lo que queramos. Una gran
ventaja es que no tenemos que solicitar grants para
financiar los proyectos. Nunca he tenido ningún problema para financiar ninguno de mis proyectos.
También tenemos total libertad para publicar artículos en congresos y revistas científicas. Microsoft
Research tiene una presencia muy fuerte en la comunidad científica. Otra ventaja es que no tenemos que
dar clase. A mí me gusta dar clase, con lo que no me
importaría ese aspecto de la vida en la universidad,
pero al mismo tiempo, las horas de clase son horas en
las que no estás investigando…Una diferencia importante es que no trabajamos con estudiantes tanto como
se trabaja en la universidad. Es quizás el aspecto más
negativo de trabajar en un laboratorio privado. Me
encanta trabajar con estudiantes. Ahora mismo estoy
trabajando con un estudiante de la Universidad
Autónoma de México y estoy disfrutando muchísimo.
Normalmente tenemos estudiantes que vienen a trabajar con nosotros en el verano, durante unos tres
<< dnm.directo.entrevistas
meses. Excepcionalmente tenemos estudiantes durante el invierno, como yo ahora. En Microsoft Research
también podemos colaborar con universidades, dar
clases en la Universidad de Washington, etc…realmente es un paraiso para la investigación. Finalmente,
otro aspecto muy importante para mí es la flexibilidad en el trabajo. Podemos trabajar desde casa, tener
horario flexible, etc… Hoy en día, me parece fundamental ofrecer opciones de flexibilidad en el trabajo.
Studio con el que nos comuniquemos oralmente, por
ejemplo?
Pienso que las herramientas de desarrollo cambiarán, porque cambiará la naturaleza de nuestra
interacción con los ordenadores. Hay muchas áreas en las que el desarrollo de software se vería afectado: por ejemplo, si el ordenador tuviese acceso al
estado emocional del programador, podría adaptar
su estilo de comunicacion, ofrecer diferentes estrategias de ayuda, etc…
Jim Gray me comentaba el pasado
verano que lo que hacía falta no era sólo
inteligencia en las máquinas, sino en la
información misma. En la forma de
acceder a ella. ¿Cuál es tu opinión al respecto?
Hoy en día estamos inundados por
información, por datos que a veces son
útiles, y otras veces no son mas que
spam, basura. Si no disponemos de
modos inteligentes para acceder a la
misma, para discernir lo que es información de lo que no lo es, corremos el
riesgo de que el sistema entero se vuelva inútil. Por lo tanto, es muy importante disponer
de algoritmos inteligentes para acceder a la información que es relevante en cada momento. Esos
algoritmos estarán en algun tipo de ordenador y
por lo tanto la inteligencia de las máquinas se traducirá en modos más inteligentes de acceder a la
información.
Por último, y, a propósito de “Yo Robot”, ¿crees
que en 2025, -pongamos- podrán existir robots del
estilo de los que vemos en la película? No me refiero
a Sony, sino a los de la generación anterior... ¿O es
algo todavía tan lejano como la Computación
Cuántica?
Lamentablemente no he visto la película, porque
no tuvo buenas críticas, pero conozco el tema. La
película sucede en Chicago en el año 2035 y, gracias
al trabajo del Dr. Lanning, los robots son parte de
la vida diaria. Para asegurar que los robots nunca
dañen o desobezcan a los seres humanos, Lanning
los ha programado siguiendo ciertas leyes… hasta
que aparece el modelo NS-5 y las cosas se complican… Hoy en día disponemos de electrodomésticos
inteligentes, aspiradoras que aspiran solas (como
Roomba), coches plagados de sensores, perritos de
juguete que reconocen ciertos comandos, juegan con
pelotas, etc... en cierto sentido, estamos rodeados de
robots. También hay robots humanoides, como ASIMO de Honda. Estamos dando los primeros pasos
en el área, pero hay muchísimos centros de investigación, tanto a nivel universitario como industrial,
trabajando en robótica y pienso que los robots –tanto humanoides como no—estarán cada vez más integrados en la fibra de nuestra vida cotidiana.
<<dotNetManía
Hay muchas áreas en las que el desarrollo de
software se vería afectado: por ejemplo, si el ordenador
tuviese acceso al estado emocional del programador,
podría adaptar su estilo de comunicacion, ofrecer
diferentes estrategias de ayuda, etc…
14
Dentro de tus areas de interés científico, observo
la presencia constante de la búsqueda de patrones y
modelos matemáticos que describan el comportamiento
humano. ¿Cuál te parece que va a ser el siguiente gran
salto en la informática? ¿Ves un futuro (o no tan futuro) sistema operativo que se comunique con el usuario
mediante voz? ¿Para cuándo podría estar lista una cosa
así? ¿Podría Blackcomb, previsto para 2011 llevar algo
parecido? Esto viene por otro artículo tuyo en el que
anticipas algo así: “GWindows: Towards Robust
Perception-Based UI”
Hay muchas áreas de investigacion que podrían
constituir un gran salto en la informática: ordenadores cuánticos, sistemas híbridos con componentes biológicos, ciberorganismos, nanotecnología, y, por
supuesto, la inteligencia artificial y la percepción por
ordenador, que son mis áreas de investigacion. Dentro
de mi campo, sí pienso que cada vez vamos a ver más
ordenadores con capacidad de percibir qué es lo que
sucede a su alrededor, reconocer la situación y reaccionar en consecuencia. Hoy en día ya hay, por ejemplo, robots humanoides que pueden comunicarse con
las personas, tienen capacidad de visión y de habla (un
tanto limitadas, pero aún así existentes), pueden caminar, etc… Hay muchas áreas de nuestra vida cotidiana que se verían muy afectadas (y espero que en sentido muy positivo) si pudiésemos comunicarnos con
los ordenadores de modo similar a como lo hacemos
con otras personas, si hubiese ordenadores en el
ambiente, en nuestra ropa, con capacidad de monitorizar señales vitales, por ejemplo.
¿Cómo crees que van a cambiar las herramientas
de desarrollo? ¿Qué puede ofrecer un futuro Visual
dnm.asp.net
Braulio Díez
Reyes García
Generando hojas Excel con
ASP.NET
Hoy en día las hojas Excel se han convertido en un estándar para representar información financiera, de control de stock, etc. Cuando hablamos de ASP.NET solemos tener
asociado el HTML como formato de representación de la información, otras alternativas nos hacen pensar en problemas de rendimiento, o herramientas con un coste elevado, ¿existe alguna forma sencilla de hacer esto con .NET?
ma dinámica sin apenas consumir recursos del sistema.
Para ello utilizaremos las siguientes tecnologías:
• XML (para los datos que queramos introducir
en la hoja Excel).
• XMLSS/XSL: El formato XML de Excel (usaremos XSL para construirnos una plantilla).
Reyes García
Ha sido consultora “todo
terreno”. Hoy día se dedica al
gratificante mundo de la
docencia.
Braulio Díez
colabora habitualmente con
dotNetManía. Es MCSD en
programación distribuida
con Visual C++.
Trabaja como Solutions
Developer de Avanade.
El proceso consiste en formatear los datos de
entrada a XML, y aplicarles una plantilla XSL
obteniendo así el fichero Excel que enviaremos al
cliente. ¿Complicado? ¿Laborioso? .NET
Framework y Office 2002 nos harán el 90 % del
trabajo, veamos cómo:
• XML: Si leemos de la base de datos utilizando
un dataset, podemos guardar los resultados en
formato XML gracias a un método que esta
clase nos ofrece.
• XMLSS/XSL: No tenemos que estudiarnos los
entresijos del formato XML de Excel, podemos hacer directamente la plantilla con Office
y a la hora de grabar decirle que lo haga en formato XMLSS. Para pasarlos a XSL sólo tendremos que hacer unos pequeños cambios
sobre el fichero generado.
¡Manos a la obra!
Para ver cómo funciona todo esto, vamos a crear un ejemplo sencillo; una hoja de trabajo que calcule el total de horas extras que hemos hecho en
un periodo de tiempo (suponemos que trabajamos
de lunes a viernes y que la jornada laboral es de 8
horas).
La hoja Excel de nuestro ejemplo tiene dos fórmulas, una que calcula el número total de horas extras
que se han realizado en un día (muy complicada…
“8 - total”), y otra que suma el total de todas las horas
extras de ese periodo de tiempo. En la figura 1 se
puede observar cómo quedaría.
Figura 1. Hoja Excel que vamos a crear
Para crearlo ejecutamos MS Excel, le decimos
que queremos crear una nueva hoja, y añadimos las
siguientes celdas:
1
2
A
Fecha
B
Horas Totales
C
Extras
2/07/200
10
=B2-8
<<dotNetManía
<< En este artículo vamos a ver cómo generar hojas Excel de for-
15
<< dnm.asp.net
Dejamos una fila en blanco y, a continuación, mostramos los totales en las celdas B4 y C4 (esta última,
al igual que C2, es una fórmula):
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
<?xml version="1.0"?>
B
C
<<dotNetManía
4 Total Extras =SUM(INDIRECT("C$2:C"&ROW()-2))
16
La formula de la celda C4 no es más que un
sumatorio de todos los valores desde la columna
C2 hasta la actual (la de total) menos dos; de esta
forma cuando añadamos más elementos nos calculará los datos de manera satisfactoria.
Ya tenemos la hoja prácticamente montada,
vamos a darle algo de formato para que tenga mejor
pinta: seleccionamos desde la celda A1 hasta la C1,
y a través de las opciones de menú “formato” y
“celdas”, las ponemos con fuente negrita y color
de fondo gris.
Guardamos la hoja Excel, pero seleccionamos
el formato “XML Spread Sheet” (en español “Hoja
de cálculo XML”), y el nombre del fichero lo ponemos como ”fichero_original.xls” (entre comillas
y con la extensión .XLS, para que lo grabe sin
extensión .XML). Si hacemos doble clic sobre el
fichero, veremos como Excel lo abre sin problemas.
Ya tenemos un fichero Excel en formato XML,
ahora vamos a transformarlo en una plantilla XSL
que nos sirva para cargar datos de forma dinámica.
Copiamos el fichero fichero_original.xls y le ponemos el nombre plantilla.xls. En los fuentes 1a, 1b,
1c y 1d podemos ver una comparativa entre el fichero original y el que modificaremos, las partes que se
insertan están marcadas en amarillo, y las que debemos eliminar en rojo. Abrimos plantilla.xls con
cualquier editor de texto (por ejemplo Notepad) y
hacemos los siguientes cambios:
• Añadimos las etiquetas xsl:template y xsl:stylesheet para definir el fichero como una plantilla XSL; ponemos como raíz TestDataSet que
será el nombre del DataSet del que extraeremos los datos más tarde (fuente 1a).
• Añadimos al final del fichero las etiquetas de
cierre de las dos etiquetas anteriores <xsl:template> y </xsl:stylesheet> (fuente 1b).
• En la entrada <table> quitamos el parámetro
que indica cuántas filas hay en la hoja
(ss:ExpandedRowCount), ya que el número de filas
varará en función de los datos de entrada (fuente 1c).
• Para introducir los campos añadimos una sentencia foreach y cambiamos los datos de la segunda fila por lo que vamos a leer de la base de datos,
que en nuestro caso son: fecha en la que se trabajo y número de horas (fuente 1d).
<xsl:stylesheet version="1.0"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" >
<xsl:template match="TestDataSet">
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
Fuente 1a. Datos para definir la plantilla XSL.
</Worksheet>
</Workbook>
</Worksheet>
</Workbook>
</xsl:template>
</xsl:stylesheet>
Fuente 1b. Etiquetas de cierre
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="4"
x:FullColumns="1" x:FullRows="1">
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="6"
x:FullColumns="1" x:FullRows="1">
Fuente 1c. Quitamos ss:ExpandedRowCount, número de filas variable
<Row>
<Cell ss:StyleID=”s21”>
<Data ss:Type=”DateTime”>2004-07-02T00:00:00.000</Data></Cell>
<Cell><Data ss:Type=”Number”>10</Data></Cell>
<Cell ss:Formula=”=RC[-1]-8”><Data ss:Type=”Number”>2</Data></Cell>
</Row>
<xsl:for-each select=”t_horas”>
<Row>
<Cell ss:StyleID=”s21”>
<Data ss:Type=”String”>
<xsl:value-of select=”Fecha”/>
</Data>
</Cell>
<Cell>
<Data ss:Type=”Number”>
<xsl:value-of select=”Horas”/>
</Data>
</Cell>
<Cell ss:Formula=”=RC[-1]-8”><Data ss:Type=”Number”>2</Data></Cell>
</Row>
</xsl:for-each>
Fuente 1d. foreach y nombre de campos.
<< dnm.asp.net
public DataSet CreateTestDataset()
{
// Ojo con el nombre, tenemos que usar el
// mismo en el XSL de Excel
DataSet testData = new DataSet("TestDataSet");
// Lo mismo aquí con el nombre
DataTable dtHoras = new DataTable("t_horas");
// Creamos las columnas de nuestra "tabla"
DataColumn dcHoras;
dcHoras
= new DataColumn();
dcHoras.ColumnName = "Fecha";
dcHoras.DataType = Type.GetType("System.String");
dtHoras.Columns.Add(dcHoras);
El código que aplica la plantilla Excel a cualquier
DataSet, lo he encapsulado en una clase para que pueda ser reutilizado fácilmente en otros proyectos. Ésta
contiene dos métodos: SendExcelStreamToClient y
SendExcelStreamToFile.
• SendExcelStreamToClient: se le pasa como parámetro el DataSet y el objeto Response. Transforma
el primero a una hoja Excel y usa el segundo para
enviarla al navegador del cliente.
• SendExcelStreamToFile: se le pasa como parámetro el DataSet y la ruta completa de un fichero.
Transforma el primero a una hoja Excel y usa el
segundo para guardarlo en la ruta especificada (por
si se quiere utilizar en una aplicación desktop).
En el fuente 3 se puede ver el código del primer
método, y en el fuente 4 cómo se usa la clase y su método al pulsar el botón de “Exportar a Excel”.
/// <summary>
/// Carga la plantilla, la aplica contra el fichero XML,
/// tomamos el stream generado, y lo enviamos al cliente
/// como un fichero Excel
/// </summary>
/// <param name=”Ds”></param>
/// <param name=”response”></param>
/// <returns></returns>
public void SendExcelStreamToClient( DataSet Ds,
System.Web.HttpResponse response)
{
try
{
XslTransform xslTrans = new XslTransform();
dcHoras
= new DataColumn();
dcHoras.ColumnName = "Horas";
dcHoras.DataType = Type.GetType("System.Int32");
dtHoras.Columns.Add(dcHoras);
// Cargamos nuestro XML que genera el DataSet
XmlDataDocument doc = new XmlDataDocument(Ds);
// Le añadimos unos cuantos datos
DataRow curr = dtHoras.NewRow();
curr["Fecha"] = "01/06/2004";
curr["Horas"] = 10;
dtHoras.Rows.Add(curr);
// Cargamos la plantilla de Excel que hemos creado
xslTrans.Load(_pathToExcelXslTemplate);
// Creamos un XPathNavigator que usaremos en la transformación
XPathNavigator nav = doc.CreateNavigator();
curr = dtHoras.NewRow();
curr["Fecha"] = "02/06/2004";
curr["Horas"] = 8;
dtHoras.Rows.Add(curr);
// Transformamos y enviamos los datos
response.AddHeader( “content-disposition”,
“attachment; filename=Testeo.xls”);
response.ContentType = “application/vnd.ms-excel”;
response.Charset = string.Empty;
xslTrans.Transform(nav, null, response.OutputStream, null);
curr = dtHoras.NewRow();
curr["Fecha"] = "02/06/2004";
curr["Horas"] = 8;
dtHoras.Rows.Add(curr);
response.Flush();
response.Close();
curr = dtHoras.NewRow();
curr["Fecha"] = "03/06/2004";
curr["Horas"] = 11;
dtHoras.Rows.Add(curr);
}
catch(System.Exception Ex)
{
// Sólo relanzamos la excepción, implementar a gusto
// del consumidor :-)
throw Ex;
}
curr = dtHoras.NewRow();
curr["Fecha"] = "04/06/2004";
curr["Horas"] = 12;
dtHoras.Rows.Add(curr);
testData.Tables.Add(dtHoras);
return testData;
}
Fuente 2. Creando nuestros datos de test
}
Fuente 3. Este es el método que coge el DataSet, le aplica la plantilla XSL que
hemos creado y envía al cliente la nueva hoja generada
<<dotNetManía
¡Ya tenemos lista nuestra plantilla XSL!, sólo nos
queda crear una página ASP.NET que lea los datos de
una base de datos, los transforme a una hoja Excel y
la envíe al cliente.
Creamos una aplicación Web que llamaremos
ExcelSimple y en la página por defecto le añadimos
una etiqueta y un botón. A éste lo llamaremos
btnExportExcel y nos suscribimos a su evento OnClick.
En dicho evento, cargaremos los datos de una base
de datos, le aplicaremos la plantilla XSL que hemos
creado y le enviaremos stream de memoria con el fichero Excel a nuestro cliente.
Para mantener el ejemplo lo más sencillo y fácil de
instalar posible, he creado el DataSet que obtendríamos
de leer de base de datos en tiempo de ejecución (ni qué
decir tiene que en las aplicaciones reales debemos leer
de una base de datos de verdad), ver fuente 2.
17
<< dnm.asp.net
private void btnExportExcel_Click(object sender,
System.EventArgs e)
{
// Tomamos como path de la plantilla excel
// el de la aplicación web
string TemplatePath =
System.AppDomain.CurrentDomain.BaseDirectory+
“plantilla.xls”;
try
{
MsExcelTransformer msExcelTransformer = new
MsExcelTransformer(TemplatePath);
msExcelTransformer.SendExcelStreamToClient(
CreateTestDataset(), Response);
}
catch(System.Exception Ex)
{
Response.Write(“<p>”);
Response.Write(“<i>El proceso ha fallado, “ +
¿ existe este fichero en tu disco duro ? </i>” +
TemplatePath);
Response.Write(“<BR>”);
Response.Write(“<b>Información Extendida:</b> “ +
Ex.Message);
Response.Write(“/p”);
}
}
Fuente 4. El código que ejecutamos cuando se pulsa
el bóton de nuestra página.
Antes de arrancar el ejemplo tenemos que asegurarnos de que la plantilla XSL que hemos creado está en la ruta de la aplicación (en mi caso es
C:\Inetpub\wwwroot\ExcelSimple).
Ya está todo listo, ejecutamos el ejemplo, pulsamos el botón y… ¡voila!, nos aparece un mensaje de
Internet Explorer, que nos pregunta si queremos abrir
el fichero Excel o guardarlo a disco..., lo abrimos y
vemos nuestro fichero Excel con los datos del DataSet
que le habíamos introducido. En la figura 2 podemos
ver la página ASP de nuestro ejemplo, y en la figura
3 la hoja Excel con los datos que hemos cargado.
Figura 3. La hoja Excel que se carga en el cliente
Otras opciones
Hay más formas de generar ficheros Excel, dependiendo de las
necesidades se puede optar por las que siguen.
Automation
Si lo que se desarrolla es una aplicación desktop, puede
usar Automation, esto es, arrancar Excel como un objeto
COM EXE. La ventaja es que se puede hacer todo lo
que se quiera con Excel; las desventajas son su lentitud,
los recursos que consume, los cambios entre versiones
de Office y los problemas que da con algunas herramientas
de antivirus. Para más información, un buen punto de
partida está en la MSDN, referencia Q316126, “HOW
TO: Use Visual C# .NET to Automate a Running
Instance of an Office Program”.
Librerías gratuitas específicas
Una que tiene muy buena pinta es la desarrollada por
Carlos Aguilar Mares (http://www.carlosag.net/Tools/
ExcelXmlWriter).
Componentes comerciales
Si lo que se necesita es generar archivos binarios de Excel,
se puede optar por librerías como la de Soft Artisans
(http://www.asp.net/ControlGallery/
ControlDetail.aspx?Control=1002&tabindex=2 ), o como
la de Aspose (http://www.aspose.com/Products/Aspose.Excel).
<<dotNetManía
CSV (Comma Separated Values)
18
Si es necesario dar soporte a versiones muy antiguas de
Excel, esto puede valer. Consiste en importar de un fichero de texto que separa cada celda por comas y cada fila
por un retorno de carro, puede encontrar más información en: http://www.creativyst.com/Doc/Articles/CSV/
CSV01.htm
Figura 2. La página ASP de nuestro ejemplo
<< dnm.asp.net
Si no es necesario soportar versiones anteriores a la 2002 de Office, el formato
XML de Excel (XSSL) combinado con las tecnologías XML/XSL se presenta
como un gran aliado a la hora de generar hojas de cálculo de forma dinámica
Nota: Depende de la versión de IE que tenga, le
aparecerá dos veces el mensaje de “Abrir / Guardar”,
esto es un fallo conocido del navegador y hay parches
que lo arreglan.
Este ejemplo está disponible en la Web de la revista, en www.dotnetmania.com.
Limitaciones
No todo el monte es orégano… si bien esta forma de generar Excel es limpia y consume pocos recursos, tiene varias limitaciones:
• El cliente necesita tener instalado Office 2002 o
superior para que pueda leer este formato.
• No se pueden incluir imágenes, ni objetos
ActiveX en la hoja (al menos en Microsoft Office
2002).
Conclusión
Si no es necesario soportar versiones anteriores a
la 2002 de Office, el formato XML de Excel (XSSL)
combinado con las tecnologías XML/XSL se presenta como un gran aliado a la hora de generar hojas de
cálculo de forma dinámica.
Aquí tiene unos enlaces en los que podrá encontrar más información sobre estás tecnologías (los que
no tienen link, son de la MSDN, http://msdn.microsoft.com):
• “Q285891. How to use Visual Basic or ASP to create an XML Spreadsheet for Excel 2002”: Otro
ejemplo sobre cómo crear XMLSS.
• “XML Spreadsheet Reference2”: Descripción
completa del formato XML de excel (XMLSS).
• Un tutorial de XSLT: http://www.w3schools.com/xsl
trucos.trucos.trucos
Leyendo y modificando hojas Excel
Además de generar hojas Excel, hay veces en las que nos
es necesario poder leerlas y/o modificarlas, en este caso ADO
.net nos será de gran ayuda. Cubrir este tema a fondo queda
fuera del alcance de este artículo, no obstante, vamos a ver
un pequeño ejemplo que lea nuestra “hoja de horas” y la vuelque por pantalla:
Puede encontrar más información en los siguientes links:
• MSDN: “How To Use ADO.NET to Retrieve and
Modify Records in an Excel Workbook With Visual Basic
.NET” [kb316934]
• “Import from Excel using ADO.NET” (ejemplo simple
y útil): http://www.dotnetspider.com/technology/kbpages/1080.aspx
static void Main(string[] args)
{
string strConnectionString =string.Empty;
// OJO ! Cuidado con el Path al fichero Excel, si nos equivocamos nos da
// un error que despista un poco... "Could not find installable ISAM"
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ @"Data Source=C:\ejemplo.xls;"
+ "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
while (reader.Read())
{
for(int i =0; i < reader.FieldCount; i++)
Console.Write(" " + reader[i].ToString());
Console.WriteLine();
}
reader.Close();
}
<<dotNetManía
OleDbConnection cn =new OleDbConnection (strConnectionString);
cn.Open();
OleDbCommand cmdSelect = new OleDbCommand (@"SELECT * FROM [Sheet1$]", cn);
OleDbDataReader reader = cmdSelect.ExecuteReader(CommandBehavior.CloseConnection);
19
César de la Torre
¿Qué es Microsoft WSE?
Microsoft WSE es un nuevo módulo de componentes .NET que permite extender el
marco de trabajo de .NET Framework 1.1 para poder desarrollar servicios Web XML
con características avanzadas.WSE es algo que, sin embargo, al no tenerlo disponible
directamente con Visual Studio 2003 no es muy conocido por el momento, pero si se
quiere desarrollar un servicio Web XML complejo,hoy en día,la única opción es basarse en WSE 2.0.La intención de este artículo es simplemente dar una visión de alto nivel
de qué es WSE y cómo se integra mediante SOAP con .NET 1.1 y Visual Studio 2003.
<< ¿Qué es WSE? Bueno, literalmente significa Web Services
César de la Torre
Es Microsoft MVP en
XML-Web-Services, MCSE y
MCT. Profesionalmente es
Arquitecto de Software y Socio
Cofundador de Renacimiento
Sistemas, empresa consultora
Microsoft GOLD Certified
Partner
Enhancements, por lo que simplemente por el nombre vemos que tiene mucho que ver con Servicios
Web XML y con aspectos avanzados de éstos. Sin
embargo, antes de meternos de lleno en qué nos proporciona WSE, vamos a remontarnos un poco a los
orígenes de los servicios Web XML y ver las razones de por qué surgen estos nuevos servicios avanzados para ellos.
Los servicios Web XML surgen debido a necesidades de interoperabilidad entre diferentes plataformas y aplicaciones (antes era un infierno comunicar
aplicaciones, por ejemplo COM, con aplicaciones
CORBA, JAVA, etc.), marcándose como objetivo el
basarse en estándares (como XML, SOAP, HTTP,
etc.). Es muy importante que las comunicaciones entre
aplicaciones (servicios) sean independientes de la plataforma (.NET, Java, etc.), del lenguaje, de los objetos e incluso de los mecanismos de llamada y protocolos de transporte. Estos objetivos son los que conforman SOA (Service Oriented Architecture).
SOA “ve el mundo” de una forma distinta: todas
las aplicaciones deben ser servicios autónomos donde se definan fronteras explícitas y se asuma la heterogeneidad y colaboren plataformas dispares (por
ejemplo, comunicar aplicaciones .NET con aplicaciones Java). Para esto, en lo que ya es la “implementación de SOA en el mundo real” es imprescindible hablar un mismo idioma, es decir, compartir el
mismo formato de datos (XML) y los mismos esquemas XML (esquema de mensajes de comunicación
SOAP). SOA (Service Oriented Architecture), como
algo lógico o “filosofía”, podía haberse implementado con cualquier mecanismo “a inventar”. En este
caso la implementación de SOA, hoy por hoy, se ha
basado en los servicios Web XML implementados
con cualquier tecnología (.NET, Java, etc.).
Los servicios Web XML básicos (y ya centrándonos en plataforma Microsoft) nacen inicialmente como una tecnología básica (protocolo y definiciones de mensajes SOAP, implementados con
SOAP Toolkit para lenguajes compatibles con
COM como VB 6.0, etc.), diseñada ésta y sus estándares de forma abierta (especificaciones teóricas de
servicios Web definidas por diferentes organizaciones como MS, IBM, Sun, etc.) para que fuera
evolucionando en el futuro con otras plataformas
y lenguajes (en este caso de Microsoft), es decir,
.NET Framework.
Efectivamente, cuando apareció .NET (.NET 1.0
y Visual Studio .NET), esta nueva plataforma nos
proporcionaba una serie de clases .NET y un tipo
nuevo de proyecto de Visual Studio para desarrollar
servicios Web XML de una forma extremadamente
fácil (basándonos en ASP.NET y atributos). Como
cualquier desarrollador en .NET habrá podido com-
SOA “ve el mundo” de una forma
distinta: todas las aplicaciones deben
ser servicios autónomos donde se
definan fronteras explícitas y se asuma
la heterogeneidad y colaboren
plataformas dispares
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
dnm.comunicaciones
Los servicios Web necesitan aspectos
más avanzados como cifrado, firma,
mensajería asíncrona, enrutamiento de
mensajes SOAP, etc.
Entonces, centrándonos en los servicios Web
XML básicos proporcionados tanto .NET 1.0 con
Visual Studio .NET como .NET 1.1 con Visual
Studio .NET 2003, lo que se nos ofrecía son las
siguientes características:
• Comunicaciones entre aplicaciones mediante
estándares de Internet (HTTP).
• SOAP como formato de mensajes de comunicación.
• WSDL como definición y descripción de los servicios (aplicaciones WebServices).
• UDDI como localizador de servicios Web.
• Al implementar los servicios Web XML con
ASP.NET (Web-Methods ASMX) tenemos también acceso a toda la funcionalidad de ASP.NET
(sesiones, seguridad, extensiones, etc.).
• Los servicios Web XML de .NET 1.0 y 1.1 consiguen una comunicación básica:
- Proporcionan un intercambio básico de mensajes XML.
- Permiten la interconexión entre sistemas heretogéneos.
- La compartición de esquemas permiten mayores abstracciones.
Pero, la mayoría de las aplicaciones distribuidas
corporativas o comerciales necesitan más…
Se necesitan aspectos más avanzados (no soportados por los servicios Web básicos en .NET 1.0 y 1.1)
como:
- Modelo de seguridad orientado a mensajes
(cifrado, firma, etc.).
- Mensajería estable y confiable.
- Soporte de transacciones entre diferentes servicios Web.
- Mecanismos de direccionamiento y ruteo de
mensajes SOAP.
- Mensajería asíncrona.
- Metadatos para “políticas” de servicios Web.
- Soporte para datos binarios.
La teoría: Especificaciones estándar
(WS-*)
Para definir todas estas necesidades avanzadas, diferentes empresas (Microsoft, IBM, HP, Fujitsu, BEA,
VeriSign, SUN, Oracle, CA, Nokia, CommerceOne,
Documentum, TIBCO, etc.) han estado y continúan
definiendo unas especificaciones teóricas que conformen cómo deben funcionar los aspectos extendidos de
los servicios Web XML.
A todas estas especificaciones teóricas se las conoce como las especificaciones WS-*.
Si alguien quiere conocer en detalle estas especificaciones, lo puede estudiar en: http://www.oasisopen.org.
El siguiente esquema muestra a alto nivel las diferentes funcionalidades que trata de resolver WS-*.
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
Figura 1.
<<dotNetManía
probar, desarrollar un servicio Web XML y consumirlo desde una aplicación cliente remota (ya sea
WinForm o ASP.NET) es algo sumamente sencillo y
es la forma recomendada de realizar aplicaciones distribuidas en tecnología Microsoft para sustituir el antiguo esquema (componentes COM y DCOM como
protocolo de invocaciones remotas).
Por supuesto, en .NET, además de los servicios Web
XML podemos hacer uso de .NET Remoting, pero esto,
a pesar de que actualmente ofrece algunas ventajas (mayor
rendimiento, posibilidad de singleton, diferentes tipos de
serialización, etc.), Microsoft lo desaconseja actualmente en la medida de lo posible, porque primero, .NET
Remoting no es interoperable con otras tecnologías
(requiere .NET en ambos extremos) y segundo .NET
Remoting probablemente se descontinúe con la aparición de Indigo y Windows Longhorn (aunque esta última afirmación de descontinuación de .NET Remoting
todavía no es algo completamente oficial). Así pues, el
caso es que .NET Remoting lo dejamos a un lado en este
artículo porque tiene poco que ver con WSE, que es
nuestro objetivo.
21
<< dnm.comunicaciones
Todos los módulos centrales (seguridad, mensajería confiable, transacciones y metadatos) son precisamente las funcionalidades de las que carecen los
sevicios Web XML básicos y lo que trata de definir
WS-*.
Las especificaciones WS-* están así mismo formadas por subconjuntos de especificaciones:
•
•
•
•
•
WS-Security
WS-Messaging
WS-Transaction
WS-Reliability
WS-Metadata
Éstos a su vez se vuelven a dividir en otros subconjuntos de especificaciones aún más definidas, como
muestra el siguiente cuadro:
<<dotNetManía
Especificaciones WS-*
22
Messaging
• WS-Addressing
• WS-Eventing
• MTOM (Attachments)
>>
Reliability
• WS-ReliableMessaging
>>
Security
• WS-Security
• WS-Trust
• WS-SecureConversation
• WS-Federation
>>
Messaging
• WS-Coordination
• WS-AtomicTransaction
• WS-BusinessActivity
>>
Security
• WS-Policy
• WS-PolicyAssertions
• WS-PolicyAttachment
• WS-SecurityPolicy
• WS-Discovery
• WS-MetadataExchange
WSE realmente tiene ya un largo camino, pero debido a
que su nacimiento está paralelo a la evolución constante de
las especificaciones WS-*,WSE ha ido también cambiando y
creciendo.Al principio solamente teníamos algunas especificaciones implementadas y cada vez vamos teniendo más.
Cuando lleguemos a Indigo, deberíamos de tener la mayoría. La cronología es la siguiente:
<<
WS-* son las especificaciones y estándares, no las implementaciones
>>
Cronología y futuro de WSE
Tabla 1.
WSE 1.0
WSE 1.0 + SP1
WSE 2.0
WSE 2.0 + SP1
WSE 2.0 + SP2
WSE 2.0 + SP3
WSE 3.0
Indigo
Diciembre de 2002
Marzo de 2003
Mayode 2004
Julio de 2004
Diciembre de 2004
Febrero de 2005
? de 2005 (única versión de
WSE que MS promete será
interoperable con Indigo)
? de 2006 ?
Como iréis viendo ya, las especificaciones WS-*
son prácticamente todo un mundo; no es algo pequeño y limitado que simplemente extienda un poco a
los servicios Web XML. Además, son especificaciones todavía en evolución y no cerradas definitivamente.
Bien, hasta ahora solamente hemos hablado de
especificaciones, teoría, pero para que la teoría funcione en el mundo real (desarrollo de servicios Web
XML) hacen falta implementaciones de dichas teorías y especificaciones. Cada fabricante podrá crear su propia implementación de WS-*, pero lo
importante es que cumpliendo la teoría e interfaces
de WS-*, todas las implementaciones de WS-*deberían ser compatibles unas con otras.
¡Es aquí donde aparece Microsoft WSE! WSE
(Web Services Enhancements) es la implementación
actual (de Microsoft) de las especificaciones WS-*
(por ahora, en la versión 2.0 de WSE solamente de
parte de las especificaciones). Me parece muy importante recalcar que WSE es realmente una implementación temporal y en evolución hasta que
Microsoft ofrezca su plataforma completa que debería abarcar la totalidad de WS-*. Esa futura plataforma que abarcará WS-* y muchos más aspectos de
comunicaciones es Indigo (parte de la siguiente versión de Windows Longhorn). Sin embargo, hasta que
dispongamos de Indigo, tenemos que volver al presente y a lo que podemos utilizar ahora para desarrollar servicios Web avanzados, es decir, WSE.
Por otro lado, que nadie se asuste. El hecho de
que WSE esté en evolución no significa que sea una
beta. Es una plataforma de la que van saliendo dife-
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
<< dnm.comunicaciones
rentes versiones (actualmente estamos
en la versión WSE 2.0 SP3), pero todas
ellas están soportadas, es decir, son versiones release con soporte por el departamento de soporte técnico de
Microsoft, por lo tanto, WSE es perfectamente apto para desarrollar proyectos y ponerlos en un entorno de producción.
Pero vuelvo a destacar que, al estar
en evolución WSE, es posible que de
una versión a otra no tengamos compatibilidad hacia atrás en los interfaces y
definiciones de clases de WSE.
el marco de trabajo de los servicios
Web básicos de .NET (ASMX) con
WSE.
Bueno, y ¿como se hace esto?. Pues
precisamente mediante SOAP, el cual
métodos de interfaces necesarios
(ProcessMessage, etc.), con lo que conseguimos implementar un filtro propio
dentro del procesamiento de mensajes
SOAP (ver figura 2).
¿Dónde estamos?
Para resumir y tener una visión global, repasemos la tabla 2.
Plataformas Servicios
Web .NET
>>
>>
>>
ASMX (parte de ASP.NET)
es la plataforma actual de
WS en .NET
• Soporta funciones básicas
para servicios sencillos.
• No implementa las especificaciones WS-*.
WSE 2.0 es una extensión
de la plataforma actual
• Puede utilizarse para
extender el comportamiento de ASMX (como
Security).
• Puede utilizarse de forma
separada sin ASMX
(como Messaging).
• Implementa algunas de las
especificaciones WS-*.
Figura 2. Funcionamiento de filtros propios basados en SoapExtension
da la “casualidad” que en sus cabeceras
está preparado para añadir extensiones
(¿casualidad?, no, SOAP se definió precisamente con “puertas abiertas” a
ampliaciones futuras).
Soap Extensión Framework
Lo que voy a contar ahora no es algo
que necesitemos hacer cada vez que
vayamos a desarrollar con WSE, al contrario, es explicar como Microsoft ha
“enganchado” WSE con la implementación actual de servicios Web XML
(ASMX).
ASMX proporciona un framework
para la extensibilidad. Podemos desarrollar una clase nuestra que será invocada antes y después del procesamiento de cada mensaje SOAP. Estas clases
tienen que heredar de la clase
SoapExtension (clase de .NET
Framework 1.1) e implementar los
En estos filtros o extensiones desarrollados por nosotros podríamos implementar lo que quisiéramos, como por
ejemplo un log de mensajes SOAP recibidos y enviados, o un mecanismo de
seguridad propio donde hiciéramos comprobaciones a nivel de mensajes, etc.
Bueno, pues ¡eso es precisamente
lo que hace WSE basándose en
SoapExtension!, pero en este caso, en
lugar de inventarse los mecanismos y
filtros (como haríamos nosotros) WSE
sigue al pie de la letra las especificaciones estándar marcadas por WS-*.
WSE necesita lo siguiente:
• Escribir cabeceras en los mensajes
SOAP de salida y leer de los mensajes de entrada.
• Transformar el bodyde los mensajes.
Así pues, como hemos dicho, implementa estas acciones mediante filtros
SOAP (SoapExtension).
Indigo es la siguiente generación de plataforma de
Web Services
• Proporcionará una solución completa WS-*.
Bien, entonces estamos actualmente en un punto en que todavía falta bastante hasta que dispongamos de
Indigo, pero queremos desarrollar servicios Web XML con aspectos avanzados. Para eso tenemos que extender
Figura 3.
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
<<dotNetManía
Tabla 2.
23
<< dnm.comunicaciones
<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services2.WebServicesExtension, Microsoft.Web.Services2,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="1" group="0" />
</soapExtensionTypes>
</webServices>
Fuente 1
Siguiendo el mismo esquema, WSE
implementa un filtro por casi cada
aspecto de WS-* que habilita, como
políticas, seguridad a nivel de mensajes,
trazas, lógica de Addressing en el filtro
de Referal, etc.
cio Web XML .ASMX (con
HTTP) donde implementásemos
cifrado de datos y firma electrónica mediante el módulo de Security
de WSE.
2.- La segunda forma de desarrollar
servicios Web XML es sin basar-
nos en ASMX (sin extender los servicios Web de ASP.NET 1.1) y sin
usar siquiera HTTP. Realmente,
el desarrollo de un servicio Web
implica solamente el basarnos en
SOAP y por lo tanto también en
XML como formato de datos, pero
no es obligatorio basarse en
HTTP como protocolo. Teóricamente, el protocolo a utilizar por
un servicio Web XML debería ser
transparente (en .NET 1.1 no es
así, solamente nos podemos basar
en HTTP), y en WSE empieza a
verse esta independencia del protocolo. De hecho, utilizando
Messaging de WSE, podemos desa-
Sobre Indigo
WSE extiende los servicios
Web con nuevos filtros
gracias a SoapExtension
En la figura 3 se muestra el funcionamiento de dichos filtros implementados por WSE.
Donde se configura dicho enlace
en el servicio Web (servidor) entre la
SoapExtension y los assemblies (las
DLL) de WSE (los assemblies que realmente implementan dichos filtros en
el Web Service) es en la sección
<soapExtensionTypes> del web.config,
donde debe aparecer unas líneas similares a las del fuente 1.
La comunicación entre los filtros y
el código de nuestro servicio Web XML
será por supuesto mediante la clase
SoapContext.
<<dotNetManía
Desarrollando con WSE
24
Básicamente hay dos formas de desarrollar servicios Web XML con WSE:
1.- Extendiendo ASMX (servicios
Web XML y HTTP): Haciendo
uso del framework .ASMX y extendiéndolo mediante el mecanismo
que hemos visto antes (basándonos en la extensibilidad de SOAP
y la clase SoapExtension). Ejemplos
de este tipo de WS sería un servi-
Indigo es una plataforma de componentes que proporcionará una
infraestructura de comunicaciones que habilitará a aplicaciones distribuidas o componentes el mandar y recibir datos mediante un sistema
de mensajería unificado. La incorporación de Indigo permitirá asegurar el flujo de mensajes transaccionales, seguros y confiables entre diferentes aplicaciones o servicios que empleen los mismos protocolos
estándares compartidos.
Indigo será el futuro y evolución de las siguientes tecnologías actuales: servicios Web XML,WSE, .NET Remoting,ASMX, System.Messaging,
y .NET Enterprise Services (transacciones distribuidas, etc.), pero aglutinando las funcionalidades de todo lo anterior y muchas otras nuevas en
una única tecnología unificada.
Indigo unificará y ofrecerá lo siguiente:
• Amplio rango de transportes, incluyendo HTTP,TCP, UDP, IPC y
abierto a otros protocolos asíncronos como SMTP, etc.
• Mecanismos de seguridad como claves públicas y simétricas y certificados.
• Topologías, como punto-a-punto y extremo-a-extremo mediante
intermediarios, peer-to-peer y publicación-suscripción.
Debido a que la interoperabilidad es un objetivo importante, Indigo
tiene un gran compromiso con XML, SOAP y todas las especificaciones
emergentes de servicios Web XML avanzados (WS-*) para proporcionar
seguridad, confiabilidad y transacciones a aplicaciones basadas en SOAP.
Como parte de Longhorn,Indigo estará disponible para cualquier aplicación basada en este sistema operativo. Sin embargo, Microsoft afirma
que también Indigo (en su versión definitiva) estará disponible como un
instalable separado para poder instalarlo sobre Windows XP y Windows
Server 2003, si bien algunas funcionalidades solamente estarán disponibles en Longhorn y en la siguiente versión de Windows Server.Actualmente
también se puede bajar una versión beta 1 RC de Indigo desde
http://msdn.microsoft.com/Longhorn/understanding/pillars/Indigo.
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
<< dnm.comunicaciones
rrollar un servicio Web XML que utilice como
protocolo simplemente TCP basándonos en el
puerto TCP que nosotros queramos y se comunique con otro servicio Web de una forma similar a aplicaciones peer-to-peer. Otro ejemplo de
protocolo a emplear (todavía no disponible
directamente en WSE) sería SMTP, un protocolo ideal para servicios Web asíncronos.
También podemos utilizar en WSE un protocolo InProcess para comunicaciones dentro del
mismo proceso.
Simplemente resaltar que este nuevo tipo de
servicios Web XML se desarrollan en nuestros propios procesos (por ejemplo, un servicio Windows)
y no necesitan para nada de ASP.NET ni siquiera
de IIS.
Vamos a centrarnos en el primer caso, que es el
más inmediato y similar a los servicios Web XML
actuales (el segundo caso requeriría un artículo completo sobre WSE Messaging).
Podemos desarrollar con WSE 2.0 extendiendo
ASMX de ASP.NET o también podemos desarrollar
un servicio Web directamente con Messaging en
nuestro propio proceso sin utilizar ASP.NET.
la clase proxy también se llamará Service1 y si
miráis en el fichero donde está definida
(Reference.cs en C# o Reference.vb en VB.NET)
veréis que hereda de la clase del Framework llamada System.Web.Services.Protocols.SoapHttp
ClientProtocol.
Pues bien, si habilitamos el uso de WSE en nuestra aplicación cliente (luego veremos cómo), Visual
Studio nos crea dentro del mismo fichero Reference.cs
una segunda clase proxy que se llama igual que la original pero acaba en el literal ‘Wse’ y que en este
caso deriva de una nueva clase base llamada
Microsoft.Web.Services2.WebServicesClientProtocol,
que como véis pertenece a un espacio de nombres
nuevo Microsoft.Web.Services2 que no está dentro de System (puesto que WSE está en evolución,
por coherencia es mejor que, por ahora, no esté
integrado dentro del namespace Sytem). En nuestro ejemplo anterior, esta segunda clase proxy se
llamaría Service1Wse.
Una vez que disponemos de esta nueva clase proxy,
si cuando vamos a llamar a un WebMethod lo hacemos mediante un objeto instancia de la nueva clase
proxy (en este caso Service1Wse) entonces estaremos
utilizando el nuevo marco de trabajo de WSE. Por
el contrario, si la invocación al WebMethod lo hacemos mediante un objeto instancia de la antigua clase proxy, seguiremos empleando el marco de trabajo
de servicios Web XML básicos de .NET 1.x. Es así
de simple su utilización y siempre podemos utilizar
los dos caminos (invocación a nuestro servicio Web
por WSE o por servicios Web básicos, a elección
nuestra).
Cómo instalar y habilitar WSE en Visual
Studio 2003
En este caso, está claro que si nos basamos en
.ASMX y ASP.NET, estamos, entonces, hablando de
servicios Web XML basados en HTTP.
La gran mayoría del código nuevo a implementar en aplicaciones que usen WSE está mas bien en
el lado cliente (aplicación que consume el servicio
Web XML) casi más que en el lado del servidor (por
supuesto, depende de lo que haga el WS).
Repasando el desarrollo básico de cómo consumir servicios Web XML en ASP.NET de .NET
Framework 1.1, recordaréis que cuando desde una
aplicación cliente añadimos una referencia Web a
un servicio Web XML, Visual Studio nos genera
una clase proxy con el mismo nombre que la clase
del servicio Web. Posteriormente, usábamos un
objeto instancia de esta clase proxy para invocar
los WebMethods del servicio Web. Por ejemplo, si
la clase del servicio Web se llamaba Service1, pues
Instalación de WSE
WSE 2.0 no lo tenemos disponible directamente en Visual Studio 2003. Es lógico, porque su aparición es posterior a Visual Studio 2003. Para poder
trabajar con las librerías de WSE 2.0 e incluso tenerlo integrado con el IDE de Visual Studio 2003, es
necesario bajar el paquete de instalación del sitio
público de Microsoft en Internet. En concreto, la
dirección de download es:
http://msdn.microsoft.com/webservices/downloads/default.aspx
Y ahí, seleccionar el último download de WSE.
Actualmente, la última versión es WSE 2.0 con el
Service Pack 3.
Una vez instalado (por supuesto, siempre teniendo ya primero instalado Visual Studio 2003), si hemos
elegido la opción de instalación para “Desarrollo”,
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
<<dotNetManía
Desarrollando extendiendo ASMX de ASP.NET
25
<< dnm.comunicaciones
entonces, además de tener disponibles
los assemblies de WSE, también se nos
habrá integrado una pequeña aplicación
de configuración de WSE dentro de
Visual Studio 2003.
Habilitar WSE en un proyecto
Para que un proyecto de Visual Studio
2003 (tanto un servicio Web como una
aplicación cliente que consuma al servicio
Web) pueda hacer uso de WSE, simplemente tenemos que tener acceso a los
assemblies (Microsoft.Web.Services2.dll),
namespaces (Microsoft.Web.Services2,
Microsoft.Web.Services2.Security, etc.)
y adicionalmente conocer configuraciones
específicas de WSE que se codifican en el
XML del web.config de cada proyecto
(como las secciones <microsoft.web.services2>, <diagnostics>, <security>, etc.).
Sin embargo, la integración de WSE
con Visual Studio 2003 nos facilita
mucho la vida y la mayoría de las operaciones anteriores (añadir en references,
o añadir secciones del web.config, etc.)
las hace por nosotros dicha aplicación
de configuración integrada en el IDE
de Visual Studio 2003. Esta aplicación
se ejecuta desde la opción “WSE
Settings 2.0...” del menú de contexto de
cada proyecto de Visual Studio 2003:
Figura 5
Por ejemplo, seleccionando la
opción “Enable this Project for Web
Services Enhancements” básicamente
lo que hace es añadir a nuestro proyecto las referencias que necesitamos. Esto
se puede hacer, por lo tanto, en un proyecto de servicio Web XML pero también en el proyecto cliente (ASP.NET,
WinForms, etc.) que consume al servicio Web. Sin embargo, la opción
“Enable Microsoft Web Services
Enhancements Soap Extensions” solamente es posible en proyectos
ASP.NET de servicios Web XML, porque lo que hace por debajo es configurar WSE 2.0 como una soapExtension de
forma que se pueda extender el comportamiento de SOAP mediante cabeceras nuevas. Esto es lo que nos añade
al web.config automáticamente la
segunda opción (solamente el elemento <add>):
tenemos con los servicios Web XML
de .NET Framework 1.1.
Es importante volver a destacar que
WSE es algo temporal y en constante evolución debido a que los estándares y especificaciones en los que está basado están
también en evolución (especificaciones
WS-*).
Esta temporalidad y evolución de
servicios Web XML se entiende que
quedará consolidada y como plataforma completa y estable cuando aparezca
Indigo (siguiente gran salto en componentes y desarrollo de aplicaciones distribuidas basadas en estándares y sobre
todo en servicios Web). Indigo es uno
de los módulos principales de Windows
Longhorn, aunque ya tenemos disponible una versión beta instalable de
Indigo sobre Windows XP o Windows
Server 2003.
Actualmente (versión 2.x de WSE)
Microsoft advierte que el modelo de
objetos y programación es muy diferente de WSE a Indigo, sin embargo,
cuando aparezca WSE 3.x, dentro de
muy poco tiempo, Microsoft promete
que será interoperable con Indigo.
Por último, destacar otra vez que
aunque WSE está en evolución, esto
no significa que estemos trabajando
con betas. Al contrario, WSE está plenamente soportado por Microsoft y es
una plataforma de componentes probada y disponible para desarrollos de
aplicaciones en entornos de producción. No estamos hablando de productos beta.
<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services2.WebServicesExtension,
Microsoft.Web.Services2, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="1" group="0" />
</soapExtensionTypes>
</webServices>
Fuente 2
Conclusiones y próximos pasos
<<dotNetManía
Figura 4
26
Eligiendo dicha opción, aparece la
aplicación de configuración según muestro a continuación:
Como conclusión y resumen,
podemos decir que WSE son nuevos
componentes que nos permiten desarrollar servicios Web Xml avanzados
(con WS-SECURITY, WS-MESSAGING, etc.) extendiendo en su mayoría el mismo marco de trabajo que
Especializados en tecnología Microsoft desde 1995 • www.renacimiento.com
El presente artículo cubre solamente
una introducción a WSE y muestra cómo
está integrado a .NET 1.1. Sin embargo,
no nos hemos introducido realmente en
los módulos interesantes de WSE
(Security, Messaging, etc.) porque sería
necesario un artículo específico para cada
módulo. Quizás en un próximo número
de dotNetManía...
dnm.plataforma.net
Carlos Quintero
Creación de complementos en
Visual Studio .NET
Aunque Visual Studio .NET es uno de los mejores entornos de desarrollo jamás
creados, siempre habrá funcionalidades que echemos en falta. Afortunadamente
Microsoft ya pensó en ello y nos permite añadir nuestras propias funcionalidades
a medida mediante complementos, que aprenderemos a crear en este artículo.
<< Hace ya bastantes años que los entornos de desarrollo de
Carlos J. Quintero
es Microsoft MVP de .NET desde
principios del año 2004. Es autor
del popular complemento MZTools 3.0 para VB6,VB5 y VBA, y
de MZ-Tools 4.0 para Visual
Studio .NET 2002/ 2003, ambos
disponibles en
http://www.mztools.com
Microsoft son extensibles (Visual Basic 4.0 en el año 1996
ya lo era), lo que quiere decir que no tenemos que conformarnos con las funcionalidades que nos ofrecen sino
que podemos complementarlos con nuevas funcionalidades de herramientas fabricadas por nosotros mismos
o por terceros. Estas extensiones se integran perfectamente en cada entorno de desarrollo integrado (IDE,
en adelante) a través de nuevos menús o barras de botones. En las versiones anteriores de Visual Basic, Microsoft
sólo ofrecía una forma de extensibilidad, que eran los
complementos (add-ins). En Visual Studio .NET no hay
una sino tres formas de extensibilidad:
• Macros: Por primera vez los desarrolladores de
Visual Basic pueden grabar, editar y ejecutar macros
en Visual Studio .NET, a través del editor de macros
(menú “Herramientas”, “IDE de macros…”). Hay
que indicar que la versión actual de Visual Studio
.NET sólo admite Visual Basic .NET como lenguaje de programación de macros.
• Complementos: Permiten una integración a alto nivel
de nuevas funcionalidades proporcionadas por
DLLs externas. Los complementos se pueden escribir en cualquier lenguaje de .NET, como Visual
Basic .NET, C#, Visual J# o C++.
• Paquetes del Visual Studio Integration Program (VSIP):
Permiten una integración a bajo nivel de nuevas
funcionalidades, editores especializados, nuevos lenguajes de programación, etc. Inicialmente sólo se
permitía escribir estos paquetes en C++, pero más
tarde Microsoft proporcionó VSIP Extras, que permiten crear estos paquetes en lenguajes como Visual
Basic .NET o C# (no obstante la complejidad sigue
siendo grande).
En este artículo vamos a hablar de la forma de extensibilidad más común, los complementos. Al ser un componente compilado en una DLL, un complemento ofrece más protección de la propiedad intelectual que una
macro y mejor rendimiento.
El complemento “Hola mundo”
En esencia, un complemento no es más que una
DLL compilada que cumple 3 condiciones:
• Su clase principal implementa ciertos interfaces
para poder integrarse en el IDE.
• Está registrada como componente COM
(ActiveX). Debido a que Visual Studio .NET no
es una aplicación .NET sino que sigue usando
COM (una herencia del IDE de Visual Studio 6.0),
sus complementos tienen que ser componentes
COM. No obstante, podemos usar la interoperabilidad COM para hacer pasar a nuestra DLL
.NET por un componente COM.
...vamos a hablar de la forma de extensibilidad más común,los complementos.
Al ser un componente compilado en
una DLL,un complemento ofrece más
protección de la propiedad intelectual
que una macro y mejor rendimiento
<< dnm.plataforma.net
Figura 1.
Para ir abriendo boca y antes de entrar en las farragosas explicaciones del registro de complementos,
vamos a crear nuestro primer complemento “Hola
mundo”. Para ello usaremos el asistente para creación
de complementos que nos proporciona Visual Studio
.NET. Se accede a dicho asistente pulsando el menú
“Archivo”, “Nuevo”, “Proyecto…” seleccionando en
el árbol de tipos de proyectos de la izquierda el nodo
“Otros proyectos”, “Proyectos de extensibilidad”, y
en la lista de la derecha la plantilla “Complemento de
Visual Studio .NET”. Esto abre el asistente y en sus
páginas iremos seleccionando como lenguaje de programación Visual Basic .NET, como aplicación de destino (host) a Microsoft Visual Studio .NET, le daremos un nombre (por ejemplo, MiAddin1) y una descripción, y dejaremos las siguientes opciones en sus
valores por defecto. Al finalizar el asistente, éste nos
habrá creado una solución con 2 proyectos: uno que
generará la DLL de nuestro complemento y otro que
generará un programa de instalación del mismo.
Si nos fijamos en el proyecto de la DLL, veremos
que tiene tres referencias que no nos sonarán tan familiares como las demás: son EnvDTE (contiene el modelo de objetos de la extensibilidad de Visual Studio
.NET), Extensibility (contiene el interfaz que tienen que implementar todos los complementos) y
Office (contiene el modelo de objetos de barras de
menús, barras de botones, etc. que Visual Studio .NET
toma prestado de Microsoft Office). Para familiarizarnos con el modelo de objetos de estos ensamblados, especialmente de EnvDTE , podemos usar el
“Examinador de objetos”.
La clase principal de este proyecto es Connect.vb.
En esta clase:
• Se declaran un atributo GUID y un atributo ProgId:
como se mencionó anteriormente, necesitamos
hacer pasar nuestra DLL por un componente
COM, así que esos atributos especifican el GUID y
ProgId de la clase del complemento.
• Se implementa el interfaz Extensibility.
IDTExtensibility2 . Esta interfaz contiene los
métodos OnConnection , OnDisconnection ,
OnStartupComplete, etc. que a modo de eventos
serán llamados por Visual Studio .NET cuando
el complemento sea cargado o descargado.
• Se declaran e inicializan las dos variables más
importantes del complemento:
La variable applicationObject representa el objeto
raíz del entorno de desarrollo (del tipo EnvDTE.DTE)
a partir de la cual tendremos acceso a los menús,
documentos, soluciones, proyectos, ventanas, etc.
del mismo. La variable addInInstance (del tipo
EnvDTE.AddIn) representa esta instancia del complemento. Debido a que el interfaz IDTExtensibility2
sirve también para complementos que se usan en
otros hosts (como Outlook, etc.) dicho método nos
pasa las variables siendo del tipo Object y nosotros
las convertimos a los tipos adecuados para poder usar
Intellisense, early binding, etc.
…no basta con que nuestra DLL implemente
ciertos interfaces (en concreto Extensibility.
IDTExtensibility2) para que se comporte como
un complemento.Además hay que registrar
la DLL como componente COM y como
complemento de Visual Studio .NET
El método OnConnection es el más importante de
todos, y puede ser llamado en distintas situaciones.
Visual Studio .NET nos informa del motivo mediante el parámetro connectMode. Cuando el complemento
es cargado manualmente después de Visual Studio
.NET, el valor que toma el parámetro connectMode
es ext_ConnectMode. ext_cm_AfterStartup. Cuando el
complemento es cargado automáticamente al inicio
de Visual Studio .NET, el valor que se recibe es
ext_ConnectMode. ext_cm_Startup. En este último caso,
es posible que Visual Studio .NET no se haya inicializado por completo y no es recomendable acceder a sus propiedades, etc. por lo que cuando se ha
completado la inicialización, Visual Studio .NET llama al método OnStartupComplete de nuestro com-
<<dotNetManía
• Está registrada como complemento de Visual
Studio .NET, para que aparezca en la lista de complementos (menú “Herramientas”, “Administrador
de complementos...”). Como podéis ver en dicha
ventana, los complementos se pueden cargar y descargar en cualquier momento, y pueden ser marcados para ser cargados en el arranque de Visual
Studio .NET (figura 1).
29
<< dnm.plataforma.net
plemento. Por tanto, la forma correcta de inicializar nuestro complemento
es la siguiente (antes de ejecutar el
complemento, añadiremos una referencia a System.Windows.Forms.dll, con
su correspondiente línea Imports en el
inicio del archivo, e incluiremos una
caja de mensaje):
el código fuente del mismo, y cuando
vayamos a compilarlo nos dará un error
porque no puede escribir la DLL ya que
está en uso. En este punto no basta con
ir al “Administrador de complementos”
y descargar el complemento, ya que los
dominios de aplicación (appdomains) no
permiten descargar ensamblados y la
Private applicationObject As EnvDTE.DTE
Private addInInstance As EnvDTE.AddIn
decir que cada vez que ejecutamos el
complemento, sus clases públicas (en
nuestro caso la clase Connect) son registradas como componentes COM.
Conviene saber que también podemos
registrar manualmente DLLs de .NET
como componente COM usando la utilidad regasm.exe del .NET Framework,
usando el flag /codebase:
Regasm.exe /codebase miaddin.dll
Y para desregistrarlo como componente COM usaríamos:
Public Sub OnConnection(ByVal application As Object, _
ByVal connectMode As Extensibility.ext_ConnectMode, _
ByVal addInInst As Object, ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnConnection
Regasm.exe /unregister miaddin.dll
applicationObject = CType(application, EnvDTE.DTE)
addInInstance = CType(addInInst, EnvDTE.AddIn)
Select Case connectMode
Case ext_ConnectMode.ext_cm_Startup
' No hacemos nada. VS.NET llamará a OnStartupComplete
' cuando esté inicializado
Case ext_ConnectMode.ext_cm_AfterStartup
OnStartupComplete(custom)
End Select
End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnStartupComplete
MessageBox.Show("Hola mundo. Soy " & addInInstance.Name & _
" en " & applicationObject.Name)
End Sub
<<dotNetManía
Fuente 1
30
Ahora ya podemos ejecutar y depurar nuestro complemento: ponemos un
punto de ruptura en alguna línea del
método OnConnection, pulsamos F5 y
aparece una nueva instancia de Visual
Studio .NET. En esta segunda instancia, vamos al “Administrador de complementos” y cargamos nuestro complemento MiAddIn1. Si todo ha ido bien,
la ejecución se detendrá en el punto de
ruptura que establecimos y al continuar
la ejecución aparecerá una caja de mensaje con el texto “Hola mundo. Soy
MiAddin1 en Microsoft Development
Environment”. Para evitar tener que
cargar manualmente el complemento
en la segunda instancia de Visual Studio
.NET, podemos marcarlo para que se
cargue siempre al inicio de Visual Studio
.NET, pero hay que tener en cuenta que
en la siguiente sesión de Windows (al
día siguiente, por ejemplo), el complemento se cargará en la primera instancia de Visual Studio .NET, la que tiene
DLL seguirá en uso. Para solucionarlo
hay que desmarcar el complemento para
que no se cargue al inicio, cerrar Visual
Studio .NET y volver a arrancarlo.
En cualquier caso, para la versión
final del complemento que queremos
distribuir a nuestros usuarios, el programa de instalación del mismo deberá
registrarlo como componente COM.
Cuando el asistente creó nuestro
proyecto también se encargó de crear
unas entradas en el registro de Windows
que permiten a Visual Studio .NET descubrir cuales son los complementos disponibles que mostrará en el
“Administrador de complementos”.
Visual Studio .NET lee los complementos disponibles de dos ramas distintas del registro de Windows:
• HKEY_CURRENT_USER\Software\
Microsoft\VisualStudio\7.1\Addins\
<ProgId>. Se usa esta entrada para
complementos que están disponibles
sólo para el usuario que los instaló.
• HKEY_LOCAL_MACHINE\SOFTWARE\
Registro de complementos
Microsoft\VisualStudio\7.1\AddIns\
<ProgId>. Se usa esta entrada para
Como dijimos al inicio, no basta con
que nuestra DLL implemente ciertos
interfaces (en concreto Extensibility.
IDTExtensibility2) para que se comporte como un complemento. Además
hay que registrar la DLL como componente COM y como complemento
de Visual Studio .NET. ¿Cuándo hemos
hecho esto en nuestro ejemplo anterior?
La respuesta es que el asistente lo ha
hecho por nosotros:
Si vamos a la ventana de propiedades del proyecto del complemento, a la
sección “Propiedades de configuración”,
“Build”, veremos que la casilla de verificación “Registrar para interoperabilidad COM” está marcada. Esto quiere
complementos que están disponibles
para todos los usuarios.
Para el caso de Visual Studio .NET
2002 las entradas usarían “7.0” en lugar
de “7.1”.
Como vemos, cada complemento
queda identificado por su ProgId. Dado
que este valor no es muy descriptivo, se
usan unas entradas llamadas
FriendlyName y Description para proporcionar un nombre y una descripción
para nuestro complemento (estos son
los valores que nos pidió el asistente en
uno de los pasos). Se crean también otras
entradas (CommandPreload, etc. que de
momento ignoraremos).
<< dnm.plataforma.net
IDE tienen por detrás un objeto comando (de la clase
EnvDTE.Command). Podemos ver los comandos que pro-
¿Complicado tanto registro de complemento?
Ciertamente. La buena noticia es que parece que en
Visual Studio 2005 no será necesario ni registrar el complemento como componente COM ni usar el registro
de Windows: un archivo XML en el directorio adecuado se encargará de todo, pero mientras tanto cuando vayamos a distribuir nuestro complemento a otras
máquinas tendremos que hacer que nuestro programa
de instalación cree dichos valores en el registro de
Windows.
Por tanto, combinando ambas formas de
registro del complemento, el proceso de descubrimiento y carga resulta ser el siguiente: Visual
Studio .NET muestra en
el “Administrador de
complementos” los nombres y descripciones que
ha encontrado para cada ProgId que aparece en las ramas
del registro HKEY_CURRENT_USER\Software\Microsoft\
VisualStudio\7.1\Addins\ y HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\AddIns. Cuando cargamos un complemento, Visual Studio .NET busca en
la rama de registro HKEY_CLASSES_ROOT\<ProgId>
(HKEY_CLASSES_ROOT\MiAddin1.Connect en nuestro caso)
cual es el CLSID que corresponde a ese ProgId, y entonces busca la rama del registro HKEY_CLASSES_ROOT
\CLSID\<CLSID>, cuyo valor InProcServer32\CodeBase
contiene la ruta a la DLL del complemento. Se carga
la DLL del complemento y como al menos una clase
pública (la clase Connect) implementa el interfaz
Extensibility.IDTExtensibility2, el complemento es
cargado satisfactoriamente y Visual Studio .NET invoca el método OnConnection pasándonos las instancias del
host y del complemento.
porciona Visual Studio .NET pulsando el menú
“Herramientas”, “Personalizar…” y en la ventana de
diálogo que aparece pulsando en la ficha “Comandos”.
Vemos que los comandos están agrupados en categorías, siendo una de ellas la categoría “Complementos”,
que contiene los comandos externos al IDE, proporcionados por complementos como veremos más adelante. Cada comando está identificado de manera inequívoca por un GUID y un identificador ID. El GUID permite identificar al creador del comando (subsistema
de Visual Studio .NET, un paquete VSIP o un complemento) y el ID permite al creador distinguir sus
propios comandos entre sí. Como las propiedades GUID
e ID de un comando no son muy amigables, cada
comando tiene un caption, que es lo que se muestra
en la interfaz de usuario, y un nombre. Podemos ver
la lista de nombres de comandos en la ventana anterior, pulsando el botón “Teclado”. El nombre está formado por un prefijo y un nombre corto (por ejemplo,
Build.Compile). En el caso de los complementos, el
prefijo es el ProgId del complemento. Como el ProgId
que genera el asistente es de la forma MiAddIn1.Connect,
La buena noticia es que parece que en Visual Studio 2005 no
será necesario ni registrar el complemento como componente
COM ni usar el registro de Windows:un archivo XML
en el directorio adecuado se encargará de todo
A diferencia de versiones anteriores de Visual Basic,
en Visual Studio .NET todos los menús y botones del
Interacción con el IDE
Un complemento puede interaccionar con el IDE
de alguna de las siguientes maneras:
• Respondiendo a eventos que se producen en el IDE con
la solución, proyectos, documentos, etc. Para esto disponemos de distintas clases como DebuggerEvents,
DocumentEvents, SolutionEvents, TaskLiskEvents,
etc. El IDE nos proporciona una instancia de
<<dotNetManía
Introducción a los comandos
los comandos de nuestro complemento tendrán nombres de la forma MiAddIn1.Connect.MiComando, lo cual
no es muy estético; sería mejor que fueran de la forma MiAddIn1.MiComando, por lo que podemos cambiar
el ProgId de nuestro complemento a simplemente
MiAddIn1 (cambiando también, eso sí, las correspondientes entradas del registro del complemento y volviendo a registrar el complemento como componente COM para que el cambio tenga efecto). Por último, podemos obtener mediante código la lista de
comandos usando la colección Commands de la clase
EnvDTE.DTE.
31
<< dnm.plataforma.net
dichas clases mediante la propiedad Events de
nuestro objeto del tipo EnvDTE.DTE. Por ejemplo,
el siguiente complemento intercepta el evento
DocumentOpened que se dispara cada vez que abrimos un documento:
Private WithEvents eventosDocumento As EnvDTE.DocumentEvents
Public Sub OnStartupComplete(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnStartupComplete
eventosDocumento = applicationObject.Events.DocumentEvents()
End Sub
Private Sub eventosDocumento_DocumentOpened( _
ByVal Document As EnvDTE.Document) _
Handles eventosDocumento.DocumentOpened
MessageBox.Show("Has abierto el documento " & Document.Name)
End Sub
Fuente 2
• Interceptando la ejecución de un comando del IDE externo al complemento. A veces es muy interesante poder
interceptar la ejecución de dichos comandos para
realizar alguna acción antes o después de su ejecución. Por ejemplo, es muy habitual querer interceptar
la
ejecución
del
comando
Build.BuildSolution, para realizar alguna acción
antes de generar la solución. Para ello disponemos de la clase EnvDTE.CommandEvents, que nos proporciona los eventos BeforeExecute y AfterExecute.
Para obtener una instancia de la clase
EnvDTE.CommandEvents tenemos que usar la propiedad Events de nuestro objeto del tipo
EnvDTE.DTE. Un complemento con esta funcionalidad quedaría como ve en el fuente 3.
Hay que hacer notar un par de detalles: primero,
que hay distintos comandos Build.XXX y este complemento sólo intercepta el que usa el menú
“Generar”, “Generar solución” (“Build”, “Build
Solution”); segundo, que existe también en el
Private WithEvents eventosComando As EnvDTE.CommandEvents
Public Sub OnStartupComplete(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnStartupComplete
Dim comandoBuildSolution As Command
comandoBuildSolution = _
applicationObject.Commands.Item("Build.BuildSolution")
eventosComando = _
applicationObject.Events.CommandEvents( _
comandoBuildSolution.Guid, comandoBuildSolution.ID)
End Sub
<<dotNetManía
Private Sub eventosComando_BeforeExecute(ByVal Guid As String, _
ByVal ID As Integer, ByVal CustomIn As Object, _
ByVal CustomOut As Object, ByRef CancelDefault As Boolean) _
Handles eventosComando.BeforeExecute
32
If MessageBox.Show("¿Seguro que deseas compilar la solución?", _
"Pregunta", MessageBoxButtons.YesNo) = DialogResult.No Then
CancelDefault = True
End If
End Sub
Fuente 3
modelo de objetos una clase BuildEvents con eventos OnBuildBegin, OnBuildDone, etc. que podríamos
usar como en el primer caso que hemos expuesto
pero dichos eventos no permiten cancelar la acción.
• Respondiendo a la ejecución de comandos del propio complemento (a través de sus botones y menús). Esto será
lo más habitual en un complemento. Para ello, primero el complemento tiene que haber creado sus
propios comandos.
Creación de comandos
Un complemento puede crear sus propios comandos usando el método AddNamedCommand de la colección Commands de nuestro objeto DTE. Dicha función
recibe como parámetros la instancia del complemento (la que recibimos en el método OnConnection), el
nombre corto del comando (el nombre largo llevará
como prefijo el ProgId de nuestro complemento), el
texto del comando (su caption en la interfaz de usuario), el texto de su tooltip, un valor booleano que indica si la imagen asociada al comando será una de las de
Microsoft Office o una a medida diseñada por nosotros y el identificador de dicha imagen (más adelante
comentaremos cómo asociar una imagen al comando). Podemos ignorar los otros parámetros opcionales restantes.
Un aspecto importante a tener en cuenta es ¿cuándo debe crear un complemento sus comandos?
Podríamos pensar que podría crearlos cada vez que
es cargado y eliminarlos cada vez que es descargado.
Sin embargo, esto no es muy conveniente, porque el
usuario puede asociar un comando a una combinación de teclas y si hiciéramos eso el usuario perdería
la asociación con su combinación de teclas preferida
cada vez que descargara el complemento o cerrara
Visual Studio .NET. Por tanto, aunque se pueden crear asociaciones con combinaciones de teclas por código mediante la propiedad Bindings de la clase Command,
la respuesta correcta es que los complementos sólo
deben crear comandos una vez, la primera vez que son
cargados tras su instalación, y de igual manera sólo
deben eliminarlos cuando son desinstalados de la
máquina. Además, así se mejora el tiempo de carga de
los complementos ya que no tienen que crear los
comandos cada vez que son cargados (pensemos en
complementos que proporcionan varias decenas de
comandos, por ejemplo).
Para facilitarnos la tarea de distinguir si es la
primera vez que cargamos el complemento o no, el
IDE nos proporciona el valor especial
ext_ConnectMode.ext_cm_UISetup en el parámetro
connectMode del método OnConnection. Solamente
una vez recibiremos ese valor, y en ese momento
deberemos crear los comandos del complemento.
No obstante, si nuestro complemento tiene pocos
comandos es más robusto comprobar cada vez que
<< dnm.plataforma.net
complicado aún más, en especial
para conseguir que la imagen tenga
“transparencia” en lugar de un fon-
Dim miComando As Command
Try
miComando=applicationObject.Commands.Item(addInInstance.ProgID & "." & "MiComando")
Catch
End Try
If (miComando Is Nothing) Then
miComando = applicationObject.Commands.AddNamedCommand( _
addInInstance, "MiComando", "Mi comando", "Mi comando", True, 59)
End If
Fuente 4
El programa de desinstalación tiene
que encargarse de eliminar los comandos del complemento. Para ello, en una
acción custom debe crear una instancia
del ProgID “VisualStudio.DTE.7.1”
(para Visual Studio .NET 2003) o
“VisualStudio.DTE.7” (para Visual
Studio .NET 2002) que será un objeto
del tipo DTE, a partir del cual podemos
acceder a su colección Commands y borrar
los comandos de nuestro complemento
con el método Delete de la clase Command.
Imagen de un comando
Para asociar una imagen a un
comando de manera que cuando creemos botones en la interfaz de usuario a
partir de dicho comando aparezca su
imagen, tenemos dos opciones:
• Usar una imagen ya existente en las
barras de botones de Microsoft Office.
En este caso, pasaríamos el valor
True en el parámetro MSOButton del
método AddNamedCommand y en el
parámetro Bitmap pasaríamos el
identificador de la imagen proporcionado por Office. Se pueden ver
las imágenes disponibles en Office
y sus identificadores como se explica en [3].
• Usar una imagen propia para nuestro
comando. Usar imágenes propias en
los botones de los complementos
siempre ha sido complicado en la
historia de Microsoft (antes había
que usar el portapapeles de
Windows, cuyo contenido se perdía
si nuestro complemento no tenía la
precaución de preservarlo). Por
increíble que parezca, en el caso de
Visual Studio .NET la cosa se ha
do gris. Para llevarlo a cabo tenemos
que crear una DLL satélite mediante un proyecto Win32 en Visual
C++, añadir un recurso de tipo bitmap de 16x16 píxeles, pintar la imagen usando el color RGB 0,254,0 para
las zonas transparentes (casi verde
total, pero no el verde RGB 0,255,0
como indica erróneamente la documentación), colocar la DLL en una
subcarpeta de nuestro complemento que tenga como nombre el código del locale (por ejemplo, 1033 para
English US) y añadir unas entradas
en el registro de Windows correspondientes a nuestro complemento
con los nombres SatelliteDLLName
(contiene el nombre de la DLL satélite) y SatelliteDLLPath (contiene la
carpeta de la DLL, pero excluyen-
Estado y ejecución de comandos
Una vez que tenemos creados los
comandos de nuestro complemento,
podemos querer cambiar su estado (visible, invisible, habilitado, deshabilitado, etc.)
en función del contexto, por ejemplo,
dependiendo de si la ventana activa es
una ventana de código o no. Y naturalmente, querremos recibir un evento
cada vez que un comando es ejecutado
para llevar a cabo la acción para la cual
se creó. Para ambos propósitos Visual
Studio .NET nos proporciona el interfaz EnvDTE.IDTCommandTarget, que debemos implementar en nuestro complemento. Dicho interfaz tiene sólo 2
métodos:
• QueryStatus: Este método es llamado
por el IDE cuando ha cambiado algo
en el entorno de desarrollo y necesita saber el nuevo estado del comando.
En este método recibimos el nombre
del comando y tenemos que devolver
una combinación de flags con el estado del comando. Si se trata de un
comando de nuestro complemento,
siempre tenemos que devolver como
mínimo el valor vsCommandStatus.
vsCommandStatusSupported. Si deseamos que el comando esté habilitado,
combinaremos dicho valor con
vsCommandStatus.vsCommandStatusEnab
led, como se muestra en el fuente 5.
Public Sub QueryStatus(ByVal CmdName As String, _
ByVal NeededText As EnvDTE.vsCommandStatusTextWanted, _
ByRef StatusOption As EnvDTE.vsCommandStatus, _
ByRef CommandText As Object) _
Implements EnvDTE.IDTCommandTarget.QueryStatus
If CmdName = addInInstance.ProgID & "." & "MiComando" Then
StatusOption = vsCommandStatus.vsCommandStatusSupported Or _
vsCommandStatus.vsCommandStatusEnabled
End If
End Sub
Fuente 5
do la parte del locale, a pesar de lo
que dice la documentación oficial).
Finalmente, en nuestra llamada a la
función AddNamedCommand, pasaríamos el valor False en el parámetro
MSOButton y en el parámetro Bitmap
pasaríamos el número de recurso del
bitmap en nuestra DLL satélite.
Para más información se puede consultar el artículo [4].
• Exec: Este método es llamado por el
IDE cuando el usuario ha invocado
nuestro comando. En este método llevaremos a cabo la acción deseada,
como se muestra en el fuente 6.
Creación de menús y botones
El siguiente paso es crear elementos
en la interfaz de usuario del IDE (boto-
<<dotNetManía
se carga el complemento si sus comandos están creados, y si no es así, crearlos como se muestra aquí:
33
<< dnm.plataforma.net
Public Sub Exec(ByVal CmdName As String, _
ByVal ExecuteOption As EnvDTE.vsCommandExecOption, _
ByRef VariantIn As Object, ByRef VariantOut As Object, _
ByRef handled As Boolean) Implements EnvDTE.IDTCommandTarget.Exec
If CmdName = addInInstance.ProgID & "." & "MiComando" Then
Handled = True
MessageBox.Show("Has ejecutado MiComando.")
End If
End Sub
Fuente 6
nes, menús, etc.) asociados a nuestro comando. Para
crear un botón a partir de un comando se usa el método AddControl de la clase Command. Dicho método recibe como primer parámetro la barra de comandos
(CommandBar) a la que se añadirá el botón. Como segundo parámetro se pasa la posición que tendrá el botón
en dicha barra (si no se pasa un valor se asumirá que
irá en la primera posición).
Las posibilidades para añadir un botón son las
siguientes:
• Usar una barra de comandos ya existente: En este caso
utilizaremos una de los objetos CommandBar que
devuelve la colección CommandBars de nuestro objeto del tipo DTE. Cuando el complemento se descarga debemos eliminar dicho botón. Aquí se muestra
cómo añadir o quitar nuestro comando de la barra
de comandos “Herramientas” (“Tools”) de Visual
Studio .NET (otra barra de comandos muy usada es
el menú de contexto de las ventanas de código, cuyo
nombre es “Code Window”):
• Crear una barra de botones nueva: Esto sólo será necesario si nuestro complemento proporcionara tantos comandos que fuera mejor agruparlos en su propia barra, lo cual no es el caso de nuestro complemento de ejemplo, pero para ello emplearíamos el
método Add de la colección CommandBars de nuestro objeto del tipo DTE. Dicho método nos devuelve un objeto del tipo CommandBar al que podemos añadir un botón como en el caso anterior.
Conclusión
En este artículo hemos visto lo básico para la creación de complementos para Visual Studio .NET. Con
esto ya podemos centrarnos en la funcionalidad propia de nuestro complemento, como puede ser el manejo de ventanas y documentos, generación y manipulación de texto en nuestro código fuente, manipulación de formularios, navegación por la estructura de
nuestro código fuente (namespaces, clases, métodos,
etc.). En el siguiente apartado se proporcionan todos
los recursos necesarios para seguir nuestra andadura.
Recursos en la Web
Existen multitud de recursos como documentación oficial, ejemplos, artículos, weblogs, foros y newsgroups, libros, etc. para los desarrolladores de complementos para Visual Studio .NET. Todos ellos están
en inglés (incluso los que escribo yo) y están recogidos en la siguiente página de mi sitio Web:
Private controlMiComandoEnMenuHerramientas As CommandBarControl
Private Sub AñadirCommandoEnMenuHerramientas(ByVal comando As Command)
Dim barra As CommandBar
barra = applicationObject.CommandBars.Item("Tools")
controlMiComandoEnMenuHerramientas = comando.AddControl(barra)
controlMiComandoEnMenuHerramientas.Visible = True
End Sub
Public Sub OnDisconnection( _
ByVal RemoveMode As Extensibility.ext_DisconnectMode, _
ByRef custom As System.Array) Implements _
Extensibility.IDTExtensibility2.OnDisconnection
If Not (controlMiComandoEnMenuHerramientas Is Nothing) Then
controlMiComandoEnMenuHerramientas.Delete()
End If
End Sub
<<dotNetManía
Fuene 7
34
Si deseamos cambiar alguna propiedad del botón,
por ejemplo su propiedad Style (para que muestre
sólo el texto, o texto con imagen, etc.) o su propiedad BeginGroup (para que se muestre un separador),
tendremos que convertir el objeto de tipo
CommandBarControl en un objeto del tipo
CommandBarButton mediante la instrucción CType (o
DirectCast). Con el tipo CommandBarButton tendremos acceso a dichas propiedades que no están en el
tipo CommandBarControl.
http://www.mztools.com/resources_addin_developers.htm
En especial cabe destacar los siguientes:
[1] El libro “Inside Microsoft Visual Studio .NET
2003”, de Craig Skibo y otros: http://www.microsoft.com/mspress/books/6425.asp. Este libro es
imprescindible para cualquier desarrollo serio en
el tema de complementos para Visual Studio .NET
y está escrito por uno de los miembros del equipo de extensibilidad de Microsoft Visual Studio
.NET.
[2] El foro de Yahoo para complementos de Visual
Studio .NET. http://groups.yahoo.com/group/vsnetaddin. Tiene una historia de mensajes con preguntas y respuestas muy completa y una sección
Files con muchos recursos. Yo mismo he pasado
en este foro más de 3 años contestando preguntas
sobre complementos para Visual Studio .NET.
[3] “Finding Face ID Numbers for Your Microsoft
Office 97 Toolbars”: http://msdn.microsoft.com/
library/default.asp?url=/library/en-us/
dno97ta/html/faceid.asp.
[4] “Custom
command
bitmaps
101”:
http://weblogs.asp.net/craigskibo/archive/2004/01/08/48814.aspx.
dnm.inicio.fundamentos
dnm.incio.fundamentos
Guillermo “Guille” Som
Interfaces
Yo implemento, tu implementas,... ¡implementemos todos!
En este primer artículo de esta nueva seccción explicamos las Interfaces. Las
interfaces son de esos elementos de .NET Framework que juegan un papel bastante importante, pero que, a pesar de estar por todas partes, aparentemente
pasan desapercibidas...
<< Y es cierto, tanto que juegan un parte importante como
que pasan desapercibidas; de hecho las estamos
usando continuamente y en muchos de los casos ni
tan siquiera somos conscientes de ello. Esto es así,
al menos en la mayoría de los casos, porque es el
propio .NET el que juega ese papel de implementador de interfaces; nosotros simplemente las usamos, pero me atrevo a asegurar que en la mayoría
de los casos no somos conscientes de que estamos
trabajando codo a codo con las interfaces. Por tanto, ya va siendo hora de que sepamos que existen
y cómo podemos aprovecharnos de su existencia...
en el buen sentido de la palabra.
Las interfaces son...
Guillermo “Guille” Som
es Microsoft MVP de Visual Basic
desde 1997. Es redactor de
dotNetManía, miembro de Ineta
Speakers Bureau Latin America,
mentor de Solid Quality Learning
Iberoamérica y autor del libro
Manual Imprescindible de Visual
Basic .NET.
http://www.elguille.info
En su forma más simple, las interfaces son simplemente definiciones de buenas intenciones, es decir,
sólo indican cómo deberían definirse ciertos miembros de nuestras clases y estructuras. Pero si lo examinamos un poco más a fondo, realmente son más
que esas buenas intenciones, ya que, cuando entran
en juego, no basta con tener buenas intenciones, sino
que debemos seguir al pie de la letra lo que esas interfaces definen. Y este es el punto fuerte de las interfaces, no sólo definen cómo deberían ser las cosas, sino
que nos obligan a que las cosas sean de una forma
determinada.
Seguramente estaremos hartos de leer que las
interfaces son un contrato, es decir, son algo que cuando decidimos usarlas, debemos hacerlo al pie de la
letra, no basta con tener la intención de..., sino debemos convertir esa intención en algo tangible.
Como hemos comentado, el propio .NET
Framework utiliza las interfaces cuando quiere ase-
gurarse de que algo se puede hacer, por ejemplo, si
queremos clasificar elementos en un array o una colección, (ver nº 7 de dotNetManía), esos elementos
deben implementar la interfaz IComparable, de esta
forma, el propio .NET se asegura de que esas clases
clasificables se comportarán de una forma determinada, de modo que pueda utilizarse como está previsto que se utilicen. Esa seguridad que tiene .NET
de hacer las cosas como está previsto se la da el hecho
de que el programador que ha creado la clase usada
para ser clasificada ha firmado un contrato, ese contrato le dice que debe utilizar los miembros de la interfaz correspondiente de la forma adecuada; en este
ejemplo, debe implementar el método CompareTo para
que coincida exactamente con la forma que está definido en la interfaz IComparable. Por tanto, si .NET
se encuentra con una clase que define los miembros
de esa interfaz, tiene la certeza de utilizarlos como
está previsto.
¿Qué contiene una interfaz?
Debido a la naturaleza propia de las interfaces, es
decir, que solamente representan buenas intenciones,
éstas no contienen código ejecutable, sólo definen qué
código debe tener la clase o estructura que decida
implementarla. Dicho esto, podemos concluir que las
interfaces sólo definen los miembros, realmente la “firma” de los mismos, es decir, de qué tipo son, si reciben parámetros, cuántos y de qué tipo, y en el caso de
las propiedades, además del tipo de las mismas, si éstas
son de sólo lectura, predeterminadas (indizadores en
C#), etc. Veamos un ejemplo para aclarar conceptos.
En los fuentes 1 y 2 tenemos la definición de una interfaz, tanto para VB como para C#.
<< dnm.inicio.fundamentos
Public Interface IPrueba
Sub Mostrar(ByVal saludo As String)
Property Nombre() As String
Default ReadOnly Property Item(ByVal index As Integer) As String
Function Total() As Integer
Event DatosCambiados(ByVal mensaje As String)
End Interface
tipo) implementa dicha interfaz, lo haremos de la misma forma que al derivar la
clase a partir de otra: usando dos puntos después del nombre del tipo, seguido con el nombre de la interfaz:
public class Prueba : IPrueba {...}
Fuente 1. Definición de una interfaz en Visual Basic
Fuente 2. Definición de una interfaz en C#
Como podemos comprobar, en las
dos interfaces hemos definido todos los
tipos de miembros que cualquier clase o
estructura pueden tener: métodos, propiedades, indizadores (propiedades predeterminadas en VB) y eventos. En el
caso de los eventos, la diferencia está en
cómo se definen en VB y en C#, en este
último, los eventos siempre están ligados
con los delegados, mientras que en Visual
Basic no tiene por qué hacerse esa asociación, aunque internamente sí que están
bastantes ligados con los delegados, de
hecho la declaración de la interfaz del
fuente 1 la podemos hacer tal como mostramos en el fuente 3.
Aunque en cualquier caso, siempre
se podrán definir de la forma habitual (de
VB), de hecho, cuando el propio IDE de
Visual Studio crea la plantilla para implementar esta interfaz, lo hace de la misma forma que si hubiésemos usado la
definición hecha en el fuente 1.
¿Cómo usar una interfaz?
Tal como podemos comprobar en los
fuentes 1 y 2, al definir una interfaz sólo
indicamos la “firma” que tendrán los
miembros sin indicar siquiera el ámbito
de éstos, ya que siempre serán públicos,
de hecho no tendía ningún sentido defi-
Public Delegate Sub DatosCambiadosEventHandler(ByVal mensaje As String)
Public Interface IPrueba
...resto de miembros...
Event DatosCambiados As DatosCambiadosEventHandler
End Interface
Fuente 3. Definición de una interfaz de VB usando delegados
[
El nombre de las interfaces
Por definición, o convención, los nombres
de las interfaces siempre empezarán con la
letra I mayúscula seguida del nombre propiamente dicho. Aunque esto es sólo una sugerencia, ya que realmente el nombre de una
interfaz puede ser cualquier nombre válido.
]
nir miembros privados en
una interfaz.
Una vez que hemos
definido el contenido de
una interfaz y queremos
usarla en una clase, estructura u otra interfaz, lo
haremos de forma distinta
dependiendo del lenguaje.
En el caso de C#, para
indicar que una clase (o
Public Class Prueba
Implements IPrueba
...
End Class
Si estamos usando Visual Studio
como editor de nuestro código, éste
puede crear las plantillas de los miembros de la interfaz automáticamente, de
forma que nosotros sólo tengamos que
escribir el código correspondiente a cada
uno de estos miembros.
La forma de definir esos miembros
dependerá también del lenguaje que
estemos utilizando, en el caso de C#, no
hay que hacer nada especial, simplemente definir los miembros en la clase
y asunto arreglado. Pero si el lenguaje
usado es Visual Basic, esas definiciones
hay que hacerlas de forma explícita, es
decir, debemos indicar que las definiciones de esos miembros realmente son
las definiciones de los miembros de la
interfaz. Esto lo haremos usando, a continuación de la definición de cada uno
de ellos, la instrucción Implements seguida del nombre de la interfaz y el miembro que implementa:
Public Property Nombre() As String _
Implements IPrueba.Nombre
Realmente esta forma de hacer de
VB puede parecer, (de hecho lo es), una
forma de rizar el rizo, pero la explicación o excusa que hay (con la que nos
podemos consolar), es que en VB no
tenemos porqué usar el mismo nombre
indicado en la interfaz, por ejemplo, el
método Mostrar lo podríamos definir de
esta otra forma:
Public Sub Imprimir(_
ByVal saludo As String)_
Implements IPrueba.Mostrar
<<dotNetManía
public delegate void DatosCambiadosEventHandler(string mensaje);
public interface IPrueba
{
void Mostrar(string saludo);
string Nombre{get; set;}
string this[int index]{get;}
int Total();
event DatosCambiadosEventHandler DatosCambiados;
}
En Visual Basic utilizaremos la instrucción Implements seguida del nombre de la interfaz:
37
<< dnm.inicio.fundamentos
En este caso, el método Imprimir de la clase Prueba
realmente es la definición del método Mostrar de la
interfaz IPrueba. Sobre esto, aunque está bien que
podamos hacerlo, si queremos mantener nuestras
mentes claras, sobre todo la de los que prefieren usar
C#, deberíamos respetar siempre el nombre indicado en la interfaz.
La primera, (que es la que usa el IDE de Visual
Studio), es creando dos miembros para implementar
cada uno de los de cada interfaz; por supuesto esos
miembros deben tener nombres diferentes:
Public Sub Mostrar(_
ByVal saludo As String) _
Implements IPrueba.Mostrar
Múltiples interfaces en nuestros tipos
.NET es un lenguaje de herencia simple, es decir,
una clase de .NET no se puede derivar de más de
una clase, (salvo con la excepción de la herencia
implícita de la clase Object), pero en el caso de las
interfaces, podemos decir que los lenguajes de .NET
son de herencia múltiple. Esto es así porque una clase (o tipo) puede implementar más de una interfaz;
por supuesto, en ese caso, siempre deberemos definir todos los miembros de todas las interfaces que
implemente.
Para indicar que una clase implementa más de
una interfaz lo haremos de la siguiente forma. Para
C#:
public class Prueba2 : IPrueba,
IPrueba2 {...}
Public Sub Mostrar1(_
ByVal saludo As String)
Implements IPrueba2.Mostrar
La segunda es definiendo sólo un miembro e indicando que ese único miembro implementa las dos
interfaces:
Public Sub Mostrar(_
ByVal saludo As String) _
Implements IPrueba.Mostrar,_
IPrueba2.Mostrar
Por supuesto, la forma que elijamos dependerá
de cómo queramos implementar estos miembros, es
decir, si queremos que compartan el mismo código
o que ese código sea independiente para cada implementación.
Y de esta otra para VB:
Public Class Prueba2
Implements IPrueba, IPrueba2
...
End Class
Múltiples interfaces con miembros idénticos
<<dotNetManía
Un problema con el que nos podemos encontrar es que dos interfaces distintas tengan miembros con la misma firma (y el mismo nombre).
Bueno, problema, lo que se dice problema, no lo
es, ya que la definición la haremos como de costumbre, si bien aquí volvemos a encontrarnos con
la forma que tiene cada lenguaje de hacer frente a
esa duplicidad.
En el caso de C#, no tenemos que hacer nada en
especial, sólo definir un miembro que cumpla con la
firma correspondiente y ese mismo miembro lo podemos usar para las dos interfaces.
38
public void Mostrar(string saludo)
{
// Esta implementación servirá
// para las dos interfaces
En el caso de Visual Basic, podemos hacerlo de
dos formas:
Las interfaces sólo definen los miembros, realmente
la “firma” de los mismos, es decir, de qué tipo
son, si reciben parámetros, cuántos y de qué tipo,
y en el caso de las propiedades, además del tipo
de las mismas, si éstas son de sólo lectura,
predeterminadas (indizadores en C#)
Implementaciones privadas, ¿realmente
son privadas?
El problema con el que nos podemos encontrar es si esta misma forma de actuar, de tener definiciones diferentes para cada implementación, la
queremos implementar en C#. Ya que este lenguaje
no permite indicar que cada implementación es
independiente una de la otra. Al menos si queremos que tanto una como otra sean públicas y queremos que ambas formen parte de la interfaz pública de la clase.
<< dnm.inicio.fundamentos
public void Mostrar(string saludo)
{
// Esta implementación servirá para la interfaz IPrueba
Console.WriteLine(saludo + ", " + Nombre);
}
void IPrueba2.Mostrar(string saludo)
{
// Esta implementación solo es para IPrueba2
Console.WriteLine("2: " + saludo + ", " + Nombre);
}
Fuente 4. Implementación privada en C# de los miembros de una interfaz
Igualmente si sólo queremos que ambas implementaciones sean privadas, es decir, que no formen
parte de la propia clase que las define, sino que sólo
sean accedidas desde un objeto del tipo de la interfaz, las declaraciones las haremos usando la segunda
forma mostrada en el fuente 4.
En el caso de Visual Basic, como hemos visto,
podemos hacerlo de las dos formas mostradas anteriormente, pero si queremos que tengan la misma
funcionalidad “privada” que hemos visto en C#,
podemos declarar esos miembros como privados,
de forma que no formen parte de la interfaz pública de la clase, sino que sólo podamos usarlas desde
objetos del mismo tipo que las interfaces. En el
siguiente fuente podemos ver un ejemplo de esto
que comentamos:
Private Sub Mostrar1(ByVal saludo As String) _
Implements IPrueba2.Mostrar
.NET es un lenguaje de herencia simple, es decir,
una clase de .NET no se puede derivar de más
de una clase, pero en el caso de las
interfaces, podemos decir que los lenguajes
de .NET son de herencia múltiple
Como hemos comentado, aunque estos miembros estén definidos como privados, debemos saber
que siempre formarán parte de la interfaz que implementa la clase, por tanto podremos acceder a ellos
por medio de un objeto de la interfaz, tal como podemos ver en el código de los fuentes 5 y 6.
Dim pr2 As New Prueba2
pr2.Nombre = "Pepe"
pr2.Mostrar("Desde la clase Prueba2: Hola")
Dim ipr1 As IPrueba
Dim ipr2 As IPrueba2
ipr2 = pr2
ipr2.Mostrar("Desde la interfaz IPrueba2: Hola")
ipr1 = pr2
ipr1.Mostrar("Desde la interfaz IPrueba: Hola")
Fuente 5.Acceder a los miembros de una clase por medio
de un objeto de la interfaz (VB)
Prueba2 pr2 = new Prueba2();
pr2.Nombre = "Pepe";
pr2.Mostrar("Desde la clase Prueba2: Hola");
IPrueba ipr1;
IPrueba2 ipr2;
ipr2 = pr2;
ipr2.Mostrar("Desde la interfaz IPrueba2: Hola");
ipr1 = pr2;
ipr1.Mostrar("Desde la interfaz IPrueba: Hola");
Fuente 6.Acceder a los miembros de una clase por medio
de un objeto de la interfaz (C#)
Conclusión
Como hemos podido comprobar en lo expuesto
aquí, las interfaces son una de las formas que tienen
los lenguajes para que nuestras clases puedan ofrecer
cierta funcionalidad y que dicha funcionalidad pueda
ser compartida por clases distintas. Debido a que las
interfaces nos obligan a seguir unas normas o formas
a la hora de definir ciertos miembros en nuestros tipos,
podemos usar esta característica para asegurar que
nuestras clases utilizan uno de los pilares de la programación orientada a objetos: el polimorfismo, ya que
las interfaces le dan a nuestras clases una forma de utilización “medio-anónima”, al menos en el sentido de
que si utilizamos una interfaz que nuestra clase implementa, podemos acceder a los miembros implementados por esa interfaz, sin necesidad de saber que estamos usando un objeto determinado de una clase en
particular.
En otra ocasión veremos de una forma algo más
práctica cómo utilizar las interfaces y de paso algunos consejos que siempre vendrán bien para sacar el
provecho de este tipo de datos que .NET pone a nuestra disposición.
<<dotNetManía
La solución es definir cada miembro independiente para que sólo puedan ser accedidos usando
objetos del tipo de cada interfaz (o que uno sea parte de la clase y de una de las interfaces y el otro sólo
lo sea de la otra interfaz).
Esto lo podemos hacer definiendo estos miembros de la siguiente forma. En el fuente 4 se muestra cómo hacerlo para que la implementación de
IPrueba sea parte de la clase y que la implementación
de IPrueba2 sólo pueda ser accedida mediante un objeto del tipo de esa interfaz.
39
Suscríbase y llévese el
CD Volumen 1 gratis
AG
OT
AD
O
AG
OT
AD
O
Aún está a tiempo
❑ Nº3
Nº4
❑ Nº5
❑ Nº6
❑ Nº 7
❑ Nº8
❑ Nº10
❑ Nº11
❑ Nº12
❑ Nº13
❑ Nº14
❑ Nº15
Nº2
❑ Nº9
Oferta válida sólo para España hasta el 30 de Junio de 2005 o hasta agotar existencias
✃❑
❑
Deseo suscribirme a dotNetManía por un año (11 números) por un precio de 60,00€ IVA incluido y recibir el CD
Volumen 1 con los 11 primeros ejemplares en formato PDF de alta calidad de forma gratuita.
Deseo que me envíen los números atrasados marcados por un precio de 6,00€ IVA incluido cada uno.
DATOS DE ENVÍO
CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DATOS DE FACTURACIÓN (sólo si son distintos a los datos de envío)
CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Usted autoriza a la mecanización
FORMA DE PAGO
de estos datos. El responsable y
❑ Talón nominativo a nombre NETALIA, S.L.
destinatario de éstos es Netalia,
❑ Transferencia bancaria a nombre de NETALIA, S.L. a:
S.L. Usted tiene derecho a acceLa Caixa - Número de cuenta 2100 4315 48 2200014696 (Indique su nombre en la transferencia)
der a sus datos, modificarlos y
❑ Domiciliación Bancaria (con renovación automática, previo aviso)
cancelarlos cuando lo desee. Sus
Indique su número de cuenta:
datos no serán cedidos en ningu❑ Tarjeta de crédito
na de las formas posibles a terceras partes y no se utilizarán más
❑ VISA
❑ MASTERCARD
que para el buen funcionamienNúmero de su tarjeta:
to de su suscripción a la revista
Fecha de caducidad:
/
(imprescindible)
Firma y/o sello
a
de
Puede enviar sus datos por Fax al 91 499 13 64, o por teléfono al 91 666 74 77,
o por email a la dirección [email protected], o también puede
enviarlos por correo postal a la siguiente dirección:
de 20
dotNetManía y para informarle de las actividades comerciales
que realice la editorial Netalia,
S.L. Si no desea recibir información comercial de dotNetManía
marque la casilla siguiente ❑
Netalia, S.L.
C/ Robledal, 135
28529- Rivas Vaciamadrid (Madrid)
dnm.arquitectura
Daniel Mazzini
Herencia ¿To be or not to be?
En este artículo se demuestra por medio de patrones cuando la herencia es una buena
opción y algunos síntomas que nos pueden indicar cuando usarla se puede convertir en
un problema y cómo resolverlo.
todo esto explicado por dos patrones de diseño y con
ejemplos sacados de la plataforma .NET y otros propios. Primero veremos cuando no utilizarla, veremos
algunos de sus inconvenientes para luego hacer de
esos inconvenientes, virtudes. Por último unas conclusiones salomónicas. Los patrones que seleccione
se conocen como Pattern of Patterns, es decir patrones de diseño que son muy básicos y están por debajo de los patrones que se definen en otros libros como
GoF o Fowler03.
Patrón delegado
Resumen
Mejorar el diseño por medio de composición
cuando la herencia da más problemas que soluciones. Se ruega no confundirse con delegate.
Objetivo
En algunas situaciones usar herencia para extender clases no es una decisión acertada. La delegación
sigue un propósito más general para extender funcionalidad.
Contexto de uso
Daniel Mazzini
colabora habitualmente con
dotNetManía. Es Arquitecto de
Sistemas de Información en
Insert Sistemas. Imparte cursos
tanto de C# como de Visual
Basic.NET para Aula DAT y
colabora en los talleres MSDN
de Microsoft Ibérica.
La herencia es el modo más común de extender
funcionalidad, si se usa correctamente para los casos
“es un”. Recalcaría el “un” debido a que en .NET no
soporta herencia múltiple.
En algunos sistemas, un usuario juega distintos
roles. Por ejemplo, en un sistema de conferencias
para hoteles un congresista puede ser un empleado
del hotel o una persona externa, teniendo tratamientos diferentes, ya que un congresista externo factura sus horas mientras que el empleado no.
También en otros entornos donde no se soporta
herencia (yo la he usado en VB 6) se imita por medio
de la delegación.
No debemos mezclar las clases referentes al dominio de la aplicación con las clases de utilidades.
Cuando desarrollamos clases de utilidades o herramientas, por ejemplo un manejador de XML, es normal ver cómo una clase delega la creación del XML
a la herramienta.
Este patrón sigue una de las máximas que se
encuentra en GoF: es mejor la colaboración entre
clases que la herencia. Esto se debe a que la herencia define su estructura en tiempo de diseño sin
posibilidad de cambiar la clase base en tiempo de
ejecución.
El ocultar métodos o propiedades de una clase
base es un indicador de que no es buena idea heredar de esa clase. Lo mismo sucede con las interfaces;
si vemos que tenemos una interfaz de tres métodos,
la implementamos en diez clases, en ocho de las diez
clases uno de los tres métodos está devolviendo un
nulo, es porque debemos separar la interfaz y dejar
ese método en una segunda interfaz.
Y, sobretodo, el uso inapropiado de la herencia
puede que nos lleve a crear un AntiPatron como puede ser una clase Dios. Una clase Dios es aquella clase que lo hace todo, donde todo el sistema gira alrededor de esta clase, logrando una gran dependencia
hacia ella.
Ventajas de este patrón
• La herencia es una relación estática mientras que
la delegación es dinámica. Podemos hacer lo mis-
<<dotNetManía
<< Veremos distintas motivaciones para usar o no herencia,
41
<< dnm.arquitectura
mo que con herencia pero cambiando la clase
que resuelve el problema en tiempo de ejecución.
• Las clases relacionadas al dominio de la aplicación no deben
heredar de clases de utilidades. Además de ser una mala
decisión de diseño, una vez terminada la clase expondría los métodos públicos de la clase de utilidad, rompiendo su encapsulación.
• Proliferación de clases hijas. Ejemplo: tenemos dos
clases, empleado y colaborador. Luego sabemos
que un empleado puede llegar a ser un colaborador, las dos clases heredan de persona. Habría
que crear una clase uniendo las dos posibilidades. Si en lugar de tener una combinación entre
2, lo hacemos entre 5, el número crece radicalmente.
• Mejora con interfaces. Se puede mejorar más la
colaboración entre clases si el delegado implementa una interfaz. Esto daría la posibilidad de
tener más de una clase que pueda servirnos como
delegado.
Desventajas de este patrón
• Más código: Se requiere escribir más código en algunas situaciones.
• Comportamiento: Se pueden dar casos donde el
comportamiento de la clase cambie, por ejemplo
se espera un tipo de error y se recibe otro.
Roles
Delegado: Clase en que se confía una responsabilidad.
Delegador: Clase que le pide al delegado que le
resuelva su problema.
determinado. Internamente, cuando se cambia la propiedad ListViewItemSorter también se ejecuta el método Sort.
Para ordenar un vector, la clase System.Array en una
sobrecarga del método Sort permite que le pasemos el
vector a ordenar y una clase que implemente la interfaz
IComparer.
Ejemplo
Durante la primera etapa de un desarrollo podemos llegar a conclusiones apresuradas. Por ejemplo, que una ventana es un tipo de rectángulo.
Como la relación es del tipo “es un”, creamos la
clase base rectángulo capaz de calcular su superficie en m2 y luego la clase ventana que heredara de
rectángulo. Todo funciona correctamente, hasta
que, bajo un nuevo requerimiento, el cliente nos
indica que las ventanas pueden tener distintas formas y que también necesita calcular la superficie.
Debemos cambiar el diseño porque no podemos
cambiar la clase base
de ventana. Debemos delegar en una
clase u otra el calculo basándose en el
tipo de forma que
tiene la ventana.
Para que pueda ser
más de una clase
hacemos una interfaz llamada ISuper
ficie, con el método CalcularArea. El
fuente 1 muestra el Figura 2. Grafico del apartado de
ejemplo - Diseño inicial
código que resuelve
esta situación.
Figura 1. Roles del patrón delegado
<<dotNetManía
Dentro de .NET
42
Existen gran cantidad de casos dentro de las librerías bases de la plataforma donde podemos ver el uso
de delegados. Paso a ejemplificar dos, ambos relacionados con la ordenación de objetos. Cuando hay que
ordenar un control ListView se consulta a la propiedad ListViewItemSorter, que es de tipo IComparer si
tiene un ordenador asignado. Si la propiedad
ListViewItemSorter está nula, crea el ordenador pre-
Figura 3. Diseño final.
Patrones relaciones
Al igual que en la plataforma .NET, muchos patrones utilizan la delegación, los casos mas claros son el Proxy
y el Decorador.
<< dnm.arquitectura
#region Miembros de ISuperficie
public Double CalcularArea()
{
return _lado1 * _lado2;
}
#endregion
}
/// <summary>
/// La clase circulo es uno de los delegados
/// </summary>
public class Circulo:ISuperficie
{
public Circulo(double radio)
{
_radio=radio;
}
double _radio;
#region Miembros de ISuperficie
public Double CalcularArea()
{
return (Math.PI * (Math.Pow(_radio,2)));
}
#endregion
}
/// <summary>
/// La clase ventana es el delegador
/// </summary>
public class Ventana
{
ISuperficie _sup;
public Ventana(double lado1,double lado2)
{
_sup= new Rectangulo(lado1,lado2);
}
public Ventana(double radio)
{
_sup= new Circulo(radio);
}
public double ObtenerArea()
{
return _sup.CalcularArea();
}
}
/// <summary>
/// Aplicacion de prueba
/// </summary>
public class Test
{
[STAThread]
static void Main(string[] args)
{
Ventana v1 = new Ventana(5,5);
Ventana v2 = new Ventana(2.5);
Console.WriteLine(v1.ObtenerArea());
Console.WriteLine(v2.ObtenerArea());
Console.WriteLine();
Console.WriteLine("Presione cualquier tecla para continuar");
Console.ReadLine();
}
}
}
Fuente 1
Patrón Superclase Abstracta
Resumen
Asegurar consistencia para encapsular clases
conceptualmente relacionadas por medio de una
clase superclase abstracta.
Contexto
Tenemos que crear un conjunto de colecciones
para un sistema con información crítica, nos han pedido que no se pueda quitar un objeto de la lista y que
podamos ocultar la información lo más que podamos.
No quieren que usemos ArrayList.ReadOnly por las
dudas que nos olvidemos de usarlo en una de las clases. Nosotros hemos decidido que al llamarse a Remote
o RemoteAt, que siga con la documentación de .NET,
que dice que debe elevar una excepción del tipo
NotSupportedException.
Si usamos la clase ColeccionBase nos encontramos
que ya viene con este método escrito pero sin posibilidad de sobrescribirlo. Tenemos que usar la interfaz
IList. Llegado este punto tenemos dos posibilidades:
• Implementar en cada clase concreta la interfaz
IList y tener n veces repetido el mismo código
que eleva la excepción en los métodos Remote o
RemoveAt.
• Crear una clase abstracta que resuelva cómo usar
el método Remote y RemoveAt para todas las clases
hijas.
Muchas veces tenemos la posibilidad de elegir
entre dos maneras de solucionar un problema, y
pocas veces son las que unimos las dos soluciones
en una mejor solución, sino que generalmente optamos por una y descartamos la otra. ¿Vacaciones en
la playa o en la montaña? ¿Por qué no las dos juntas?. Es el caso de interfaz y clase abstracta: la interfaz nos garantiza indireccionamiento, que el cliente sabrá lo mínimo sobre el servicio que usa, mientras que la clase abstracta nos da un comportamiento común. Si unimos los dos, podremos encontrarnos que tendremos un sistema donde el cliente sólo verá una interfaz (IList), las clases se ocultarán y tendrán un comportamiento homogéneo ya
que unos métodos los resuelve la propia clase abstracta y otros métodos quedan abstractos para que
los resuelva la clase concreta porque éstos sí son
diferentes en cada clase concreta.
Ventajas de usar este patrón
• Asegurar que un conjunto de clases relacionadas se
implementan en forma consistente.
• No desea escribir de más.
• Facilidad a la hora de mantenerlo.
• Facilidad en caso de agregar una clase nueva.
<<dotNetManía
using System;
namespace Delegado
{
/// <summary>
/// Interfaz para comunicar mejor el delegador con el delegado
/// </summary>
public interface ISuperficie
{
Double CalcularArea();
}
/// <summary>
/// La clase rectangulo es uno de los delegados
/// </summary>
public class Rectangulo:ISuperficie
{
public Rectangulo(double lado1,double lado2)
{
_lado1=lado1;
_lado2=lado2;
}
double _lado1;
double _lado2;
43
<< dnm.arquitectura
using System;
using System.Collections;
• Pruebas: Si un método se implementa en la superclase, y se prueba satisfactoriamente, sabremos que todos los
hijos también pasarán esa prueba.
namespace SuperClaseAbstracta
{
public abstract class BaseColeccion:IList
{
private ArrayList _lista;
Desventajas
protected BaseColeccion(ICollection coleccion)
{
_lista= new ArrayList(coleccion);
}
#region Miembros de IList
public bool IsReadOnly
{
get{return true;}
}
public object this[int index]
{
get{return _lista[index];}
set{throw new NotSupportedException("La colección es de solo lectura");}
}
public void RemoveAt(int index)
{
throw new NotSupportedException("La colección es de solo lectura");
}
public void Insert(int index, object value)
{
throw new NotSupportedException("La colección es de solo lectura");
}
public void Remove(object value)
{
throw new NotSupportedException("La colección es de solo lectura");
}
public bool Contains(object value)
{
return _lista.Contains(value);
}
public void Clear()
{
throw new NotSupportedException("La colección es de solo lectura");
}
public int IndexOf(object value)
{
return _lista.IndexOf(value);
}
• La dependencia que crea la clase abstracta (en el patrón anterior se explicó en detalle este problema).
- El hecho de agregarle responsabilidad
que no debe tener. Cuando desarrollamos solemos agregar más y más
funcionalidad hacia las clases base.
El problema es que en ciertas veces,
no todas las veces, se necesita esta
funcionalidad en todas las clases
hijas.
Roles
• Interfaz: Métodos genéricos que se
desean ejecutar desde el cliente.
• SuperClase abstracta: Clase encargada de encapsular la lógica común
para un conjunto de clases relacionadas que son sus clases hijas. Los
métodos con lógica diferente se
dejan como abstract, asegurando que
cada subclase concreta lo implementa a su manera.
• Clases concretas: Las clases concretas son clases relacionadas entre
sí, por ejemplo, que están en la
misma capa de la aplicación, y que
se desea que los métodos que tienen código igual pase a formar
parte de una clase base.
public int Add(object value)
{
throw new NotSupportedException("La colección es de solo lectura");
}
public bool IsFixedSize
{
get{return true;}
}
#endregion
#region Miembros de ICollection
<<dotNetManía
public bool IsSynchronized
{
get{return _lista.IsSynchronized;}
}
44
Figura 4. Roles del patrón superclase abstracta
Dentro de .NET
public int Count
{
get {return _lista.Count;}
}
public void CopyTo(Array array, int index)
{
Fuente 2 (...sigue)
En las colecciones se ven mucho estos
casos. Tenemos la interfaz ICollection, la
clase abstracta CollectionBase, que implementa ICollection y más de 20 clases que
heredan de CollectionBase.
<< dnm.arquitectura
_lista.CopyTo(array,index);
arAuto[1]=a2;
arAuto[2]=a3;
ColeccionAuto col = new ColeccionAuto(arAuto);
}
public object SyncRoot
{
get{return _lista.SyncRoot;}
}
try
{
col.Add(new Auto("Z","z"));
}
catch(NotSupportedException nse)
{
Console.WriteLine(nse.Message);
}
try
{
col.Insert(2,new Auto("Z","z"));
}
catch(NotSupportedException nse)
{
Console.WriteLine(nse.Message);
}
try
{
col.Clear();
}
catch(NotSupportedException nse)
{
Console.WriteLine(nse.Message);
}
try
{
col.Remove(a1);
}
catch(NotSupportedException nse)
{
Console.WriteLine(nse.Message);
}
try
{
col.RemoveAt(0);
}
catch(NotSupportedException nse)
{
Console.WriteLine(nse.Message);
}
#endregion
#region Miembros de IEnumerable
public IEnumerator GetEnumerator()
{
return _lista.GetEnumerator();
}
#endregion
}
public class ColeccionAuto:BaseColeccion
{
public ColeccionAuto(ICollection col):base(col)
{}
}
public class Auto
{
public Auto(string marca,string modelo)
{
Marca=marca;
Modelo=modelo;
}
public string Marca;
public string Modelo;
}
/// <summary>
/// Aplicacion de prueba
/// </summary>
public class Test
{
[STAThread]
static void Main(string[] args)
{
Auto a1 = new Auto("A","a");
Auto a2 = new Auto("B","b");
Auto a3 = new Auto("C","c");
Console.WriteLine();
Console.WriteLine(
"Presione cualquier tecla para continuar");
Console.ReadLine();
}
}
Auto[] arAuto = new Auto[3];
arAuto[0]=a1;
}
(...cotinuación) Fuente 2
Ejemplo
Voy a seguir con el ejemplo que puse al principio, en
el apartado de Contexto. Vea el fuente 2.
Patrones relacionados
• Composite: Utilizado para representar relaciones
jerárquicas. Todas las jerarquías tienen un grupo de
información común que nos permite movernos
entre las jerarquías.
• Bridge: Se definen dos interfaces que se comunican
entre sí, luego se crean clases abstractas y concretas a partir de estas dos interfaces. Por ejemplo, un
IMusico toca un IInstrumento, hasta llegar a que un
guitarrista, que es un músico de cuerda, toca una guitarra que es un instrumento de cuerda.
• Visitor: Un caso especial de Bridge, donde se extiende funcionalidad indirectamente. Para asociarlo con
algo conocido, el ToolTip es un control que con sólo
soltarse sobre el formulario hace que cada uno de los
otros controles que están en el mismo formulario se
le agregue una nueva propiedad que es el texto que
mostrará el ToolTip.
<<dotNetManía
Otro caso lo tenemos en los DataAdapter. Está
la interfaz IDataAdapter, con los métodos básicos
Fill y Update; la clase abstracta DataAdapter, que
implementa IDataAdapter, dejando los metodos Fill
y Update como abstractos; luego la clase abstracta
DBDataAdapter, que hereda de DataAdapter y le agrega propiedades relacionadas con las bases de datos,
como SelectCommand, dejando Fill y Update como
métodos que se pueden sobrescribir; y, por último,
las clases concretas según cada motor de bases de
datos, como SQLDataAdapter, que están marcadas
como no heredables para que nadie sobrescriba ningún método.
45
<< dnm.arquitectura
using System;
namespace Mixto
{
/// <summary>
/// Clase base de las entidades
/// </summary>
public abstract class BaseBE
{
public BaseBE()
{
}
public void Cargar(System.Data.IDataReader dr)
{
//TODO Hacer la carga por Reflection
}
}
/// <summary>
/// Log que se hace sobre una entidad
/// </summary>
public class Signatura:BaseBE
{
public DateTime FechaHoraCreacion;
public DateTime FechaHoraUltimaModificacion;
public string Creador;
public string Modificador;
}
/// <summary>
/// Clase base para quien use una firma
/// </summary>
public abstract class BaseFirmado:BaseBE
{
public Signatura Firma;
}
En estos casos, debemos:
• Juntar un conjunto de responsabilidad que creemos que está relacionada.
• Crear una clase con esa responsabilidad.
• Agregarlo como propiedad a una buena clase base.
• Hacer que quienes tengan que tener esa responsabilidad hereden de la nueva clase base.
En la figura 5 se ven estos pasos, primero se crea la
clase Signatura. Luego se crea la clase abstracta
BaseFirmado que a diferencia de la clase BaseEntidades
tiene la propiedad Firma de tipo Signatura. Todas las clases que no necesitan firma heredarán directamente de
BaseEntidades, mientras que aquellas que necesiten una
firma lo hacen de BaseFirmado e indirectamente continuarán heredando de BaseEntidades.
/// <summary>
/// Clase concretaque usa firma
/// </summary>
public class Comercial:BaseFirmado
{
public int IdComercial;
public string Nombre;
}
Figura 5.
/// <summary>
/// Clase que no usa firma
/// </summary>
public class Mensaje:BaseBE
{
public string Creador;
public string Destinatario;
public DateTime FechaHoraEmicion;
public DateTime FechaHoraLeido;
public int Prioridad;
}
}
<<dotNetManía
Fuente 3
46
De esta manera hemos unido los dos patrones, primero por medio de la SuperClase abstracta al crear una
interfaz y clase abstracta para tener un comportamiento común, y después el patrón delegado creando un clase asignándole una responsabilidad muy concreta, y que los demás delegan esa responsabilidad en
esta nueva clase. En el fuente 3 puede ver el código
del ejemplo anterior.
¿To be and not to be?,¿por qué no?
Conclusiones
Una de las afirmaciones que hice es que a veces tenemos dos soluciones posibles y optamos por una o por la
otra, cuando si unimos podemos mejorar aún más el diseño. ¿Se puede unir herencia y delegación?
Un pequeño ejemplo: Cuando se desarrollan
entidades de negocios por medio de clases, se suele colocar una clase base y seguir el patrón
SuperClase abstracta. Una vez me encontré frente a
un caso donde las clases de entidad tenían que tener
un log, pero luego resultó que no todas las clases
debían tener ese log porque eran invariables, es
decir, que después que se creaban no se podían
modificar, por ejemplo, los mensajes que se enviaban entre usuarios del sistema.
Siempre me gusta decir una frase que está en
“Analisys Pattern”, de Martin Fowler: "Los diseños
no son malos o buenos, sino más o menos provechosos". Expuse en la primera parte los problemas de la
herencia para que sepamos de antemano, si la usamos,
con qué nos podemos topar, y si el camino lo vemos
libre, pues usarla y si no está tan claro, mejor tirar
hacia delegación. Lo que es malo de la herencia es lo
que la hace fuerte, la dependencia que tiene una clase hija hacia la clase base es la que nos permite escribir código en la clase base, probarlo y saber que funcionará para todas sus hijas. Por otro lado, si no hemos
entendido bien el dominio de aplicación del cliente
podemos suponer ciertas cosas que no lo son y quedarnos con un diseño poco provechoso.
<< dnm.mvp.online
Jorge Serrano
Aviso para navegantes
La amplitud de movimiento de los MVP permite, en muchos casos, divulgar la tecnología Microsoft a rincones insospechados a través de los medios disponibles hoy día.
El artículo de la sección MVP Online de este mes trata de mostrar cómo la radio puede llegar a ser una buena prueba de la divulgación tecnológica. Alejandro Curquejo,
MVP de Windows, es un fiel ejemplo de esto que comento.
<< El título no es ningún aviso para el lector; es el nombre del pro-
Jorge Serrano
es redactor de dotNetManía. Es
Ingeniero Informático y MVP de
VB y de .NET. Es Webmaster de
PortalVB.com y autor de
diferentes libros y artículos
técnicos. Jorge está entre los
mejores profesores y
conferenciantes sobre la
tecnología .NET de nuestro país.
grama en el que participa Alejandro todos los martes
en la segunda parte del programa. Este programa radiofónico se emite de lunes a viernes a partir de las 21 horas
a través del Canal Sur Radio, una de las tres emisoras
de radio de la RTV Autonómica Andaluza o RTVA.
Como esta revista llega a ser leída incluso por algunos privilegiados fuera de nuestro país, comentaré brevemente, que Andalucía es una de las regiones de España,
situada al sur del país.
“Aviso para navegantes” es un programa que lleva
en antena muchos años. Se trata de un programa sobre
Internet y las nuevas tecnologías, y donde el objetivo
que se persigue, es el de informar y hacer reflexionar
sobre la nueva era digital, siempre desde un punto de
vista del usuario no especializado. En este programa se
abordan diferentes apartados, todos ellos dentro de secciones de noticias, ocio electrónico, seguridad en la red,
administración electrónica, software libre como Linux,
y software propietario como Windows.
Sobre la emisora Canal Sur Radio, diremos de ella
que es según el EGM (Estudio General de Medios), una
de las emisoras más escuchadas en la región de
Andalucía.
En el programa, Alejandro dispone de 10 minutos para hablar de la tecnología Windows XP. El buen
ambiente reinante y la genial transferencia de los
conocimientos por parte de Alejandro, hace que el
director del programa deje pasar de largo esos 10
minutos y éstos se extiendan a veces hasta los 25 ó 30
minutos incluso.
Ojos que no ven...
Cuando le toca a Alejandro el turno de participar
en el programa, el director le introduce en el tema
del día, a partir del cuál se desarrolla la plática.
Quizás la mayor dificultad del medio radiofónico para
hablar de un tema de carácter tan práctico y técnico como
la informática, es encontrar las palabras justas y adecuadas para describir el tema que se quiere abordar.
El espacio en el que participa Alejandro está enfocado a los usuarios no expertos, con grandes dosis de
entusiasmo por aprender. Por todo esto, un usuario
experto puede entender en un momento dado lo que
Alejandro podría querer explicar en un momento dado,
pero para un usuario novel, las explicaciones deben estar
muy preparadas y pensadas para que no haya dudas y
todo resulte ameno, didáctico y útil.
La informática no come a nadie
El espacio en el que colabora Alejandro, trata de llevar la informática a todos los usuarios, ayudándolos a
comprender las tareas más comunes y habituales.
En este programa, se les explica a los usuarios tanto tareas comunes como tareas un poco más complejas,
y aunque a algunos oyentes puedan resultarles algunas
de las tareas bastante obvias y sencillas, para un gran
número de usuarios y aficionados a la informática son
tareas muy interesantes y útiles.
Entre algunas de las tareas mencionadas por
Alejandro en el programa radiofónico en el que participa, podemos citar por ejemplo, la explicación a los usuarios de cómo instalar un sistema operativo, cómo se formatea un disco, cómo se crean particiones, como realizar una instalación dual, las acciones generales del mantenimiento de un equipo o una explicación de las diferencias entre el software y el hardware.
De todos los modos, Alejandro aborda a veces en el
programa una sección específica que se parece a algo
como “hágalo usted mismo”. En esta sección, se le anima al oyente a abrir su ordenador y conocer los entresijos de éste. En esta investigación, se le anima, enseña
<< dnm.mvp.online
Sobre Alejandro Curquejo
“Aviso para navegantes” es un programa que lleva
en antena muchos años. Se trata de un programa
sobre Internet y las nuevas tecnologías, y donde el
objetivo que se persigue, es el de informar y hacer
reflexionar sobre la nueva era digital
y explica al oyente cómo realizar una limpieza de polvo del ordenador,
cómo instalar un segundo disco duro, cómo mejorar el uso del sistema
operativo Windows XP y a usar herramientas fundamentales como por
ejemplo, el programa anti-spyware de Microsoft.
Aún y así, en el programa no se pasa por el olvido tampoco tratar
temas relacionados con la seguridad. El usuario debe conocer la importancia de la seguridad y por eso se le enseña a que se familiarice con
ella y con sus términos. Por todo esto, al usuario y por lo tanto al oyente, se le educa a que actualice su sistema operativo con regularidad y
se le explica el porqué de la importancia de las actualizaciones. De
hecho, se hace especial hincapié en el Service Pack 2 de Windows XP
y se indica que no es una simple actualización o una simple mejora del
sistema operativo de Microsoft.
Indudablemente, para contar todos estos temas, es necesario utilizar
un lenguaje llano, no purista ni lleno de tecnicismos. El oyente debe encontrarse completamente identificado para sentirse cómodo.
Conclusión
Es interesante saber que hay diferentes medios de comunicación para
informar y divulgar una tecnología como la informática, pero es muy curioso observar como uno de los medios de comunicación más antiguos de la
historia moderna, es el utilizado para divulgar en este caso, algo tan actual
como Internet, la tecnología y Windows XP.
La tarea más compleja en el caso de usar un medio radiofónico, es sin
duda el transmitir el mensaje para que llegue al oyente de forma clara y
concisa. Al contrario de una conversación telefónica, no existe emisor y
receptor que interactúen entre sí, y por lo tanto, sabiendo los temas que
se abordan, la complejidad en la comunicación es muy alta.
Alejandro Curquejo es
MVP de Windows XP desde Abril
de 2003, y es conocido en los
grupos de noticias de Windows
XP como Alezito. En su periplo por los bit y bytes, entra en
el mundillo informático en los
años 80 de la mano de una Casio
PB-100 para pasar posteriorAlejandro Curquejo
mente al nostálgico Spectrum
48K y más adelante a un QL de
Sinclair; todo ello mientras realizaba estudios sobre
Electrónica de Comunicaciones.
Desde aquel mismo instante, la informática, que
hasta ese momento sólo era privilegio de algunas
empresas, comenzaba a llegar a los usuarios y ocuparía un lugar importante entre sus aficiones y el mundo
laboral hasta el día de hoy.
Alezito es y ha sido colaborador habitual de los grupos de noticias de Windows 98, Windows ME y
Windows XP en castellano, siendo uno de los miembros más activos del grupo de noticias, con cerca de
10.000 intervenciones al año.
Además de participar en los foros de noticias, también es probador de versiones beta de aplicaciones
Microsoft, participando en muchas de ellas como en
el programa beta de Windows XP SP2 y Longhorn.
En lo que compete a su perfil profesional, Alezito
trabaja para un importante medio de telecomunicaciones, y comparte su trabajo y dedicación como MVP
en los foros, a formar a compañeros y empleados de su
misma empresa y a escribir numerosos artículos técnicos y trucos relacionados con Windows XP, además de
colaborar en Canal Sur Radio.
Puede recoger más información de las actividades
realizadas por Alezito en los grupos de noticias, o en
la web: http://www.multingles.net/tutexpertos.htm#ALE
Para otros asuntos o inquietudes, podrás contactar
con él en la dirección de e-mail [email protected].
Si quieres saber más sobre el programa MVP puedes consultar la página oficial de Microsoft en:
http://mvp.support.microsoft.com
Programación de la emisora
http://www.canalsur.es/PROGRAMAS/radio/index_radio.html
Sintonización de la emisora por Internet (con Real Player)
http://www.canalsur.es/Informativos/EmisionesDirecto/canalsurradio.ram
Sintonización por el Satélite ASTRA
Nombre de Servicio: ANDALUCÍA RADIO
Dial Digital+: 224
Satélite: Astra 2C
Transponder: 1056
Frecuencia Downlink: 10.818 MHz
Polarización: V
Symbol rate: 22 Mbaudios
FEC: 5/6
Codificación (acceso condicionado): Mediaguard
Network ID: 1
TS ID: 1056
Service ID: 29969
http://www.canalsur.es/PROGRAMAS/radio/programas/aviso_navegantes/index_aviso_navegantes_jorge_gonzalez.htm
Para descargarse emisiones anteriores en MP3
<<dotNetManía
Diales de Canal Sur Radio
49
dnm.comunidad.net
<<
dnm.comunidad.net
El sitio de “El Guille”
Un sitio con más de ocho años de historia
El sitio de “El Guille” ha crecido mucho desde que nació en 1996.Y no por “viejo”
está anticuado. Como él mismo dice, en el sitio de el Guille hay mucha información
y de la buena sobre .NET Framework. Guillermo Som es redactor de
dotNetManía, mentor asociado de Solid Quality Learning y miembro de INETA
Speaker Latin America por lo que se recorre el mundo dando conferencias
<< Hace unos días que Paco Marín, el editor de esta revista,
me pidió que escribiera algo sobre mi sitio, realmente
me dijo:
"...cuenta un poco la historia –o la prehistoria casi– de
tu sitio, qué es lo que se pretende con él, para qué puede ser
útil, etc."
Al principio, lo de prehistoria me hizo gracia, (todavía me la hace), y la verdad es que no anda muy desencaminado, ya que en estos tiempos que corren y tratándose de un sitio de programación, ocho años sí que se
puede considerar prehistoria...
Pero no te preocupes que no te voy a contar las batallitas que he tenido que mantener durante estos últimos
ocho años -realmente ocho años y medio- para mantener vivo y activo mi sitio. Pero como tengo que enrollarme un poco, pues algo sí que te contaré de todo este
tiempo que llevo en la red.
<<dotNetManía
Al principio fue...
50
Todo comenzó casi por casualidad, en aquellas fechas,
noviembre de 1996, yo mantenía un sitio dedicado a
noticias sobre Nerja y alrededores. El servidor que alojaba ese sitio lo gestionaba un amigo mío, y este caballero me comentó si quería tener un sitio para que yo
pusiera lo que quisiera en él. Le dije que sí, así me serviría para practicar más todo eso de crear páginas Web
y demás “novedades”, al menos para mí, sobre escribir
código HTML, ya que en esas fechas, prácticamente casi
todas las páginas había que hacerlas a mano, que eso de
tener un editor de HTML no era tan común como lo
es ahora. Así que rebusqué entre las cosillas que tenía en
mi disco duro, creo que en aquella época era uno de 100
megas, (sí, megas, no gigas), y empecé publicando algunos trucos de Visual Basic. En enero del 97 me apunté
a una lista de distribución de Visual Basic, (vb-es), ade-
más de empezar a visitar algunos grupos de noticias públicos de Microsoft, no sólo de Visual Basic, sino también
otros relacionados con la programación HTML y lenguajes scripts, ya que lo que yo iba descubriendo me servía para “orientar” a otros que estaban más perdidos que
yo. Así fue como poco a poco mi sitio fue creciendo, cuatro trucos por aquí, cuatro por allá; por suerte la gente
también empezó a colaborar con sus propios trucos, (creo
que la primera colaboración que recibí fue de David A.
Garza), hasta que en pocos meses era casi un sitio en el
que había que pararse para encontrar algo sobre Visual
Basic y en español, ya que en inglés sí que había otros
sitios, pero, si ya cuesta trabajo leer... tener que hacerlo
en inglés, pues como que costaba más, y si además del
idioma le añadías que todo era gratis y que encontrabas
un montón de código, pues mejor... sobre todo para
muchos que lo que necesitaban era precisamente esa
“rutinilla” que andaban buscando y que acababan por
solucionarle algunos quebraderos de cabeza.
En el mes de febrero de 1997 empecé a publicar artículos traducidos del inglés de, por aquél entonces, un
gran sitio dedicado a Visual Basic: VBOnline. En esa
labor de traducción, en la que el primer número me tocó
traducirlo todo a mí, colaboraron un montón de gente
que iban rotando, entre ellos mi buen amigo Joe
LeVasseur, el yankee menos yankee de todos los yankees. Esos artículos traducidos no estaban en mi sitio,
sino en uno independiente, aunque al cabo de poco tiempo, acabó como un directorio de mi sitio, ya que no seguimos con las traducciones porque al final casi todo el contenido de la versión USA era “semi” comercial y lo que
realmente interesaba era publicar temas relacionados
con el “código” y no traducir anuncios.
En todo este tiempo, el sitio de el Guille ha cambiado varias veces de ubicación, aunque hasta finales de
2003 siempre en el servidor de mi amigo Manolo: Web
Costasol. Incluso en los primeros meses ni tan siquiera se
llamaba “guille”, sino “guiller”, (con “r” al final), ya que
mi colega Manolo me llamaba así y así me “bautizó”.
La verdad es que en todos estos años, en más de una
ocasión mi sitio tuvo sus momentos críticos, al menos
<< dnm.comunidad.net
consumo de ancho de banda, de hecho ese
consumo es ilimitado, así que... el único
problema para que la cosa deje de funcionar es que todos los años por el mes de
marzo no tenga en mi cuenta el importe
del pago anual.
¿Que hay en el sitio de el
Guille?
Después de la batallita sobre la vida
desde la “prehistoria” hasta nuestros tiempos de mi sitio, ya va siendo hora de que
te cuente qué es lo que puedes encontrar
en él y cuales son mis intenciones o, las
razones para que el sitio exista.
Como te he contado antes, el sitio lo
empecé para publicar “cuatro truquillos”
que tenía, trucos que pensaba que a otros
les podía ser de interés, después empecé a escribir “tutoriales” (o entregas)
sobre temas que a muchos les interesaba, como la forma de crear un fichero
de ayuda e incluso un curso de programación con Visual Basic. Curso que
empecé en abril del 97 y que casi todas
las semanas iba actualizando, pero conforme pasaba el tiempo y al recibir más
visitas, también recibía más consultas,
tuve que ir alargando los plazos de entrega, ya que en ocasiones el responder a
todas esas consultas me llevaba incluso
más de ocho horas diarias, sí..., parece
una locura y de hecho era una locura
dedicar todo ese tiempo “por la cara” a
responder consultas, consultas que en
ocasiones se convertían hasta en peticiones, (y en algunos casos, exigencias),
de que les hiciera el programa completo... era como se suele decir que uno le
daba la mano y acababan queriendo el
brazo completo, así que... casi tuve que
cortarlo de raíz, de esa forma podía dedicarle más tiempo a publicar cosas nuevas, además de que la programación con
Visual Basic se iba complicando cada vez
más y necesitaba dedicar más tiempo a
investigar que a responder a consultas,
la mayoría de las cuales ya tenían respuesta en lo que había publicado en mi
sitio. Y es que algunos no llegaban a
entender que todo eso lo hacía, (y lo sigo
haciendo), sin recibir ninguna compensación económica, es decir, mantener el
sitio no es un trabajo remunerado,
vamos, que no hay ninguna empresa que
diga: “Guille tu dedícate a esto que yo
El Guille 1987-2005
te pago tus gastos, el alquiler de tu casa
y te doy de comer”, y para más INRI, ni
siquiera me dedico a la programación
profesional, al menos en el sentido de
que no vendo programas.
Afortunadamente no sólo era yo el que
publicaba nuevas cosas, y de forma altruista, sino que el número de colaboradores
también crecía casi a diario, incluso en la
actualidad son los colaboradores los que
se llevan todo el peso del contenido de mi
sitio, si no fuese por ellos no habría tantas cosas nuevas casi a diario.
Cosas que en los últimos años están
más enfocadas a la programación con
.NET, y no sólo dedicado al lenguaje
Visual Basic, que aunque es el que a más
gente atrae a mi sitio, realmente hay
muchas cosas publicadas sobre C# y en
general sobre todo lo que .NET
Framework ofrece, ya que hay que estar
al loro con lo que la gente demanda, y hoy
por hoy, la gente quiere saber más y mejor
sobre .NET, y aunque no esté bien decirlo, e incluso hay gente que todavía no lo
sabe, el sitio de el Guille tiene mucho contenido, y del bueno, sobre .NET
Framework, de hecho en mi caso particular, todo lo que publico lo hago siempre en los dos lenguajes principales de
.NET: Visual Basic y C#; y en lo que respecta a los colaboradores, siempre encontrarás autores que utilizan uno u otro lenguaje, así que... si aún no sabes dónde
encontrar información sobre cómo hacer
las cosas en .NET, ya sea en Visual Basic
o en C#, ya sea para trabajar con acceso a
datos mediante ADO.NET o para crear
sitios Web con ASP.NET o para crear y
utilizar servicios Web o para saber cómo
trabajar con encriptación, gráficos GDI+
o con cualquier cosa que te interese de
punto NET, sólo tienes que darte una vuelta por mi sitio: http://www.elGuille.info.
¡Te espero!
Guillero “El Guille” Som
<<dotNetManía
en lo referente a su permanencia, ya que
conforme pasaba el tiempo el sitio era más
popular y consumía más ancho de banda,
y como no reportaba beneficios, (todo
siempre ha sido gratis), pues mis peleas
me costaba para que no desapareciera; no
culpo a la gente de Costasol, ya que para
ellos era un gasto que crecía día a día y
durante demasiado tiempo soportaron
esos gastos, siete años para ser precisos.
Incluso llegué a buscar sitios gratuitos en
geocities e incluso en un servidor francés,
(que exigía que el contenido estuviese en
idioma de Asterix), por si esas conversaciones algún día se terminaban por convertir en discusiones. De hecho en marzo del 2003 la gente de BusiNet me ofreció espacio gratuito y así fue como apareció MundoProgramación, un sitio “espejo” con el que aseguraba la existencia del
sitio de “el Guille”. Fue a principios de
diciembre de ese mismo año cuando “de
pronto” el sitio que tenía en Costasol dejó
de existir, básicamente porque mi colega
ya no estaba a cargo de los servidores Web
y no podía seguir cubriéndome las espaldas, por tanto, tuve que buscar otro sitio
nuevo donde alojar las muchas cosas que
ya tenía publicadas, así es como nació elguille.info. Toda esta movida, y realmente las
últimas que tuve antes de esa fecha, estaba siempre motivada principalmente por
el consumo tan grande de ancho de banda, es más, en abril de 2004 tuve que
mudarme de nuevo, (aunque seguí conservando el mismo nombre), ya que en el
mes de marzo ese consumo se disparó (y
eso que tenía 40GB contratados), y “la
broma” me costó una pasta... aunque el
problema no fue realmente el dinero, sino
la forma “no clara” de calcular el importe extra que debía pagar, así que... agarré
los bártulos y me mudé nuevamente, y
hasta la fecha sigo en el mismo sitio, un
sitio en el que el límite sólo lo tengo en el
espacio que ocupe, y por suerte, no lo que
la gente “consuma”, ya que en el año que
llevo en el nuevo servidor, prácticamente
todos los meses se supera, y con creces, el
consumo de ancho de banda del mes anterior y hasta ahora no ha habido ninguna
queja ni tampoco nuevos “cargos extras”
en los importes pagados. Por supuesto,
esto es así porque el tipo de alojamiento
que tengo contratado no es el más económico, sino uno que me asegurara que
no tendría problemas con el “famoso”
51
dnm.todotnet.qa
Dino Esposito
Acceso a datos y contenedores de datos
<< En estos años hemos visto varios modelos de programación
Dino Esposito
es redactor de dotNetManía.
Formador, consultor y escritor
afincado en Roma. Miembro
del equipo de Wintellect,
Dino está especializado en
ASP.NET y ADO.NET. Puede
enviarle sus consultas a
[email protected]
para bases de datos en SQL Server, que se sucedían uno
a otro sin descanso. Las características suministradas por
el Sistema de Gestión de Bases de Datos subyacente (el
DBMS), cambiaban con el tiempo dando solución a los
requerimientos de los usuarios, y cumpliendo el objetivo de conseguir, cada vez, un producto más poderoso y
exitoso. De forma paralela, los modelos de acceso a datos,
evolucionaban para incorporar las novedades, mientras
mantenían un adecuado nivel de sencillez de uso de las,
cada vez, más complejas características internas ofrecidas por los servidores, tanto para el desarrollador como
para el administrador, de cara a construir la capa de acceso a datos. Hoy, los desarrolladores pueden utilizar objetos contenedores de alto nivel para almacenar y manipular datos. En un próximo futuro –en una predicción
evidente–, nos encontraremos utilizando objetos de negocio que implementen cualquier tipo de manipulación de
datos de una forma fácil y conveniente. De esta forma,
un viejo sueño de los desarrolladores se hará realidad:
usar objetos en lugar de registros. En ese día, la base de datos,
que ahora es parte constituyente del API se convertirá
–con todos los predicamentos– en una herramienta más.
Nos guste o no, esto nos lleva al siguiente paso de un
proceso que, iniciado hace una década con ODBC,
parece ahora despegar hacia el modelo de enlaces
Objeto/Relación (O/R). La abandonada iniciativa Object
Spaces. –que inicialmente era parte integrante de .NET
Framework 2.0– se muestra como un signo más del camino a seguir. Todo esto nos conduce a la primera pregunta de este mes.
¿Cuál es la diferencia entre ODBC y ADO.NET
y por qué Microsoft sintió la necesidad de crear un
modelo de objetos totalmente nuevo como
ADO.NET? ¿No bastaba con ADO?
Trabajé en mi primer proyecto Windows a principios de los 90. Nuestra aplicación necesitaba algún
tipo de soporte de bases de datos, aunque ésta no era
una de sus partes críticas. No había razón ninguna
para escoger entre Access, Paradox o quizás SQLServer. Adoptamos ODBC, que para la época era el
estándar emergente en conectividad de bases de
datos. Era una elección perfecta para nosotros, por
que lo conocíamos suficientemente. El API de
ODBC, de hecho, se diseñó para programadores de
C/C++.
ODBC fue el primer intento de normalizar el acceso a toda una serie de sistemas DBMS a través de un API
común. Antes de esto, los programadores no tenían más
remedio que adentrarse en las particularidades propias
de cada sistema de base de datos. Además, resultaba
imprescindible mantenerse al día de las novedades de
cada dialecto SQL y la arquitectura subyacente a él.
Aunque no era perfecto en sí mismo, ODBC mostraba
la forma correcta de hacer las cosas. ODBC se diseñó
como un API orientada a C pero el advenimiento de
COM y los entornos RAD como Visual Basic planteó
de inmediato la necesidad de una alternativa basada en
COM. Más o menos al mismo tiempo, los desarrolladores de Access y Visual Basic disfrutaban del modelo
de objetos DAO incluido en Microsoft Access y controlado por el motor de datos JET. DAO fue mejorado para
permitir el acceso a SQL Server y Oracle vía ODBC.
Básicamente, DAO actuaba como un proxy entre nuestro código y el API de ODBC. Este modelo, sin embargo, introdujo cierta sobrecarga, debido a que los resultados tenían que ser reconvertidos al modelo de DAO,
para poderse utilizar realmente.
Para soslayar esta dificultad, Microsoft introdujo
RDO y, después, ODBCDirect. Los Objetos de Datos
Remotos (RDO) son un modelo de objetos COM que
expone las funcionalidades del modelo ODBC. No tiene más posibilidades o es más potente que el modelo
ODBC; es sencillamente, un “envoltorio” COM para
ODBC diseñado para hacer ODBC accesible desde un
fichero de script, la Web, o aplicaciones Visual Basic.
ODBCDirect, sin embargo, se creó para acelerar las aplicaciones existentes que accedían a SQL Server.
ODBCdirect es una especie de modo de trabajo DAO.
Cuando se habilita, utiliza RDO y ODBC en lugar de
JET para leer y escribir datos en las bases de datos SQL
Server.
No obstante, la primera innovación significativa en
el acceso a datos tras ODBC fue OLE-DB. OLE-DB
se introdujo por primera vez en 1998 como parte de la
¿
¿Cuál es la diferencia entre ODBC
y ADO.NET y por qué Microsoft
creó un modelo de datos totalmente nuevo como ADO.NET?
?
<< dnm.todotnet.qa
y se ha sustituido por el proveedor de datos
administrado. Además, en .NET, se pueden llamar a los proveedores de OLE-DB
directamente, sin la intervención de ADO.
ADO.NET es un conjunto de clases
que expone servicios de acceso a datos a
las aplicaciones .NET. Existen varias diferencias sintácticas entre los modelos de
ADO y ADO.NET. A pesar de todo, las
funcionalidades de ADO y ADO.NET se
parecen bastante debido a que Microsoft
hizo lo posible para que la similitud entre
la sintaxis de ambos modelos fuera máxima. De esta forma, los desarrolladores no
necesitan familiarizarse con demasiados
conceptos nuevos para utilizar ADO.NET
y pueden migrar aplicaciones mediante
una curva de aprendizaje relativamente
suave. Con ADO.NET, probablemente,
no podrás reutilizar mucho del código
existente, pero, ciertamente, podrás reutilizar todos tus conocimientos de ADO.
ADO.NET consiste en dos bloques
de alto nivel: contenedores y proveedores de
datos. Las clases contenedoras de datos forman una especie de modelo de bases de
datos en memoria. Clases como DataSet,
DataTable y DataView son clases tipo array
y pueden ser rellenadas con cualquier dato,
incluyendo datos leídos de una base de
datos. Además, las clases suministran características avanzadas que soportan un modelo de base de datos desconectado, basado
en memoria, con características avanzadas
tales como tablas, relaciones, restricciones y claves primarias.
Son la contrapartida de los proveedores OLE-DB. Los proveedores administrados acceden a los sistemas DBMS, y en general a los
almacenamientos de datos, exponiendo sus funcionalidades a través
de una interfaz común de programación y contenedores de datos.
Los proveedores administrados
se diferencian de los proveedores
OLE-DB al menos en dos aspectos: son objetos administrados (en
oposición a los objetos COM) y son más
sencillos (implementando un conjunto
más compacto de interfaces). Otra clara
ventaja de los proveedores administrados
es que devuelven datos utilizando objetos
específicos del framework de alto nivel,
haciendo innecesaria cualquier otra conversión (como el Recordset de ADO) a contenedores más manejables. Esas son las
razones por las que Microsoft abandonó
ADO y OLE-DB en favor de un nuevo
modelo: ADO.NET
Hay tantas clases de colecciones en
el .NET Framework que uno se confunde fácilmente. Pero, afortunadamente, usted puede ayudarnos ¿no?
Exacto. Mi labor aquí es (tratar de)
ayudar y arrojar algo de luz sobre los puntos oscuros. ¿Te quejas del número de
colecciones en la versión 1.1 de .NET
Framework? Pues tienes que echar un vistazo a los generics en .NET Framework
2.0. Generics dobla el número de opciones
disponibles.
Al más alto nivel de abstracción, una
colección sirve de contenedor para instancias de otras clases. Todas las clases de
colección implementan la interfaz
ICollection, que, a su vez, implementa la
interfaz IEnumerable. Como resultado,
todas las colecciones suministran las
siguientes funcionalidades básicas:
Disponen de una propiedad Count que
devuelve el número de ítems en memoria; tienen también un método CopyTo()
para copiar sus elementos (todos o en parte) a un array externo; contienen un método GerEnumerator() que instancia un objeto enumerador para recorrer sus elementos. Este es el método que permite que
posteriormente, puedan recorrerse los
objetos que implementan esta interfaz
mediante bucles tipo foreach (C#)
/For…Each (VB.NET).
¿
Hay tantas clases de colecciones
en el .NET Framework que uno
se confunde fácilmente. Pero,
afortunadamente, usted puede
ayudarnos ¿no?
IList e IDictionary son dos interfaces que extienden ICollection otorgando
una definición más precisa a las clases
colectivas resultantes. ICollection sólo
suministra la funcionalidad mínima y básica. Por ejemplo, en la interfaz no existen
métodos para añadir o quitar elementos.
Esta función es justamente la que suministra la interfaz IList. En la interfaz
IList, los métodos Add() e Insert() aña-
?
<<dotNetManía
plataforma de Visual Studio 6.0. OLEDB era desde el punto de vista del desarrollo, lo que se dio en llamar visión UDA
(Universal Data Access). La idea inspiradora de UDA era que cualquier tipo de almacenamiento de datos fuera accesible a través de un conjunto común de interfaces
COM. Básicamente, es el mismo principio rector de ODBC, pero retocado y refinado para integrarse en la más popular y
exitosa plataforma de desarrollo del
momento: el Modelo de Objetos de
Componentes (COM).
De nuevo, el modelo –en sus inicios–
tenía ciertas imperfecciones. Totalmente
basado en COM, el modelo consumidor/proveedor de OLE-DB era relativamente fácil de implementar en aplicaciones C++, pero demostró su extrema dificultad para aplicaciones Visual Basic y
ASP. Ambos, los componentes de VB y
ASP carecen de la posibilidad de trabajar
con interfaces COM de bajo nivel, por no
mencionar que la generalidad del modelo de programación, era sofisticado y
requiere bastante trabajo para implementar incluso las operaciones más simples.
ActiveX Data Objects (ADO) es la librería COM creada para hacer accesible el
modelo OLE-DB a todos los entornos de
programación. Como RDO y ODBC, se
sitúa entre la aplicación y las API de acceso a datos de bajo nivel y sirve de mediador entre las operaciones garantizando
que los datos traspasados entre ésta y el
sistema DBMS se expongan a los usuarios potenciales en forma apropiada y conveniente.
ADO es la elección primaria –a menudo la única razonable– para construir una
capa de acceso a datos en COM, ASP y
aplicaciones VB6. También ha sido incorporado y resulta fácil de llamar desde otras
herramientas RAD no Microsoft, tales
como Delphi o PowerBuilder.
¿Y qué sucede si creamos aplicaciones
.NET? Lo primero, debido a que ADO
es un objeto COM no existe ninguna contraindicación por su arquitectura para que
sea llamado desde una aplicación .NET.
Dicho esto, sin embargo, la utilización de
ADO en .NET no es –generalmente– una
buena idea.
En .NET Framework, una gran parte de las funcionalidades de ADO han sido
incorporadas en el nuevo framework de
ADO.NET. El proveedor OLE-DB ya
no es el modo preferido de acceso a datos,
53
54
[email protected] [email protected]
<<dotNetManía
<< dnm.todotnet.qa
den elementos al final o en una posición concreta de la
colección. Los métodos Remove() y RemoveAt() borran
elementos, mientras el método Clear() vacía totalmente la colección. Finalmente, Contains() verifica si un ítem
con un valor dado pertenece a la colección e IndexOf()
devuelve el índice de un ítem especificado.
La interfaz IDictionary define un API que representa una colección de pares clave/valor. La interfaz expone
métodos similares a IList, pero con diferentes signaturas. Las clases Dictionary también muestran propiedades tales como Keys y Values. Ambos devuelven las colecciones respectivas de Claves y Valores del diccionario.
Algunos ejemplos típicos de estas clases son
ListDictionary, HashTable y SortedList.
Basados en las interfaces implementadas, podemos
reconocer tres tipos de colecciones en .NET Framework:
colecciones simples, listas y diccionarios. Las primeras
son clases secuenciales como Queue y Stack que típicamente, consumen ítems tras leerlos. Estas clases implementan ICollection solamente. Las listas (Lists) son clases que implementan IList (que, a su vez, hereda de
ICollection). Finalmente, los diccionarios implementan IDictionary e implícitamente ICollection.
En algunos casos, lo único que se necesita es una
colección particular de items de cierto tipo o una colección que añada un conjunto de nuevas características a
la colección base. En .NET Framework, se suministran
unas pocas colecciones fundamentales, como el sustrato para construir, a partir de ellas, nuevas colecciones a
medida. Las clases base abstractas son CollectionBase
DictionaryBase ReadonlyCollectionBase y NameObject
CollectionBase. Si necesitas una colección con un comportamiento específico, no tienes que reinventar la rueda, sino que puedes partir de una de esas colecciones
bien conocidas. La interfaz de programación de las clases base ya suministra todos los métodos y propiedades
que se necesitan para sobrescribir nuestra propia clase
de colección.
Las colecciones de propósito general son modificables. Hay algunas, sin embargo, específicas a un contexto dado, cuyos ítems son de sólo lectura. Un ejemplo de
una colección de sólo lectura es la clase ProcessModule
Collection en el espacio de nombres System.Diagnostics.
La clase ReadonlyCollectionBase suministra un sustrato
sobre el que construir colecciones no modificables.
¿Cuál es la colección adecuada para tu propia aplicación? La regla de oro es no usar colecciones con características que no se necesiten. Para aplicar esta regla,
comienza tu examen y valoración desde abajo, o sea, desde las clases más simples de la jerarquía.
Considera la utilización de Queue y Stack sólo si necesitas eliminar elementos tras leerlos. Si necesitas ejecutar más de una lectura sobre el mismo elemento, piensa en otras opciones. ¿Los arrays serían apropiados? Los
arrays específicos de los lenguajes son los más apropiados, en especial si se trata de arrays unidimensionales.
De hecho, en este caso, los compiladores de los lengua-
Los proveedores administrados se
diferencian de los proveedores
OLE-DB al menos en dos aspectos: son
objetos administrados (en oposición a
los objetos COM) y son más sencillos
jes pueden usar intrucciones ad hoc para procesarlos. Sin
embargo, los arrays son de dimensión fija. ¿Necesitas un
objeto que pueda crecer? En tal caso, ArrayList es la
mejor opción.
Muchas otras clases de colecciones usan objetos
ArrayList internamente para “cachear” datos que después son mostrados en interfaces más avanzadas. En la
mayoría de los casos un ArrayList es perfecto y guarda
el equilibrio entre eficiencia y facilidad de uso. ¿En qué
casos no resulta apropiado ArrayList? Por ejemplo, si
vas a rellenarlo con cadenas (strings). En ese caso, utiliza StringCollection. ArrayList sólo soporta acceso indexado a los ítems, pero no soporta ordenación o inversión de índices. ¡No es una lista ordenada, sin embargo!
Un objeto que reordena sus items tras realizar cambios,
es –normalmente– mucho más pesado que aquellos que
sólo ordenan a petición. Ten bien clara esta distinción a
la hora de escoger.
Si necesitas acceso basado en claves, en lugar de índices, entonces decide entre una clase HashTable y un
ListDictionary basándote en el número de ítems que
prevés manejar. Cuando son pocos items, lo apropiado
es un ListDictionary. ¿Pero, qué hacer si el número de
items puede crecer indiscriminadamente dependiendo
de factores del tiempo de ejecución? En lugar de controlar el número de items en la lista y entonces cambiar
a una tabla hash cuando se exceda cierto límite, puedes
usar más eficientemente la clase HybridDictionary que
hace justo esta tarea. Se trata de una colección adecuada cuando el tamaño del diccionario es desconocido. La
clase se cambia automáticamente a HashTable cuando
hay más de 15 items almacenados, y siempre mantiene
un aceptable nivel de rendimiento.
Si sabes que sólo vas a manejar cadenas, String
Dictionary es una mejor opción que HashTable. Sin
embargo, si vas a manejar muchas cadenas duplicadas
considera la utilización de la clase System.Xml.NameTable,
que suministra un almacenamiento altamente optimizado y un mecanismo de búsqueda basado en referencias
de cadenas, en vez de ordinales de cadenas.
Las clases más lentas son SortedList y
NameValueCollection, debido a razones estructurales: son
las más complejas y ricas de las clases de colección.
Deberías considerar su uso sólo si necesitas al mismo
tiempo acceso indexado y basado en claves.
Traducción por Marino Posadas
publireportaje
<<
publireportaje
El eLearning al servicio del desarrollador
El Máster Alhambra-Eidos en Tecnologías Avanzadas para el
Desarrollo de Software
<< No es fácil para los profesionales del desa-
Alhambra-Eidos aporta, como desde hace muchos
años viene haciendo, su Máster en Tecnologías
Avanzadas para el Desarrollo de Software, uno de los
más sólidos programas formativos al que pueden
acceder los desarrolladores para alcanzar el nivel
de conocimiento que las complicadas arquitecturas
tecnológicas actuales les exigen
Luis Miguel Blanco y Guido Peterssen (de izquierda a derecha)
¿A qué achacas el éxito y el prestigio de la versión virtual de vuestro Máster?
Guido Peterssen: Bueno, yo creo que hay
varios factores:
• El primero es la seriedad. El Máster en su versión presencial se está impartiendo desde el año
1993 y la versión virtual simplemente ha heredado la experiencia y buenas prácticas de su
hermano mayor.
• El segundo es la experiencia. En la convocatoria de 2005-2006 entramos en el octavo año de
impartición virtual, lo que hace al alumno consciente que no somos alguien que improvisa
algunas cosas por Internet y usando el correo
electrónico para contactar con el tutor, monta
un curso.
• El tercero es el rigor y la organización. Quien
ha estudiado con nosotros sabe que se encuentra con un itinerario absolutamente reglamentado de trabajo, con tutorías semanales planificadas, con miles de páginas de material y dece-
<<dotNetManía
rrollo de software mantenerse al día
en sus conocimientos y habilidades
en un entorno tan dinámico y cambiante como el nuestro. AlhambraEidos aporta, como desde hace
muchos años viene haciendo, su
Máster en Tecnologías Avanzadas
para el Desarrollo de Software,
uno de los más sólidos programas
formativos al que pueden acceder
los desarrolladores para alcanzar el
nivel de conocimiento que las complicadas arquitecturas tecnológicas
actuales les exigen. Este año, los responsables de dicho plan formativo
nos hablan de la versión virtual del
mismo, una de las más usadas por
los desarrolladores que no tienen
tiempo para acceder a los mucho más densos programas presenciales. Guido Peterssen, responsable del
área de eLearning de Alhambra-Eidos y Luis Miguel
Blanco, coordinador de la versión virtual de del
Máster contestan nuestras preguntas.
55
<< publireportaje
<<dotNetManía
La verdad es que estamos muy
orgullosos de las continuas
felicitaciones que recibimos de los
alumnos que terminan su proceso de
estudio con nosotros
56
nas de videoconferencias. En fin, con un entorno de enseñanza garantizado que genera cada
año un buen número de titulados.
¿Cómo es el proceso de tutorización que se realiza por parte del profesorado?
Luis Miguel Blanco: Yo me ocupo de la coordinación general del Máster y además tutorizo alguno de sus módulos. Los profesores procuramos estar
siempre encima de las necesidades del alumno.
Participamos en los foros de debate sobre las distintas temáticas, atendemos las consultas de los
alumnos y, además, tenemos todas las semanas tutorías planificadas con ellos, donde atendemos de
modo síncrono cualquier duda y orientamos el proceso de estudio. La verdad es que estamos muy
orgullosos de las continuas felicitaciones que recibimos de los alumnos que terminan su proceso de
estudio con nosotros.
De vuestro Máster destaca la absoluta actualización tecnológica de sus contenidos. ¿Cómo lo
hacéis?
Guido Peterssen: Invertimos cada año mucho
dinero en diseñar nuevos contenidos. Nunca ha
habido una edición del Máster igual a la del año
anterior. Por ejemplo, este año comenzamos ya con
la introducción al alumno a SQL Server 2005 y
Visual Studio 2005, aunque aún los productos no
están en la calle nosotros tenemos ya módulos que
orientan al alumno sobre el futuro uso de los mismos.
Decís que vuestro Máster sirve para obtener la
certificación MCAD, ¿cómo es esto?
Luis Miguel Blanco: El Máster tiene muchos
más contenidos de los que se exigen para obtener la
certificación MCAD, pero existe una parte del mismo que se ciñe absolutamente a los contenidos oficiales de Microsoft para la obtención de dicha titulación. No en vano somos el centro de formación
oficial de Microsoft que más titulados MCAD genera cada año. Nuestra especialidad es el desarrollo de
software y sabemos perfectamente qué es lo que tiene que conocer un desarrollador para afrontar con
éxito el proceso de certificación.
<< dnm.biblioteca.net
dnm.biblioteca.net
ADO.NET and System.Xml 2.0
Alex Homer, Dave Sussman y Mark Fussel
Editorial: Addison-Wesley
ISBN: 0321247124
Páginas: 560
Publicado: Enero, 2005 (2ª edición)
Autores populares en el mundo de los eventos de desarrollo Microsoft, Alex Homer
se dio a conocer con su popular “XML IE5”, ya en los primeros estadios de implantación del soporte XML en el navegador de Microsoft.
C# 2.0: Practical Guide for Programmers
Michel de Champlain y Brian Patrick
Editorial: Morgan Kaufmann
ISBN: 0121674517
Páginas: 271
Publicado: Febrero, 2005
Autores, previamente, de “Java jumpstart: using object concepts and UML”,
Champlain y Patrick, abordan este proyecto desde un punto de vista muy práctico, cubriendo las características del lenguaje, pero dejando claros ejemplos de los
fundamentos y de cómo esos fundamentos han variado en algunos casos para esta
nueva versión del lenguaje.
Todas las novedades están claramente remarcadas, y acompañadas por pequeños ejercicios (snippets) que pueden usarse con facilidad para la probatura del
código. Además, las características están organizadas según los fundamentos de
la OOP y sus características principales, de forma que la experiencia didáctica
sea más clara.
<<dotNetManía
<<
En esta obra, junto a Sussman y Fussel, recorren las novedades de desarrollo de
ADO.NET 2.0, junto a las muchas novedades del namespace System.Xml, en lo
relativo a la programación asíncrona, transacciones, integración con SQL Server
2005 (por ejemplo, su utilización como base de datos XML), personalización de la
seriación de datos XML y consideraciones de rendimiento. Mereció los elogios de
los propios autores de la herramienta.
57
<< dnm.desvan
noticias.noticias
Marino Posadas
Singularity:Un nuevo sistema operativo para investigación
escrito en C#
Dos investigadores de
Microsoft Research, Jim
Larus y Galen Hunt, han
dirigido un curioso proyecto de construcción de un sistema operativo denominado
Singularity, con propósitos
de investigación, que, según sus autores tiene por objeto la construcción de sistemas fiables a través de la innovación en areas de sistemas, lenguajes y herramientas.
Para más información, el proyecto tiene una Web propia: http://research.microsoft.com/os/singularity.
¿Cómo (y cuándo) será Office 12 en la realidad?
Una vez más recurrimos a Paul Thurrot y su Windows
SuperSite para leer de sus muy próximas fuentes que Office
12 saldrá después de Longhorn
(del que siguen afirmando que
estará
RTM
(Ready
To
Manufacture) en mayo de 2006.
Según el cronista, Office 12 no verá la luz hasta octubre
de 2006, con una primera beta pública a primeros de ese
año. Algunas de las características más notables de esa versión, tienen que ver con la productividad empresarial.
Desde un gran número de posibilidades de reutilización
de documentos, hasta las búsquedas rápidas de materiales, propiciadas por la tecnología subyacente en Longhorn.
Office 12 será más gráfico, favoreciendo la conversión de
textos en imágenes de todo tipo y la colaboración, búsqueda y recopilación analítica y sintética de información
serán pilares de la nueva versión. Respecto a los requisitos de máquina, serán más o menos los normales de ahora, ejecutándose tanto en Windows XP SP2 como en
Longhorn (cliente).
Documentos en la Red
Enterprise 1.0 Hands-On-Labs: http://www.microsoft.com/
downloads/details.aspx?FamilyID=b9bff619-236c-4bbb9aa1-2e7bc562c7f5&DisplayLang=en Este
es el sitio de descarga de las prácticas de
laboratorio para la Patterns&Practices
Enterprise Library. Incluye 8 laboratorios
distintos en VB.NET y C#.
Implementing Manage code in SQL Server 2005: Por
Jagadish Chaterjee, gran experto en bases de
datos y asiduo contribuidor de ASPFree, publica
en
http://www.aspfree.com/c/a/MS-SQLServer/Implementing-Managed-code-in-SQL-Server-2005using-Visual-Studio-NET-2005/ un documento introductorio a las características de uso del CLR desde la
nueva versión de SQL Server.
<<dotNetManía
Implicaciones y repercusiones de las clases parciales en
.NET Framework 2.0: Gran artículo de nuestro colabo-
58
rador Dino Esposito en DevX,
que recorre las implicaciones
arquitectónicas que las nuevas
clases parciales tienen en el
desarrollo. Disponible en http://www.devx.com/codemag/Article/27819?trk=DXRSS_LATEST.
A Jaime, un lanzamiento más del 2005.Alberto, todo un padre para los MVP
españoles, ya tiene un MVP, digo un niño, más que mimar. ¡Suerte Jaime!

Documentos relacionados