El modelo de objetos de Visual Studio .NET El modelo de objetos

Transcripción

El modelo de objetos de Visual Studio .NET El modelo de objetos
nº18 septiembre 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
El modelo de objetos de Visual Studio .NET
Tech-Ed 2005
Terminó el tiempo de espera
Entrevista
Alexander Vaschillo
Equipo de desarrollo de SQL Server y WinFS
Microsoft Corporation
Laboratorio
Component Art Web UI 2.1
ToDotNet Q&A
ASP.NET 2.0 está aterrizando
MVP Online
Campus MVP
Legal
.NET y software libre
Añadiendo nuestra aplicación
al área de notificación •
Ordenación de datos en
Reporting Services •
Atención MySQL, aquí
dotNet, ¿me recibe? •
Interfaces •¡Mi madre
es un Singleton!
dnm.editorial
dotNetManía
Recta final
Vol. II •Número 18 • Septiembre 2005
Precio: 6€ (España)
Editor
Paco Marín
([email protected])
Administración
Pilar Pérez
([email protected])
Asesor Técnico
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, Daniel
Mazzini, 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
Javier Aragonés Miranda, Carlos Quintero,
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
<<
Longhorn, Indigo, Avalon... ya son nombres para la historia también. Aún no he conseguido quitarme de la cabeza a Yukon y
Whidbey y ya tengo que entrenarme para
decir Windows Vista o Windows Communication Foundation o Windows Presentation Foundation, o lo que es peor, las siglas
WCF o WPF. Por favor, pronucie en voz alta:
UVEDOBLECEEFE (y si no en inglés que
es peor) y luego diga suavemente: Indigo...
¿con cuál nos quedamos...? Puede repetir con
WPF y Avalon con idénticos resultados. Claro
que a lo mejor es como ir con zapatillas cómodas a una fiesta de etiqueta; a todos nos gustaría más pero todos vamos con zapatos que estamos deseando quitarnos. A lo mejor el marketing es como ese tipo de normas sociales.
Aunque hay empresas que han triunfado sin
seguirlas, por ejemplo, Google o Yahoo, que
no les dio por llamarse..., qué sé yo, GSE
(Global Searching Engine), por ejemplo.
¡Y qué más da! La cuestión es que los
cambios de nombres en clave por los nombres de “verdad” suponen entrar en la recta final de una etapa de grandes cambios.
Porque Windows Vista Beta 1 es el principio de un gran cambio, no sólo para los
usuarios de Windows, también para los profesionales de las TI y sobre todo para los
desarrolladores. Ya tenemos el WinFX
Runtime Components Beta 1 (para Windows
Vista Beta 1) y un SDK, concretamente el
Microsoft WinFX Software Development Kit
for Microsoft Pre-Release Windows Operating
System Code-Named Longhorn, Beta 1 (no
me cebaré...), y algunas ayudas para la programación con..., pérmitame que los escri-
ba por última vez, Avalon e Indigo, llamadas Visual Studio 2005 Extensions for WinFX
Beta 1, para ir entrenándonos. Muchas betas
1 para la beta 2 de Visual Studio 2005, pero
necesarias para que desde hoy pueda trabajar con Windows Vista y las tecnologías
que están por llegar desde este otoño al
verano que viene.
Bienvenido al número 18 de septiembre
de 2005 de dotNetManía.
Le recomiendo la entrevista de Marino
Posadas a Alexander Vaschillo, del equipo
de desarrollo de SQL Server y WinFS en
Microsoft Corporation. Ahora podemos decir,
sin temor a equivocarnos, que no tenemos ni
idea de cuándo saldrá WinFS (según nuestras
propias fuentes). Bromas aparte, es un todo un
lujo tener un mes más a otro miembro del equipo de desarrollo de SQL Server.
También hemos preparado desde Ámsterdam, una esmerada crónica de Tech-Ed
2005 que espero le resulte entretenida.
Si tiene pensado emprender algún tipo de
proyecto en .NET bajo alguna licencia de software libre o tiene curiosidad al respecto, leáse el artículo de Javier Aragonés sobre los
aspectos legales de éstas.
Por supuesto, no se pierda, además no
hemos publicado nada anteriormente, el artículo de Carlos Quintero sobre el modelo de
objetos de Visual Studio .NET y que actualizaremos a Visual Studio .NET 2005 en el
monográfico sobre éste que prepararemos para
el número de noviembre.
Por supuesto esto no es todo. Dentro
hay más...
Espero que le guste.
<<dotNetManía
Dedicada a los profesionales de la plataforma .NET
3
18
dnm.sumario
.NET y software libre
10-13
En este artículo se aclararán diversas cuestiones jurídicas sobre derechos y licencias que se
puede plantear un programador en relación con un proyecto para .NET y con el software
libre.
Entrevista a Alexander Vaschillo
14-16
Durante la celebración de los Academic Days 2005 en Lisboa, tuvimos ocasión de
charlar con uno de los integrantes del equipo de desarrollo de SQL Server y WinFS,
quien nos aclaraba algunos aspectos poco conocidos de la evolución de estas tecnologías.
Tech-Ed 2005
17-20
Llegamos a Ámsterdam con el convencimiento de que la mayoría de los asistentes deseaba
ver ya características aplicadas de las versiones, demos con espectáculo, trucos incipientes,
y algunos de los mejores anticipos de lo que las versiones finales van a ofrecer. Y así fue…
Añadiendo nuestra aplicación al área de notificación
22-25
Conseguir que nuestra aplicación apareciese en el área de notificación de Windows (como
hace Messenger o una herramienta antivirus) no era tarea fácil con las herramientas de
desarrollo antiguas. ¿Qué tal se porta .NET a la hora de implementar esta funcionalidad?
dnm.sumario
El modelo de objetos de Visual Studio .NET
26-30
Muchas de las tareas que realizamos a mano en Visual Studio .NET se pueden automatizar
mediante macros y muchas otras se pueden mejorar o extender mediante complementos.
En este artículo veremos el modelo de objetos que proporciona Visual Studio .NET para
poder manejar el propio entorno de desarrollo desde código.
Interfaces
32-34
En esta ocasión veremos más ejemplos, con idea de que nos quede claro cómo utilizar las
interfaces en nuestros proyectos, aunque en esta ocasión vamos a usar las interfaces de una
forma diferente a lo “habitual”, con la intención de que nos hagamos una idea de lo útiles
que pueden llegar a ser estos tipos de datos.
Ordenación de datos en Reporting Services
35-38
Uno de los aspectos principales en cualquier generador de informes radica en la capacidad
de ordenar los datos visualizados al usuario del modo más versátil posible. Reporting Services
es una herramienta que nos ayuda enormemente en nuestro trabajo como diseñadores de
informes, gracias a la extensa oferta de elementos que nos ofrece para la creación de informes
en general, y la aplicación de ordenamiento a los datos mostrados en particular.
Atención MySQL, aquí dotNet, ¿me recibe?
39-43
MySQL es el gestor de bases de datos open source líder en la actualidad. Independientemente
de la plataforma donde se esté ejecutando este, podemos conectarlo con nuestras aplicaciones
.NET usando algunas de las API de comunicación entre MySQL y aplicaciones Microsoft
.NET existentes. En este artículo describiremos de forma sencilla cómo realizar esta tarea
con VB.NET y C#.
¡Mi madre es un Singleton!
46-48
Siguiendo con el tema del último artículo, volvemos a tratar algunos patrones de diseño
básicos. En este caso veremos el singleton. Si bien puede tener dos lugares distintos de donde
se llaman, siempre es la misma instancia que atiende a la petición cliente.
dnm.mvp.online
49-50
Campus MVP
dnm.todotnet.qa
51-53
ASP.NET 2.0 está aterrizando
dnm.laboratorio.net
54-55
Component Art Web UI 2.1
dnm.biblioteca.net
57
Visual Studio Hacks (James Avery)
Hackers de sitios Web (Joel Scambray y Mike Schema)
dnm.desvan
58
6
noticias.noticias.noticias.noticias.noticias.noticias
<< dotNetManía
<< dnm.noticias
Windows Vista
El sistema operativo que sustituirá a Windows XP primero y a Windows 2003 Server después,
dejará de llamarse Longhorn definitivamente para llamarse Windows Vista.
El desarrollo de Longhorn, del nuevo explorador de Internet y de su modelo de programación WinFX enfilan la recta final. Primero, obteniendo sus nombres de “calle”: Windows Vista, Windows
Internet Explorer 7, Windows Presentation
Foundation (WPF) y Windows Communication Foundation (WCF) serán los
nombres comerciales de Longhorn,
Internet Explorer, Avalon e Indigo, respectivamente; segundo, con la primera
beta de todos ellos: ya están disponibles
la beta 1 de Windows Vista, Windows
Internet Explorer y WinFX que agrupa
las versiones preliminares de Avalon e
Indigo (falta WinFS ); por último, se han
añadido muchos recursos para los desarrolladores, tanto de la nuevas betas, como
documentación, vídeos, ejemplos, herramientas, etc., en la nueva Web llamada
Windows Vista Developer Center en :
http://msdn.microsoft.com/windowsvista, y
se ha creado una Web específica para
Windows Vista en http://www.windowsvista.com.
WinFX Runtime Components Beta 1
El WinFX Runtime Components Beta 1
permite a los desarrolladores experimentar con estas primeras compilaciones públicas de estas tecnologías.
WCF (Indigo) es el nombre del modelo de programación para la construcción
de aplicaciones de sistemas conectados.
Esto extiende el .NET Framework 2.0 con
API adicionales para la construcción de
servicios Web seguros, fiables y transaccionales que interoperan con plataformas
heterogéneas, combinando la funcionalidad de las tecnologías existentes de aplicaciones distribuidas de Microsoft (ASMX,
.NET Remoting, .NET Enterprise
Services, WSE y System Messaging).
WPF (Avalon) es el nombre del
modelo de programación del subsistema de presentación para Windows Vista.
A través de él programaremos el interfaz gráfico con código administrado de
.NET Framework.
Esta beta 1 soporta Visual Studio 2005
beta 2 y .NET Framework 2.0.
WinFX SDK para Windows Vista, Beta 1
Microsoft WinFX SDK contiene documentación, ejemplos y herramientas diseñadas para ayudarle a desarrollar aplicaciones y librerías gestionadas usando
WinFX. Esta release incluye documentación acerca del uso de .NET Framework
2.0, de Windows Presentation Foundation y
de Windows Communications Foundation.
La documentación y los ejemplos de
tecnología y aplicación -en Visual Basic,
C# y C++- le servirán para comprender
cómo usar los API de WinFX en el desarrollo de aplicaciones, mientras que las
herramientas le serán de gran ayuda para
dicho desarrollo.
El WinFX SDK Beta 1 precisa de
tener instalado previamente el WinFX
Estándar ECMA para la especifiación del lenguaje C# 3ª edición
El estándar del lenguaje de programación C# fue aprobado por primera vez por ECMA
en 2002 y por ISO /IEC en 2003.
A finales de
junio de 2005 la
asamblea general de ECMA aprobó la tercera edición de
los estándares para C# y CLI, adoptando
ya muchas de las características que se
incluirán en Visual Studio 2005.
En cuanto al lenguaje C#, el estándar
ahora contiene nuevas características, tales
como genéricos, tipos que pueden ser
nulos y métodos anónimos, los cuales pue-
den simplificar la gestión de eventos. En
cuanto a CLI, ahora incluye soporte de
primera clase para genéricos a nivel de runtime y de clase, además de un API paralelo que permite a los desarrolladores desarrollar más fácilmente código para la ejecución concurrente en múltiples hilos.
Puede descargarse la especificación
completa en formato PDF desde la URL:
http://www.ecma-international.org/publications/standards/Ecma-334.htm.
Runtime Beta 1 y del .NET Framework 2.0
y Visual Studio 2005 Beta2.
Visual Studio Extensions para WinFX
Beta 1
Visual Studio Extensions para
WinFX Beta 1 proporciona a los desarrolladores soporte para la construcción de aplicaciones WinFX usando la
Beta 2 de Visual Studio 2005. Éste
incluye soporte de Intellisense XAML
a través de extensiones de esquema
para el editor, plantillas de proyecto
para Windows Presentation Foundation
y para el Windows Communication
Foundation.
El Visual Studio Extensions for WinFX
Beta 1 precisa tener instalado previamente WinFX Runtime Beta 1, .NET
Framework 2.0, Visual Studio 2005 Beta2 y
Win FX SDK Beta 1 (mejor consulte en la
Web, por si acaso...).
Pueden descargarse todas las versiones desde el centro de descargas
para desarrolladores de Microsoft en:
http://msdn.microsoft.com/downloads.
Diponibiliad
Desde el 3 de agosto, Windows Vista
Beta 1 está disponible para betatesters y
suscriptores a MSDN y TechNet;
Windows Longhorn Server Beta 1 está
disponible sólo para un grupo elegido de
betatesters; mientas que las primeras betas
del modelo de programación y de
Windows Internet Explorer 7 están disponibles públicamente.
Altova presenta AltovaXML, un
motor XML gratuito
Altova ha
presentado
AltovaXML, un procesador que incluye el mismo motor de validación XSLT
1.0, XSLT 2.0, XQuery y XML que
incorporan el resto de sus herramientas de desarrollo XML.
Puede descargarlo de forma gratuita desde la Web de Altova en
http://www.altova.com/altovaxml.html y
usarlo en sus aplicaciones libre de
royalties.
dnm.noticias
Patterns & Practices Enterprise Library de Junio 2005
Microsoft Baseline Security Analyzer 2.0
Microsoft Baseline Security Analyzer (MBSA) 2.0 es una herramienta diseñada para facilitar la
detección de problemas de seguridad de los equipos de las pequeñas y medianas empresas.
La nueva versión es una actualización menor
de la que apareció en enero de 2005
MBSA nos ayudará a mejorar la seguridad
de nuestros equipos, encontrando los errores
de configuración y uso más habituales. La nueva versión ofrece un interfaz de usuario más
intuitivo y más textos informativos en comparación con versiones anteriores, calificación
rigurosa, búsqueda local y remota de actualizaciones de seguridad de Office XP o superior,
compatibilidad con los servidos de Windows
Server Update, registro y actualización del agente, automática desde Microsoft Update, sopor-
Enterprise Library es una
librería de Application Blocks que
están diseñados para guiar a los
desarrolladores en el uso de
buenas prácticas de desarrollo. Aportan todo
el código fuente y éste puede ser usado tal
cual o modificado e incluirlo en nuestras aplicaciones. Todos los Application Blocks han sido
actualizados con un particular enfoque en la
consistencia, extensibilidad y la facilidad de
uso e integración.
Esta actualización contiene los mismos
Application Blocks, pero con los parches y extensiones pedidos por la comunidad de usuarios.
Puede descargarse desde: http://msdn.
microsoft.com/practices/default.aspx?pull=/libra
ry/en-us/dnpag2/html/entlib.asp
Windows Mobile 5.0 Developer Evaluation Kit
El Windows Mobile 5.0 Developer Evaluation Kit le permite comenzar a desarrollar aplicaciones para
Windows Mobile 5.0 antes de la aparición oficial de Visual Studio 2005.
Este kit incluye herramientas de desarrollo y recursos técnicos necesarios para
desarrollar aplicaciones con Visual Studio
2005, incluyendo el propio Visual Studio
2005 Beta 2, Windows Mobile 5.0 SDK para
Smartphone y para Pocket PC, Microsoft
BizTalk Server 2006 Beta 1
BizTalk Server 2006 Beta 1 será compatible con
el runtime de 64 bit de Windows Server 2003,
.NET Framework 2.0,Windows Server 2003 R2,
Visual Studio 2005 y SQL Server 2005.
tibilidad para el protocolo de autenticación de correo electrónico a través del ID
del remitente o el Exchange Intelligent
Message Filter, mailboxes mejorados que
podrán llegar a tener hasta 75 Gb, un nuevo formato para la libreta de direcciones
offline, mejoras de rendimiento, etc.
Puede visitar para más información los
grupos de usuarios de Exchange Server
(http://www.microsoft.com/technet/community/newsgroups/server/exchange.mspx) o los
blogs relacionados (http://blogs.technet.com/
exchange/default.aspx).
Para descargar esta CTP vaya a:
http://www.microsoft.com/exchange.
La beta 1 de SQL Server 2005 JDBC
Driver incluye: compatibilidad con SQL
Server 2000 y SQL Server 2005, compatibilidad con JDBC 3.0, rendimiento mejorado, soporte con transacción XA mejorada, soporte BLOB y CLOB, soporte con
autenticación integrada, conjunto de resultados actualizable.
Puede descargarlo desde: http://www.microsoft.com/sql/downloads/2005/jdbc.mspx
Nuevos recursos desde
Visual Studio 2005
Developer Center
101 Samples for Visual Studio 2005
http://lab.msdn.microsoft.com/vs2005/downloads/101samples/default.aspx
Visual Studio 2005 Starter Kit
http://lab.msdn.microsoft.com/vs2005/downloads/starterkits
Vídeos para Visual Studio 2005 ediciones Express
http://lab.msdn.microsoft.com/express/beginner/default.aspx
dnm.noticias
<< dotNetManía
Microsoft ha liberado la primera beta de
SQL Server 2005 JDBC Driver. Esta descarga está disponible para todos los usuarios
de SQL Server de forma gratuita y proporciona acceso a SQL Server 2000 y SQL
Server 2005 desde cualquier aplicación Java,
aplicación servidora o applet de Java. Este es
un JDBC de tipo 4 que proporciona conectividad a través del estándar API JDBC disponible en J2EE.
Exchange Server 2003 SP2 CTP
Desde el 19 de agosto está disponible
para su descarga la edición CTP del SP2
de Exchange Server 2003 que saldrá, muy
probablemente antes de que este año termine.
Las mejoras incluyen compresión adicional, soporte opcional de autenticación
basada en certificados, mejoras del correo
electrónico móvil, mejoras en la protección contra el spam, que incluye compa-
ActiveSync 4.0, Microsoft Device Emulator
1.0 Community Preview, documentación y
vídeos de formación.
Puede solicitarlo en CD gratuitamente
desde: http://msdn.microsoft.com/mobility/windowsmobile/howto/resourcekit.
SQL Server 2005 JDBC Driver Beta 1
En el pasado Tech-Ed 2005 de Orlando
se anunció que BizTalk Server 2006 aparecerá en la semana del 7 de noviembre junto a SQL Server 2005 y Visual Studio 2005
como parte la plataforma de la próxima
generación de sistemas conectados. Sin
embargo, la versión RTM (Release To
Manufacturing) no verá la luz hasta el primer cuarto de 2006.
Si quiere descargarse esta beta vaya a
http://www.microsoft.com/biztalk/evaluation/bts2
006beta.mspx y siga las instrucciones.
Exchange Server 2003 SP2 CTP es una prerelease no soportada por los servicios de
soporte al cliente de Microsoft y que se
distribuye con el propósito de obtener
comentarios de los usuarios.
te para la detección de actualizaciones de
Windows 64 bit y Windows XP Embedded.
Los sistemas para los que está diseñado
son: Windows 2000 SP3, Office XP,
Exchange 2000 o superior, SQL Server 2000
SP4 o versiones superiores.
Los usuarios de los servicios de Windows
Server Update deberían actualizarse a MBSA
2.0 por razones de compatibilidad.
Más información en: http://www.microsoft.com/technet/security/tools/mbsa2
7
<< dnm.noticias
Eventos
PDC 2005. Developer powered
Desde el 13 al 16 de septiembre de 2005 Microsoft celebra el PDC 2005, el mayor evento mundial
dedicado a las próximas tecnologías de Microsoft para desarrolladores, en Los Ángeles (CaliforniaUSA) ante miles de desarrolladores de todo el mundo.
Este evento, que se celebra una
vez cada dos años, reúne a los principales arquitectos de software de la compañía para exponer sus trabajos ante la comunidad de desarrolladores. Así, podremos oír
de primera mano, cuáles son las nuevas características, por ejemplo, del nuevo C# 3.0
directamente del padre de C#, Anders
Hejlsberg.
La primera keynote correrá a cargo de
Bill Gates, quien desvelará, junto con otros
ejecutivos de Microsoft, las últimas innovaciones de la plataforma de Microsoft para
desarrolladores. Existe una larguísima lista
de ponentes, muchos de ellos ilustres, que
puede consultar en la página oficial que está
en: http://msdn.microsoft.com/events/pdc.
Este año se focalizará en las innovaciones de desarrollo para Windows Vista, concretamente con el Windows Presentation
Foundation (WPF) –antes Avalon– y Windows
Communication Foundation (WCF) –antes
Indigo– y la próxima versión de Office conocida en clave como Office 12.
Más de 900 bloggers
están contribuyendo con el
sitio Web PDC Bloggers
(http://pdcbloggers.net ), que
proporciona a los desarrolladores una alternativa de
conexión para poder comunicarse con los asistentes a
la conferencia y dar su opinión a la amplia comunidad
de desarrolladores.
Más información en: http://www.developerpowered.com.
dotNetManía estará allí
Para el próximo número publicaremos
un extenso resumen de dicho evento tal y
como hemos hecho este mes con el TechEd Europe 2005. Nosotros también tendremos una oportunidad única de conversar con algunas de las personas que dirigen el rumbo de las nuevas tecnologías
para desarrolladores para los próximos
años. Os lo contaremos.
Directrices de seguridad de
Microsoft para desarrolladores
Desde Microsoft e-learning,en español y gratuito,
acaba de publicarse este curso on line sobre
directrices de seguridad para desarrolladores.
Esta sesión on line le proporcionará
los conocimientos esenciales para la creación de aplicaciones seguras. Dividido
en: fundamentos de la seguridad de aplicaciones, recomendaciones para la escritura de código seguro, defensa contra
amenazas y implementación de seguridad
en las aplicaciones con Microsoft .NET
Framework.
Los objetivos son desde comprender
la necesidad de implementar la seguridad en cada fase del proceso de desarrollo, hasta las técnicas para definir modelos de amenazas, minimizar vulnerabilidades, limitar los daños causados por los
ataques, etc.
Más información en: https://www.microsoftelearning.com/spain/eLearning/offerDetail.asp
x?offerPriceId=51363
Microsoft IT Forum 2005
Entre el 15 y el 17 de noviembre se celebrará en
Barcelona el Microsoft IT Forum 2005,el evento
europeo para profesionales de las TI
Episodio IV de GUSE.NET
<< dotNetManía
El pasado viernes 22 de julio se celebró en Murcia, en la CROEM (Confederación
Regional de Organizaciones Empresariales), el Episodio IV del GUSE.NET (Grupo
de Usuarios del Sureste de España) de cuyos orígenes ya nos habló Miguel Egea,
uno de sus fundadores, el mes pasado.
8
Asistieron alrededor de 50 personas. La agenda final del evento fue:
• 16:30-18:20: T-SQL Show con Itzik
Ben-Gan de SolidQualityLearning.
• 18:30-19:20: De DTS a SSIS con
Juansa Díaz de la CAM.
• 19:20-20:00: Ofertas-Demandas de trabajo. Novedades.
• 20:00-20:30: Constitución fiscal y formal del grupo de usuarios como asociación. Elección de cargos y acta de
constitución.
En esta ocasión, el ponente estrella era
Itzik Ben-Gan, socio fundador y mentor principal de Solid Quality Learning quien pudo
venir gracias a la inestimable colaboración de
Microsoft Ibérica. Itzik es un gurú de T-SQL,
profesor y ponente habitual de conferencias
como las de las reuniones de PASS (Professional
Association for SQL Server), SQL Devcon o
SQL Server Connections. Es autor de varios
libros y artículos en revistas tan prestigiosoas
como SQL Server Magazine.
Además de las charlas técnicas y de los
aspectos formales de la constitución del grupo de usuarios como asociación, también nos
informaron sobre la inminente apertura de
una Web propia, gracias a la colaboración de
Microsoft Ibérica en http:/www.gusenet.com
donde podremos encontrar más información
a disposición de todos los miembros y del
público.
Las reuniones del GUSE.NET se celebran normalmente el último viernes de cada
mes alternativamente en Murcia o en Alicante.
Si vive o trabaja cerca le animamos a que asista y participe con ellos. Todos los eventos serán
publicados en http://www.microsoft.com/
spain/eventos y es recomendable inscribirse en
ellos antes de ir.
Este año tenemos la suerte de ser los
anfitriones (los españoles) de este evento, que se realiza ya por cuarta vez, y que
posiblemente sea el evento europeo más
importante para profesionales de las TI.
Tres días de aprendizaje a través de entre
300 y 400 sesiones que cubrirán aspectos
incluso de Windows Server R2, Windows
Vista y SQL Server 2005. Los tres pilares en los que se basarán son: formación
técnica, evaluación tecnológica y comunidad y networking.
La keynote inicial correrá a cargo de
Bog Muglia, Vicepresidente senior de la
división de Windows Server. Dentro de
los top speakers se encuentran: John
Craddock, Mark Russinovich y
Kimberly L. Tripp.
La cita de este año: en Barcelona. Puede
obtener más información de este evento en:
http://www.mseventseurope.com/msitforum/05/pre/content/new.aspx.
dnm.noticias
dnm.legal
Javier Aragonés Miranda
.NET y software libre
En este artículo se aclararán diversas cuestiones jurídicas sobre derechos y licencias que se puede plantear un programador en relación
con un proyecto para .NET y con el software libre.
<< Cada día es más frecuente oír en una misma frase las palabras
.NET y software libre, pero, ¿hasta que punto es o no
una contradicción? ¿Son incompatibles? ¿Puede hacerse software libre utilizando herramientas de desarrollo
de .NET? ¿Puede hacerse un proyecto de .NET utilizando herramientas de desarrollo de software libre? ¿Se
puede hacer un programa inicialmente en software libre
para .NET y cambiar la licencia posteriormente? ¿y al
revés? ¿Quién decide qué licencia se ha de usar?
A todas esas preguntas, y a otras, se dará respuesta en este artículo de manera breve y, esperemos, suficientemente clara, tras analizar, en primer lugar, qué
se entiende por .NET y por software libre.
¿Qué es .NET?
Puesto que los lectores de esta revista con toda
seguridad lo saben mejor que yo, para contestar a esta
pregunta me limitaré a citar la propia definición que
hace Microsoft® al respecto1:
“.NET es una plataforma de software que conecta información, sistemas, personas y dispositivos. Desarrollado con
base en los estándares de Servicios Web XML, .NET permite que los sistemas y aplicaciones, ya sea nuevos o existentes, conecten sus datos y transacciones independientemente del sistema operativo, tipo de computadora o dispositivo móvil que se utilice, o del lenguaje de programación
empleados para crearlo.”
Javier Aragonés Miranda
es abogado de Suárez
de la Dehesa Abogados,
despacho especializado en
Propiedad Intelectual e Industrial
y Nuevas Tecnologías.
http://www.suarezdeladehesa.com
Por tanto, se podría decir que un proyecto para
.NET es todo aquel que es compatible, gracias al uso
1 http://www.microsoft.com/latam/net/introduccion/quees.asp
2 https://www.fsf.org/licensing/essays/free-sw.html
de estándares, con los restantes proyectos .NET y que
posibilita, facilita y potencia la interacción entre todos
ellos independientemente del sistema, lenguaje, dispositivo o medio empleado, todos ellos en beneficio
del usuario.
¿Qué es software libre?
De acuerdo a la definición que da la Free Software
Foundation, se entiende por software libre todo aquel
que cumple con las cuatro libertades que ellos consideran imprescindibles2: (1) Libertad para ejecutar
el programa, con cualquier propósito, (2) libertad
para estudiar como funciona el programa, y adaptarlo a tus necesidades (el acceso al código fuente es
un requisito para ello), (3) libertad para redistribuir
copias de manera que puedas ayudar al vecino y (4)
libertad para mejorar el programa, y distribuir tus
mejoras al público, de tal manera que toda la comunidad se beneficia (el acceso al código fuente es un
requisito para ello).
En este punto conviene hacer dos aclaraciones. La
primera es que software libre no es lo mismo que software gratis, o como dice el famoso aforismo, “free software is not free beer”. Si bien la palabra libre implica
libertad en español, en ingles “free” puede significar
tanto libre como gratis, por lo que podría llevar a interpretaciones erróneas que hacen que la gente asocie
“libre” con “gratis”, cuando es perfectamente posible
cobrar por el software libre, tal como Red Hat ha venido haciendo con éxito hasta ahora.
<< dnm.legal
y/o el lenguaje en el que un programador crea un programa de ordenador
y, otra muy diferente, es el resultado
de esa creación, el contenido creado
con la herramienta en un lenguaje
determinado.
¿Son incompatibles?
Una vez definido qué es .NET y
qué es software libre, nada parece indicar que sean incompatibles. Es más, un
proyecto para .NET podría venir a
garantizar una nueva libertad al usuario: la libertad para acceder a sus datos
cuándo, cómo y desde donde él quiera
con la seguridad de que podrá hacerlo
pues será compatible. Por tanto, desde
el punto de vista de un usuario, un programa de software libre para .NET sería
la mejor opción posible, pues dispondría de la mayor libertad de uso que se
puede conseguir.
Ahora bien, para determinar si desde
el punto de vista de un programador o de
una empresa desarrolladora de software
esa opción resulta o no igual de beneficiosa son muchas las cuestiones que deberían analizarse, todas ellas perfectamente
válidas y posibles, que dependerán de la
estrategia empresarial que se elija, en la
que aquí no vamos a entrar.
Cuando un programador o una
empresa tiene en mente el proyecto que
quiere abordar, o el que le han encargado que desarrolle, surgen diversas opciones y cuestiones que han de ser concretadas, como cuál es la licencia que se quiere emplear (propietaria, libre, de código
abierto), quién será el titular, etc., por
ello se hace necesario explicar algunos
conceptos antes de entrar a hablar de las
licencias y cesiones de derechos.
Herramientas y creaciones
Lo primero que hay que dejar claro es que una cosa es la herramienta
Cada programador elije la
herramienta de desarrollo
que quiere emplear para crear un programa de ordenador. Dicha herramienta de desarrollo no es otra cosa que
un programa de ordenador creado por
otro programador X o por una empresa y, como tal, habrá que disponer de
una licencia de uso para emplearlo, pero
ello no significa que el titular de esa
herramienta de desarrollo, el programador X, tenga algún derecho sobre lo
que un programador cree utilizando ese
programa. Dicho de manera sencilla:
una cosa es el programa Word que estoy
empleando para escribir este artículo,
que es titularidad de Microsoft®, y otra
diferente es el artículo en sí, del cual yo
soy el único titular, y sobre el cual
Microsoft® no ostenta ningún derecho
pese a que yo lo he creado usando su
programa.
Lo mismo es predicable de un programa desarrollado para .NET por un
programador. Independientemente de
la herramienta (o programa) de desarrollo que emplee para su creación
(Visual Studio .NET, .NET Framework, ASP.NET, Mono, etc.) el programador será, en principio, el único
titular de su creación, sin que el creador de la herramienta empleada tenga
algún derecho sobre ello. La importancia de emplear uno u otro es la posibilidad de acceder a la creación. Yo he
creado este artículo con Microsoft®
Office Word 2003, con lo cual
sólo lo puedo abrir para editarlo con un programa
compatible, igual que sucede con el código fuente de
un programa, que sólo
puede editarse con un programa compatible con aquel
en el que se creó, de ahí la
importancia de elegir un programa o lenguaje determinado
sobre otros.
El resultado del trabajo de un programador es, en principio (ya lo veremos) de su exclusiva titularidad y puede hacer con él lo que le apetezca. Puede
regalarlo, borrarlo, venderlo, grabarlo
en un CD y guardarlo en un cajón, etc.
En fin, un programador es libre de
hacer, en principio, lo que quiera con el
programa que ha creado pues para eso
es su creación y, por tanto, puede licenciarlo como quiera o no licenciarlo en
absoluto.
La titularidad
Acabamos de ver que un programador es libre, en principio, de hacer lo
que quiera con el programa que ha creado. Y se dice “en principio” pues en la
legislación de propiedad intelectual existen unas presunciones según las cuáles
si un programador trabaja para una
empresa, será ésta la titular de los derechos sobre la creación del programador
e, incluso, puede llegar a ser considerada la propia empresa como autora del
mismo.
El artículo 97 de la Ley de
Propiedad Intelectual establece cuatro
clases de titularidad respecto de un programa de ordenador en función del proceso de creación:
1. Creación individual.- Cuando un
programador crea solo, por su cuenta, él es el único titular del programa que crea, y si crea para alguien,
debería existir un contrato entre
ambos que regule la cesión de los
derechos, si es que cede alguno. Un
<<dotNetManía
La segunda es que software libre no
es sinónimo de software de código abierto o software abierto (open source). Pese
a que se usan indistintamente en muchas
ocasiones, no son sinónimos. Si bien
todo el software libre es software abierto, pues el acceso al código fuente es
un requisito de dos de las cuatro
libertades, no todo el software
abierto cumple las cuatro libertades necesarias para ser considerado libre, ya que puede que
un programa de código abierto
sólo me permita adaptarlo pero
no distribuirlo.
11
<< dnm.legal
ejemplo de este tipo serían la mayoría de pequeños programitas freeware y shareware que pueden encontrarse por la red.
2. Creación colectiva.- Cuando un
programa se crea por varios programadores bajo la iniciativa y coordinación de una empresa o de una persona, a no ser que se pacte lo contrario, esta empresa o persona se
considerará autora del programa y,
en consecuencia, será la titular de
todos los derechos sobre el mismo.
El ejemplo sería cualquier corporación (Microsoft®, Adobe®, etc.,
etc.)
3. Creación colaborativa.- Cuando
un programa se crea por varios programadores que colaboran entre sí,
todos ellos será coautores del mismo y a todos ellos corresponderá su
titularidad en las proporciones que
establezcan. Como ejemplo estarían la mayoría de proyectos de software libre, o un programita creado
entre varios amigos.
4. Creación asalariada.- Cuando un
programador crea un programa
dentro de las funciones que desarrolla como asalariado de una
empresa, él seguirá siendo el autor
pero los derechos de explotación
pertenecerán en exclusiva a la
empresa. Ejemplos serían la mayoría de relaciones laborales de los
programadores.
<<dotNetManía
[
12
Software libre no
es lo mismo que
software gratis
]
Una vez que se determina a quién
corresponde la titularidad de un programa de ordenador, será a esa persona
o empresa a quien corresponda decidir
la licencia que se aplicará al programa,
pues la condición de titular es la que permite decidirlo.
(Por brevedad, en este artículo al
referirme a programador me refiero al
titular, a no ser que se entienda claramente lo contrario.)
Las licencias
Una licencia es el conjunto de
reglas que el programador establece
para que el resto de personas en general pueda interactuar con su programa.
El programador establece en la licencia lo que permite que el usuario de su
programa haga con el mismo (como,
por ejemplo, instalarlo en todos los
ordenadores de su casa) y también lo
que se le prohíbe hacer expresamente
(como hacer una copia y colgarla en su
blog a disposición de todo el mundo,
por ejemplo). Por ello, lo primero que
ha de decidir es qué es lo que quiere
permitir hacer a los usuarios y establecer una licencia, que puede redactarse
expresamente para ese programa, o
puede usarse una de las existentes si se
adapta a lo que se quiere.
A la vista de lo expuesto, se puede
afirmar que sí es posible realizar proyectos de software libre para .NET,
pues el programador puede utilizar para
su creación una licencia de software
libre (que otorgue al usuario las cuatro
libertades mencionadas al inicio) de
igual forma que puede hacer que el programa que cree sea de código abierto o
propietario.
Entra perfectamente en las facultades del programador decidir lo que los
usuarios hagan con su programa, independientemente de la herramienta de
desarrollo que emplee en su trabajo. Un
programador que utilice Mono™ (la
herramienta de software libre para desarrollo de proyectos .NET multiplataforma) puede licenciar el programa creado con la licencia que quiera, incluso
propietaria, de la misma manera que un
programador que utilice Visual Studio®
.NET puede convertir el programa creado en software libre aplicando la licencia adecuada para ello.
Cambio de licencia
Una cuestión que puede plantearse un
programador es si puede cambiar la licencia de un programa por otra diferente una
vez que ya se haya distribuido. La respuesta, como la mayoría que puede dar
un abogado, será “depende”.
Y la posibilidad de cambio depende
de la licencia o del contrato que ya haya
[
Un proyecto bajo .NET
puede perfectamente ser
software libre
]
otorgado respecto del programa. Para
que ello no sirva de excusa para evitar
la respuesta, expondré unos criterios que
pueden emplearse de manera general,
aunque luego haya que examinarse caso
por caso.
El criterio general que ha de emplearse es el de conservación y mantenimiento de los derechos cedidos. Si con
una licencia se ceden a los usuarios unos
derechos, que han estado disfrutando
pacíficamente, éstos mismos usuarios
no pueden verse perjudicados por la
decisión del programador de modificar
los términos de la licencia y, por tanto,
esos cambios operados no les afectarán
durante el periodo de vigencia de la
licencia que les ampara.
Una primera cuestión que hay que
examinar es si la licencia es en exclusiva o no. Aunque lo normal es que las
licencias de los programas son no exclusivas, es decir, se puede ceder el programa tantas veces como usuarios haya,
es posible que un programa desarrollado a medida para una empresa sí se ceda
en exclusiva, lo que significa que nadie
(incluido el propio programador en la
mayoría de las ocasiones) puede usar
ese programa sin permiso de la empresa. Ello conllevaría que el programa no
pueda cambiarse de licencia por el programador pues, aparte de que probablemente se lo prohíba el contrato, si
cambia de una licencia exclusiva a una
no exclusiva estaría perjudicando a la
empresa a la que cedió en exclusiva,
pues lo normal es que las licencias
exclusivas cuesten más dinero y sirvan
para que la competencia no use el mismo programa.
Lo que sí puede hacerse es cambiar
una licencia no exclusiva a una exclusiva, pero con ello no puede perjudicarse a aquellos usuarios que han venido
usando el programa porque la licencia
se lo permitía. En estos casos el programa caerá en desuso, pues a medida
<< dnm.legal
[
]
El programador es quien
decide qué licencia quiere
dar a su programa
Cuestión distinta es si con el cambio de licencia se limitan los derechos
del usuario. Como ya se ha mencionado, si se limitan los derechos ya concedidos, ese cambio no puede perjudicar a los usuarios amparados en la
licencia más amplia, pues mientras
dure el término de la misma se encuentran perfectamente amparados. Con
las actualizaciones y sucesivas versiones, que sí se regirán por la nueva
licencia más restrictiva, el problema se
minimiza, pues si un usuario quiere
beneficiarse de las mismas deberá
aceptar la nueva licencia, y ya sólo será
cuestión de tiempo que los usuarios
que dispongan de la vieja licencia vayan
desapareciendo. Por este motivo, lo
recomendable es aprovechar el lanzamiento de una nueva versión para realizar el cambio de licencia, incentivando así su adopción por parte de los
usuarios.
3
4
Pese a la sencillez del proceso
expuesto, la transición de licencia puede ser más complicada si se hace de software libre a propietario, pues si es software libre, lo normal es que la licencia
sea de duración indefinida, con lo que
los usuarios podrán redistribuir, adaptar y actualizar el programa. En estos
casos, el futuro del programa libre
depende (1) de que se cree una comunidad de desarrollo, pues si no se crea,
lo normal es que caiga en desuso, (2) del
precio y (3) de las novedades que se
introduzcan en el nuevo código, pues si
estos últimos son atractivos los usuarios
los preferirán.
Existen numerosos ejemplos de
cambios en las licencias. Un ejemplo de
paso de software libre a propietario sería
el programa denominado Yanoff (programa de lectura de noticias para Palm
OS) que cambió de ser software libre
bajo GPL (licencia más usada de software libre) a ser código cerrado. En el
sitio Web del programa se reconoce que
los usuarios anteriores podrán seguir
desarrollando el mismo en la versión de
2003, pero no en las posteriores.
En el sentido contrario, de software propietario a software libre, uno de
los ejemplos más notables se ha dado
con OpenOffice.org, la suite de ofimática que pasó de ser propietaria a tener
doble licencia, una comercial y una libre
(LGPL), y que actualmente se está pensando en pasarlo todo a GPL. Otro
ejemplo anunciado recientemente se ha
dado respecto del código fuente del juego Quake III, que la empresa desarrolladora del mismo piensa distribuir bajo
la licencia GPL.
Proyectos modelos
Todo lo dicho con anterioridad solamente es aplicable a los programas creados íntegramente por el programador,
ya que si el programador introduce código no original en el programa que desarrolla, ha de respetar la licencia bajo la
cual se ha distribuido dicho código. Esta
cuestión tiene especial relevancia en el
desarrollo bajo .NET, pues en las herramientas de desarrollo se suelen incluir
http://www.asp.net/samplessourcelicense/Default.aspx
http://www.dotnetnuke.com/Default.aspx?tabid=776
[
]
Los cambios de la licencia
no pueden perjudicar los
derechos de los
usuarios actuales
proyectos, módulos y rutinas modelo
que pueden ser empleadas por el programador. Dicho código modelo solamente podrá ser empleado si se respeta
la licencia del mismo, que puede, o no,
permitir su distribución como software
de código abierto.
Por ejemplo, en la licencia de
Microsoft® ASP.NET Source Projects3 se
establece que se puede utilizar el software modelo con finalidad comercial
pero expresamente establece que no
puedes combinarlo o distribuirlo con
software cuya licencia requiera que se
suministre el código fuente. Sin embargo, también hay ejemplos que sí permiten la modificación y distribución del
código fuente, como DotNetNuke, desarrollado con ASP.NET, cuya licencia4,
denominada X11 o MIT, es una licencia de software libre.
Por tanto, antes de emplear código
ajeno en un programa propio conviene
examinar la licencia del mismo para
determinar lo que se puede y no se puede hacer, pues de otra manera se corre
el riesgo de infringir los derechos de sus
titulares.
Conclusión
De todo lo expuesto se deduce que
un proyecto desarrollado para .NET
puede licenciarse de la manera que
mejor se adapte a la estrategia comercial del titular de los derechos del mismo, pues puede hacerlo como software de código abierto, propietario o
libre, sin que en ello influya la herramienta empleada en su desarrollo. Y
si la estrategia comercial cambia, con
ella también puede modificarse la
licencia, respetando el principio general de no perjudicar los derechos de los
usuarios actuales.
<<dotNetManía
que dejen de usarlo los usuarios que
estaban amparados por la licencia, ningún otro podrá usarlo salvo el que tenga la licencia exclusiva.
Un segundo grupo de cuestiones
que ha de analizarse es si con el cambio
de licencia se limitan o se amplían los
derechos ya concedidos. En el supuesto de que se amplíen los derechos o posibilidades de uso que proporciona una
licencia no exclusiva, es perfectamente
posible ese cambio, pues el usuario no
se ve perjudicado por ello, más bien todo
lo contrario, pues ahora tendrá más
facultades de las que podrá, o no, aprovecharse. Por ejemplo, si sólo se permite la instalación en un ordenador, y
se cambia la licencia para que puede instalarse en tres, se está beneficiando enormemente al usuario y no se le perjudica en nada.
13
dnm.directo.entrevistas
Marino Posadas
Entrevista a Alexander Vaschillo
Durante la celebración de los Academic Days 2005 en Lisboa, tuvimos ocasión de charlar con uno de los integrantes del equipo de desarrollo de SQL
Server y WinFS, quien nos aclaraba algunos aspectos poco conocidos de la
evolución de estas tecnologías.
<< ¿Tu trabajo es en investigación y desarrollo o solamente
Marino Posadas es
asesor técnico y
redactor de
dotNetManía, MVP de
C# y formador de
Alhambra-Eidos
en desarrollo?
En la actualidad estoy en desarrollo, exclusivamente. Trabajo en grupos de desarrollo, casi siempre vinculados a la gestión de bases de datos y tecnologías relacionadas con ellas, como los Object
Spaces anteriormente, o la tecnología vinculada a
WinFS, el futuro subsistema de almacenamiento de
Longhorn.
Hace unos meses tuvimos ocasión de hablar también con Andrew Conrad, del equipo de desarrollo
de Object Spaces. La reacción de los lectores que seguían el tema, fue de sorpresa, al saber que esa tecnología no estaría visible, sino embebida en el subsistema,
y no utilizable directamente, como un API…
Object Spaces ha sido una tecnología en evolución
y realmente, Microsoft no ha publicado en ningún
momento que tal tecnología fuese a estar disponible
“desde fuera”, como tú comentas. Tienes razón en el
sentido de que se pensó que podría accederse desde
fuera, pero desde un inicio, la tecnología estaba pensada para usarse de forma interna. WinFS, de hecho,
utiliza esta tecnología y también un lenguaje especial
de consultas, como mostraba yo antes en uno de los
ejemplos de mi conferencia.
Otra pregunta que está provocando ríos de tinta,
especialmente en la prensa especializada de los Estados
Unidos, es si, realmente, WinFS va a estar dentro de
Longhorn de alguna forma, –aunque no en su ámbito total de desarrollo– o es que no va a estar en absoluto, aunque pueda aparecer como una beta instalable. ¿Qué puedes decirnos al respecto?
Bueno, –y esto es una de las cosas de las que tengo miedo a pronunciarme– creo que lo cierto es que
no va salir como parte de Longhorn, ni en parte,
ni en su totalidad. Pienso que aparecerá un cierto
tiempo después, aunque no podría decir cuánto
tiempo. La buena noticia es que será capaz de funcionar en otros sistemas operativos, y no sólo en
Longhorn.
¿Quizá una parte de esta funcionalidad estará presente por defecto en Longhorn? Aunque sea una
pequeña parte…
No. No lo creo.
Pongamos la pregunta de otra forma. ¿Habrá en
Longhorn algún tipo de tecnología, –aunque no sea
WinFS– que mejore la experiencia de búsqueda de
información en el sistema, se llame como se llame?
Alexander Vaschillo
<< dnm.directo.entrevistas
Alexander Vaschillo y Marino Posadas
¿Y qué hay de las posibilidades de su
utilización como mecanismo de integración, tanto en aplicaciones como en
flujos de trabajo entre plataformas o
aplicaciones distintas, al estilo de lo que
hace BizTalk Server ahora?
Creo que lo cierto es que no va salir (WinFS) como parte
de Longhorn, ni en parte, ni en su totalidad. La buena
noticia es que será capaz de funcionar en otros sistemas
operativos, y no sólo en Longhorn
XML es un concepto para permitir la
integración y la transmisión de información independiente de su formato original o su destino final. Por tanto, no sólo
es cierto lo que propones, sino que se va
extender a otras herramientas como
SharePoint desde el punto de vista de la
integración. Además, esto resolverá problemas que los usuarios de las características de XML de la versión 2000 de SQL
Server habían mencionado a la hora de la
utilización de los esquemas de los datos
que se manejaban.
Por supuesto, el otro punto fuerte
de esta nueva versión es la integración
con el CLR. ¿Crees que esa característica será suficiente para una migración?
bién, en el caso de consultas realmente
complejas que podrían ser abordadas de
otra forma novedosa en esta forma.
Has comentado en tu charla, que un
procedimiento almacenado (desde esta
óptica), se puede convertir en un servicio
Web. Incluso que podremos convertir
procedimientos almacenados existentes
en servicios Web. Esto nos lleva a una pregunta natural asociada con esto. ¿Qué va
a suceder con las Extensiones de los Servicios
Web (WSE)?
En efecto, todo eso va a ser posible en
la próxima versión. Pero no puedo contestarte a esta pregunta en este momento. La tecnología de la que yo era responsable, tenía que ver con SQL/XML,
<<dotNetManía
Con toda seguridad existirán mejoras a ese respecto, pero tendrán más
que ver con tecnologías que, si bien
no están vinculadas a WinFS, permitirán un uso más rico de las posibilidades de búsqueda de información en
el sistema.
Bien, sigamos hablando de tecnologías vinculadas con SQL Server y el
almacenamiento. Una de las novedades más importantes en SQL Server
2005 es el tipo de datos XML ¿Podrá
ser utilizable incluso en arquitecturas
de almacenamiento Web, para guardar páginas de contenido (XML) y
páginas de presentación (XSL) de forma que se pueda tener –literalmente–
guardado un sitio Web en campos de
una base de datos?
Sin duda. Es más, nosotros pensamos que con el tiempo será el mejor
sitio posible para el almacenamiento
de información, pero sobre todo, por
que podremos hacer búsquedas dentro del propio contenido del campo.
Digamos, por ejemplo, que podremos
pedir a SQL Server que nos seleccione un conjunto elementos de cierto
nombre o que posean algún atributo
concreto, y estén incluidos dentro de
la estructura del fichero XML almacenado en un campo. O extender esa
búsqueda a todos los campos XML de
una tabla en busca de elementos relacionados por nombre, atributo o valor.
Ese creo que será uno de los usos más
importantes de esta tecnología.
¿O que será lo suficientemente comprendida como para motivar la migración a esta versión?
Para situaciones diferentes, respuestas diferentes. Somos conscientes que –a
la fecha de hoy– hay gente a la que esa
característica le trae sin cuidado. Existen
otros, sin embargo, que han estado esperando la oportunidad de almacenar objetos dentro de la base de datos, y esa oportunidad se la brinda ahora esta nueva versión. Dependerá de cada aplicación concreta si la tecnología se aplica inmediatamente o no.
¿Crees que el perfil típico del desarrollador típico de SQL Server se adecua a la incorporación inmediata de estas
novedades, o requerirá una fuerte curva de aprendizaje?
Yo no creo que sea un problema. La
aceptación de .NET es y seguirá siendo
creciente, y su conocimiento, también.
Cuando el desarrollador vea que hay formas de hacer cosas con menos esfuerzo y
más fiabilidad, irá adoptando la tecnología, como se ha hecho siempre. O tam-
15
<< dnm.directo.entrevistas
<<dotNetManía
La aceptación de .NET es y
seguirá siendo creciente, y
su conocimiento, también.
Cuando el desarrollador
vea que hay formas de
hacer cosas con menos
esfuerzo y más fiabilidad, irá
adoptando la tecnología,
como se ha hecho siempre
16
y la forma en que esto se ve desde el punto de vista externo. Veremos qué sucede
en los próximos meses…
Otro punto de confusión que me gustaría aclarar aquí es la posibilidad de
almacenar ficheros en un campo de la
base de datos. Cuando oí esto, al principio pensaba que se almacenaría un “puntero” por así decirlo, a la posición física
de ese fichero, junto a información relacionada con él. Pero tú has comentado
que se trata de un almacenamiento real
del fichero dentro de un campo de una
tabla de base de datos…
Su uso depende del contexto y del
propósito de uso que el fichero tenga.
Pongamos que hablamos del formato
JPG. Una de las necesidades que se plantean es hacerlo de forma que se puedan
incluir estos campos en consultas especiales capaces de devolver información
adecuada acerca de esos datos. El otro
punto a tener en cuenta, es que si utilizas un tipo de almacenamiento común
para ficheros que –originalmente– son
bien distintos, en la salida se debe de
tener una idea clara de cuál es ese formato, para poder utilizarlo.
No sé si esta va a ser la utilización óptima en la actualidad. Quizá lo sea en el
futuro y WinFS almacenará realmente
cualquier tipo de información para servirla en la forma adecuada a quien la solicite, pero en la actualidad, esa no es la idea,
o al menos, no en su sentido global. La
utilización ideal de esta tecnología será
cuando existan más tipos de datos adecuados a los distintos tipos de almacenamiento, pero quizá eso requiera de más
potencia de ordenador y sólo tenga sentido dentro de unos años, cuando esa
potencia esté disponible ampliamente.
A propósito de potencia de almacenamiento, James Gray decía que la
potencia vinculada al hardware tendrá un
gran impacto en cómo usamos el software, puesto que un disco duro de dentro de
10 años, será –en sí mismo– un ordenador como los actuales, con su CPU, su
memoria, etc. Entonces, el problema principal (como ya lo es hoy) será el del acceso. ¿Podríamos ver en un futuro a WinFS
presente en cada dispositivo de almacenamiento vinculado a un sistema que
soporte .NET Framework?
Es una idea interesante. Y, efectivamente, así son las cosas hoy día.
Probablemente, la línea de investigación
más importante, una vez solventados los
problemas de almacenamiento sea la del
acceso a esa información almacenada.
Tenemos que ver WinFS como una capa
por encima de cualquier tipo de almacenamiento. Un día estará presente incluso en los teléfonos móviles.
Siempre que hablo de bases de datos
tengo que referirme a las bases de datos
orientadas a objetos. ¿Las ves factibles,
entonces, con la tecnología actual?
WinFS es una capa por encima de la
tecnología de acceso a bases de datos.
Ahora conocemos bien los entresijos del
funcionamiento óptimo de una base de
datos relacional. El problema es conseguir que esos objetos se almacenen en un
motor relacional bien dimensionado y
optimizado, de la misma forma que ahora. De momento, esta tecnología nos puede ayudar a solventar el problema que
planteaba Jim Gray y que él mismo está
contribuyendo a resolver. Que el propio
mecanismo de acceso a la información se
vuelva más lógico, más apropiado para la
forma en la que los seres humanos necesitamos acceder a la información. De todas
formas, siempre va a existir algún tipo de
búsqueda de la información, pero la forma en que organicemos su almacenamiento y construyamos los mecanismos
para su acceso, serán vitales para el tiempo de respuesta adecuado.
Para concluir, una comparación respecto a la importancia tecnológica a largo plazo de los 3 subsistemas de
Longhorn: Avalon es la cosmética: muy
bonito, muy espectacular, pero su aportación se detiene ahí. Indigo es más importante, creo, porque son comunicaciones.
Pero WinFS es crítico, porque se trata de
cómo se comporta nuestra información,
cómo se almacena, y cómo se recupera.
¿Estoy en lo cierto?
Para mí, totalmente cierto. Incluso lo
que los otros dos subsistemas manejan (y
manejarán) seguirá siendo información
que se almacena, se lee, se transforma, se
transporta y se vuelve a almacenar. Esa
secuencia es, efectivamente, crítica en el
comportamiento de cualquier sistema
operativo, y lo va a ser todavía más en
Longhorn, y los sistemas venideros.
Muchas gracias por tu visión de
futuro y hasta la próxima.
Gracias a vosotros.
<< dnm.directo.eventos
Marino Posadas
Tech•Ed Europe 2005
<< El lector veterano de dotNetManía quizá recuerde que
Andrew Lees durante la “keynote” inicial (la maza asoma como amenaza)
Nos recibió Andrew Lees, con una keynote (o conferencia principal), en la que presentaba los dos productos como fruto de dos principios: la madurez en la
plataforma, debido a tratarse de un tercera versión, y
el “feedback” de los usuarios, inclusive durante el período de desarrollo. Presentó un nuevo SQL Server,
mucho más maduro en todos sus aspectos, con una plétora de nuevas y reforzadas opciones, nuevos servicios,
nuevas formas de construir la capa de datos en las aplicaciones y un sistema de réplicas y tolerancia a fallos,
que llegaba al momento culminante cuando, –maza en
mano– vuelve a aparecer en plena demostración de peti-
En la entrevista con Brian Keller,
Product Mannager de Visual Studio
ciones a servidores y destruye –literalmente– uno de
los equipos, que salta por los aires, mientras el otro servidor se hace cargo de las peticiones que le llegaban al
equipo destruido y permite seguir funcionando como
si nada: “Esto es tolerancia a fallos”, añadía, entre los
aplausos de toda la audiencia, encandilada por una demo
tan contundente y clara como efectista. En otra de las
demos, Brian Keller, Product Manager de Visual Studio,
(con quien tuvimos ocasión de hablar posteriormente), nos mostraba lo tremendamente sencillo que resulta crear aplicaciones Web o Windows con el nuevo
Visual Studio 2005, incluyendo, casi de fábrica, las capacidades de mantenimiento completo de una tabla de
una base de datos cualquiera, sin tener que escribir una
sola línea de código fuente. Una característica de productividad que agradecerá todo aquel que tenga que
abordar tareas rutinarias de mantenimiento. Y esto,
funcionaba exactamente igual para Windows que para
las aplicaciones Web.
Posteriormente, mediado el evento, tuvimos ocasión de asistir a una segunda keynote, realizada por
David Vaskevitch, quien nos aportada la sabiduría
acumulada al frente de la construcción de aplicaciones en Microsoft, para analizar la evolución del software, desde hace 10 años hasta ahora, y justificada en
esa evolución, extrapolar las tendencias y las promesas de los fabricantes, para acabar dibujando un perfil muy evolucionado en el que el software es cada
vez más inteligente, más próximo al usuario final, y
Microsoft, y las herramientas que allí se presentaban,
sus valedores tecnológicos, gracias a un proceso de
innovación continua, fruto de las elevadas inversiones en investigación, llevadas a cabo por Microsoft
<< dotNetManía
el año pasado, a la vuelta del evento de Ámsterdam,
titulábamos nuestra crónica como de un tiempo de espera. Bien, la espera ha concluido, y –si bien las anunciadas versiones de VS 2005 y SQL Server 2005 no
verán la luz hasta noviembre de este año–, las betas
con las que estamos trabajando y el material expuesto
en esta edición del Tech-Ed, muestran un grado de
madurez suficiente como para poder evaluar estas betas
con conocimiento de causa.
Llegamos a Ámsterdam con el convencimiento
de que la mayoría de los asistentes deseaba ver ya
características aplicadas de las versiones, demos con
espectáculo, trucos incipientes, y algunos de los mejores anticipos de lo que las versiones finales van a ofrecer. Y así fue.
17
<< dnm.directo.eventos
David Vaskevitch, durante su exposición en la segunda keynote
Research, y cuya tendencia parece seguir
en crecimiento.
Más profunda, y también más filosófica que la anterior, la charla de Vaskevitch,
venía a recordarnos que la evolución tecnológica es ya un fenómeno imparable y
la empresa que quiera mantenerse viva,
debe participar de esa corriente de renovación, adoptando las novedades en inicio, y ofreciendo a sus clientes las últimas
posibilidades tecnológicas con conocimiento del medio.
La organización de contenidos,
las ponencias y… los ponentes
<< dotNetManía
Al igual que el año pasado, las sesiones se dividían en varios bloques troncales, o tracks, tales como Seguridad,
Herramientas de Desarrollo, Gestión
Operativa, Inteligencia de negocio, etc, a
los que precedían un día de PreConferences, con una oferta de seminarios de gran calidad, y charlas con gurús,
como Steve Railey (en seguridad), Jeff
Prosise (a quien también entrevistamos)
o Kimberley Tripp (SQL Server),
quienes también nos regalaron algunas
de las mejores ponencias de este TechEd.
18
Durante la entrevista con Jeff Prosise… un sabio
Birds-of-a-feather: reuniones de café con equipos de desarrollo
Los más de 6.500 asistentes nos fuimos repartiendo por las sesiones en una
búsqueda entre la calidad de las ponencias en sí, y el interés personal en los
contenidos, que casi siempre concluía
con éxito. Citar aquí todo lo bueno que
se vivió en las salas es difícil, pero la personalidad de algunos ponentes era innegable: Juval Löwy, conciso y elegante
en su visión de las peculiaridades de la
nueva versión de Visual Studio, arrancó varias veces los aplausos de la audiencia, mostrándonos la nueva herramienta, y con una excelente visión popular,
enfatizando siempre aquellas partes más
productivas. Incluso superior fue el efecto en el público causado por el showman
Steve Railey, en sus charlas sobre seguridad. Metido entre el público, interrogando en directo, y haciendo que las respuestas in situ fueran la ocasión para
continuar de forma natural sus argumentos, abarrotó las sesiones en las que
participaba, dejando en la audiencia
siempre un mensaje entusiasta. También
fue muy celebrada la presentación de
Jeff Prosise, en el auditórium, con su
charla sobre seguridad en el código
fuente aplicada a la construcción de
sitios Web con ASP.NET. En el inter-
viú que nos concedió posteriormente y
que publicaremos en su momento, nos
confesaba su abandono de las labores de
autor de libros (su última obra fue
“Programming.NET Framework”),
para concentrarse exclusivamente en la
escritura de artículos (inaugura una nueva sección en MSDN Magazine a partir de este mes de septiembre), las conferencias por todo el mundo y la formación y consultoría.
Con Ari Bixhorn, Lead Product Manager de la estrategia
de servicios Web
Tampoco pudimos asistir a todas las
charlas que nos hubiera gustado por razones operativas y de tiempo, pero
me gustaría recordar con algunos adjetivos a los que destacaron por méritos propios: el
entusiasmo y calidad de Ari
Bixhorn (Lead Product Manager
de la estrategia de servicios
Web), cuando presentaba
Indigo, la cohesión y secuencia
lógica de la exposición de
Kimberley Tripp en sus varias
charlas sobre aspectos diversos
de SQL Server 2005, la visión
Juval Löwy en un momento de su ponencia
<< dnm.directo.eventos
simplificadora de Ingo Rammer, centrado en el rendimiento, escalabilidad y disponibilidad de los sistemas construidos
con .NET Framework, junto a otro de
nuestros entrevistados, Arvindra Sehmi,
un profundo conocedor de las arquitecturas de .NET y de SOA en particular.
Mark Russinowitch, al igual que ya hiciera el año pasado, volvió a recordarnos cuán
vulnerables son nuestros sistemas a ataques de todo tipo utilizando –a veces– los
más contundentes argumentos en forma
de demos, que ponían en evidencia
muchas prácticas habituales en la construcción de aplicaciones. Similares –por
su contundencia lógica– resultaron
muchas de las recomendaciones del veterano Gert Drappers, ya fuera al referirse a la afinación de servidores para obtención de rendimiento, o al analizar –y después comparar– las capacidades ofrecidas
por la integración del CLR en el motor
de SQL Server, respecto a las posibilidades añadidas al lenguaje T-SQL. Otros
viejos conocidos que estuvieron por allí y
captaron la atención mayoritaria, fueron
Rafal Luckawiecki, quien introdujo con
su carisma habitual algunas novedades de
la que será la versión 4 del marco de tra-
Rafal Luckawiecki
Con Sean O'Driscoll, Director del
Programa MVP en Redmond
términos de calidad de los seleccionados,
de propuestas de colaboración, y de reconocimiento empresarial del valor añadido que suponen sus miembros.
Los asistentes: el otro Tech-Ed
Microsoft se ha empeñado en una
campaña para unir los intereses comunes
de los desarrolladores a través de herramientas comunitarias. Podemos verlo
nada más que abrimos la beta 2 de Visual
Studio (con un nuevo elemento de menú
que nos pone en contacto con recursos de
comunidades), y pudimos comprobarlo
sobre el terreno, a través de las variadas
iniciativas que –en ese sentido– poblaban
todos los rincones del RAI. Por un lado,
unas reuniones informales de café (en un
café), con integrantes de distintos equipos
de desarrollo de los productos (Birds-ofa-feather), o las asesorías gratuitas ofrecidas por la iniciativa Ask-the-Experts, en las
que expertos de hasta 12 tipos de tecnologías distintas, respondían personalmente a las preguntas de usuarios interesados.
Por otro, reuniones de comunidades,
como la ofrecida en el MVP Community
Lounge, para los MVP asistentes, a la que
compareció, como el año anterior, el
Director Mundial del Programa MVP, Sean
O'Driscoll, quien estuvo haciendo balance, de la evolución del programa MVP en
Una vista general de los Hands-on-Labs
También estaban disponibles más
de 250 equipos para albergar los populares HOL (Hands-on-Labs), prácticas de laboratorio dirigidas y/o asistidas, donde podemos aprovechar la
oportunidad para introducirnos en una
tecnología de forma guiada. Las sesiones Chalk & Talk, aprovechaban los
tiempos de descanso, para dar respuesta
a preguntas de los asistentes en directo, que también podían participar –solicitando respuestas con anterioridad–,
en las Panel Discussions, que, moderadas por un experto en el tema de discusión, comentaban las respuestas a las
preguntas propuestas, en el marco
general de la sesión e incluso admitían
puntualizaciones en directo para soporte y apoyo de las soluciones propuestas. Parece que continúa –en general–
la tendencia a facilitar la participación
real de los asistentes en los contenidos
y realización de ciertos aspectos de
estos eventos.
<< dotNetManía
Mark Russinowitch, en su conferencia sobre virus
bajo para aplicaciones Microsoft, la MSF
4.0, el extrovertido Brian Goldfarb (a
quien el lector recordará que entrevistamos a su paso por Madrid), quien presentó
muchas de las novedades de ASP.NET
2.0, la polivalente Michelle Lerroux
Bustamante, interesada en servicios Web
y en migraciones desde Java, o Tony
Goodhew, que anticipaba algunas de las
que se convertirán –en breve– en buenas
prácticas para la construcción de interfaces de usuario que resulten fáciles de
migrar a Avalon, cuando la plataforma esté
disponible en su versión definitiva.
Y por cierto, no se habló demasiado
de Longhorn (quiero decir, del que ahora sabemos que se llamará Windows Vista)
en términos de producto, sino que se realizaron varias presentaciones vinculadas a
aspectos muy puntuales del sistema, como
nuevas características de seguridad, o las
dos API que se han popularizado a través
de versiones CTP (Avalon e Indigo) y que
sabemos que podrán instalarse en los equipos actuales. Esto, sin duda, resultará un
acicate para la migración al nuevo sistema, una vez que vayamos observando sus
posibilidades.
19
<< dnm.directo.eventos
La representación española y la
Universidad
Olvido Nicolás (TechNet), Carlos Oramas (Grupo
de Soporte), y Alberto Sánchez (relaciones con
Universidades), de Microsoft Ibérica, llevaron el peso de
la representación española, que, en el apartado universitario era bastante numerosa, con asistentes de muchas
facultades de informática españolas, (ver foto de grupo
adjunta), que encontraron tiempo, para hacer un poco
de todo, y continuaron el proceso de divulgación de la
tecnología .NET que comenzara ya hace varios años, y
se ha traducido en varias iniciativas en forma de asignaturas en la carrera de Informática, seminarios y masters
impartidos en facultades de toda nuestra geografía. Los
representantes de prensa, impecablemente atendidos por
Mónica García de la agencia Ketchum/SEIS, también
tuvimos oportunidad de disfrutar de la ciudad.
Dos de los representantes de eBay
mite la migración de aplicaciones .NET a la plataforma
J2EE, y que cuenta con el apoyo del promotor de la plataforma .NET para Linux, Miguel de Icaza). Tuvimos
ocasión de comentar por teléfono con Miguel desde
EE.UU., y con el director de MainSoft, Yacoov Cohen,
en Israel, que nos comentaron también la visión que tienen en Novell sobre los desarrollos para la plataforma
.NET, y las implicaciones que prevén con la aparición
de Windows Vista el próximo año.
Y la traca final…
El grupo de universitarios españoles, con Alberto Sánchez (primero de la
derecha, de rodillas)
<< dotNetManía
Los otros asistentes: los sponsors y fabricantes
20
En este apartado, pudimos apreciar un incremento
de la presencia de fabricantes de productos de terceros,
cuyas demos de producto, rozaban –a veces– el espectáculo, como cuando permitían que los usuarios se subieran a un Fórmula 1 conectado con un sistema de simulación por ordenador, y sintieran (con vibraciones incluidas), las sensaciones que se deben de sentir al conducir
una de esas máquinas (sin peligro, eso sí). Pudimos comprobar el buen estado de salud de los productos estrella
de Altova, Compuware, Oracle, HP, Borland, DevelopMentor, Sybari, Symantec, eBay, Infragistics,
ScriptLogic (que nos presentó su nueva su nueva solución de administración de sistemas), Citrix (con cuyo
representante en EMEA, Dave Austin, tuvimos ocasión de departir sobre la presentación de sus nuevos productos para la pequeña/mediana empresa) o MainSoft
(curiosamente, esta empresa está popularizando un software –cuya demo nos mostraron en directo– que per-
Como siempre, la traca final, con mucha gente, varios
ambientes, buena música y comida europea (a buen
entendedor…) puso el punto final de unas jornadas intensas, repletas de información, que sólo a la vuelta estamos
empezando a digerir, y que refrescaremos con el invaluable DVD post-Tech-Ed, que incluye las grabaciones
de todas las sesiones impartidas, y contribuye en buena
medida a la sensación de evento de aprendizaje, ya que
podemos analizar posteriormente cualquier sesión y
reproducir su código fuente, como refuerzo de las ideas, o para asistir –llanamente– a lo que no pudimos ver
por falta de tiempo.
Conclusión
Es difícil recoger en una única ubicación tanta actividad y tan gran número de expertos en tecnología, como
la que se ha aglutinado en Ámsterdam este año. Hemos
visto el futuro, con un nivel de aproximación a la realidad
final más que notable. Hemos podido departir con gentes de intereses similares y hemos disfrutado de las capacidades de albergue que la capital de Holanda ofrece. Una
ciudad que ha mostrado ya sobradamente su capacidad y
buena disposición para albergar eventos de este tipo. El
año próximo repetirá escenario (tercera edición consecutiva, como en Barcelona). Lo acogedor de la ciudad y su
buen clima para esta época del año, le hacen un huésped
idóneo para este tipo de eventos. Tech-Ed 2006 será sin
duda el anticipo de Windows Vista (a punto de aparecer,
y cuya presencia será sin duda la más destacada). Esperemos
que en un futuro el evento retorne a España, tras los 3
años de rigor que, tradicionalmente, no se prolongan en
una misma ciudad organizadora.
dnm.plataforma.net
Braulio Díez
Reyes García
Añadiendo nuestra aplicación
al área de notificación
Conseguir que nuestra aplicación apareciese en el área de notificación de
Windows (como hace Messenger o una herramienta antivirus) no era tarea
fácil con las herramientas de desarrollo antiguas. ¿Qué tal se porta .NET a la
hora de implementar esta funcionalidad?
<< Lo primero de todo, ¿qué es el área de notificación? El área
de notificación, en inglés llamado System Tray, es
una parte de la barra de tareas de Windows que nos
muestra los programas que tenemos corriendo en
segundo plano y permite acceder a ellos rápidamente
(ver figura 1).
Figura 1. Área de notificación
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.
Me gustaría que mi aplicación estuviera disponible en dicha área, ¿cómo puedo añadir un icono que
la represente?, ¿necesito convertirla a un servicio
Windows?… Conforme avanzamos en este tema nos
topamos con varios desafíos, en este artículo vamos
a intentar resolverlos. Los puntos a tener en cuenta
son los siguientes:
• Añadir nuestra aplicación al área de notificación.
• Distinguir entre cierre de ventana y cierre de
sesión del usuario.
• Arrancar nuestra aplicación al inicio de sesión
del usuario sin mostrar la ventana principal de
la misma.
• Evitar que haya más de una instancia de nuestra
aplicación ejecutándose a la vez.
Esto lo iremos desgranando punto por punto. En
www.dotnetmania.com se encuentra disponible una
aplicación de ejemplo, realizada en C#, que le ayudará a seguirlos. ¡Manos a la obra!
Añadir nuestra aplicación al área de notificación
Gracias a .NET Framework ésta es la parte más
sencilla de implementar. Los recursos que necesitamos son los siguientes:
• Crear un proyecto “Aplicación Windows”.
• Añadirle/crearle un icono que, por ejemplo, tendrá el nombre Notify.ico , y darle valor
“Embedded Resource” a la propiedad “Build
action”.
• Asignar un menú de contexto a la ventana asociada al icono de notificación; a éste lo llamaremos Notifymenu.
[ ]
Servicios Windows
Otra opción para implementar aplicaciones que corran en segundo plano es implementarlas como servicios Windows. Estos servicios están siempre corriendo aunque no haya
usuario activo, si necesitamos darle un interfaz de ventanas tendremos que combinar el
servicio con una aplicación estándar que podría
ser activada vía remoting.
.NET Framework incorpora soporte para
crear servicios, pero esto queda fuera del objetivo de este artículo.
<< dnm.plataforma.net
Normalmente las aplicaciones destinadas a ejecutarse en el área de
notificación lo hacen mientras el usuario tenga su sesión activa, así pues,
si intentamos cerrar la ventana principal lo que hace es minimizarse
Ya sólo nos queda añadir el código, declarar el
objeto de área de notificación e inicializarlo en el
constructor de la ventana donde lo vayamos a usar
(ver el fuente 1).
public class mainForm : System.Windows.Forms.Form
{
(…)
// Declaramos el objeto que manejara nuestra área de notificación.
private NotifyIcon m_notifyIcon;
(…)
// Le asignamos el icono que queremos mostrar
m_notifyIcon.Icon
= new Icon(GetType(),”Notify.ico”);
// Le asignamos el menú de contexto que hemos arrastrado a la ventana
// principal, los eventos
// del menú lo podemos enlazar con métodos directamente desde el editor
// de la ventana
// principal, como si de cualquier control se tratase.
m_notifyIcon.ContextMenu = NotifyMenu;
// También podemos enganchar eventos del Icono que se muestra
// por ejemplo si pulsamos
// doble click sobre él para que se muestre la ventana principal.
m_notifyIcon.DoubleClick += new
System.EventHandler(this.notifyIcon_DoubleClick);
}
// Doble click en nuestro icono del área de notificación: mostrar
// la ventana... (Podemos hacer lo mismo con otros eventos)
private void notifyIcon_DoubleClick(object sender, System.EventArgs e)
{
Show();
}
}
Fuente 1. Inicializando nuestro objeto de área de notificación
Tras compilar y ejecutar la aplicación tendrá
el aspecto que se ve en la figura 2. Sólo un pequeño detalle: cuando la cerramos, nuestro icono tar-
Figura 2. Nuestra aplicación de ejemplo e icono de
Notificación (Smily)
da en desaparecer, esto lo podemos remediar
sobrecargando el método Dispose de la ventana y
liberando explícitamente nuestro objeto (ver el
fuente 2).
// Liberar recursos que estén en uso.
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
// Hacemos un dispose de nuestro objeto de
//área de notificación.
this.m_notifyIcon.Dispose();
}
base.Dispose( disposing );
}
Fuente 2. Liberando recursos
<<dotNetManía
// Constructor de nuestra ventana principal.
public mainForm()
{
InitializeComponent();
// Inicializamos él objeto de área de notificación.
m_notifyIcon
= new NotifyIcon();
m_notifyIcon.Text
= “DNM - Botón Derecho muestra menú”;
m_notifyIcon.Visible
= true;
23
<< dnm.plataforma.net
Distinguir entre cierre de ventana y cierre de sesión del
usuario
Normalmente las aplicaciones destinadas a ejecutarse en el área de notificación lo hacen mientras el usuario
tenga su sesión activa, así pues, si
intentamos cerrar la ventana principal lo que hace es minimizarse. Para
poder cerrarla, o bien lo hacemos desde una opción del menú de contexto,
o bien cuando el usuario cierra su
sesión. En este último caso la aplicación lo detecta automáticamente y se
cierra sola.
Para poder distinguir entre cierre de
sesión o cierre normal de ventana, tenemos que usar funciones nativas de Win32
y capturar el mensaje WM_QUERYENDSESSION (SystemEvents.SessionEnding no
funciona cuando la ventana principal
de nuestra aplicación se encuentra
escondida). En el fuente 3 podemos
ver cómo distinguir cada evento de
cierre de aplicación.
Para poder distinguir entre
cierre de sesión o cierre
normal de ventana,
tenemos que usar
funciones nativas de Win32
y capturar el mensaje
WM_QUERYENDSESSION
// Distinguir entre el cierre con el botón aspa de la ventana (minimizar),
// o el cierre desde el menú de contexto o el cierre desde la sesión (cerrar
// aplicación)
private bool m_bRealClosing = false;
(…)
// Si recibimos el mensaje WM_QUERYENDSESSION el usuario está cerrando su sesión,
// cerrar la aplicación.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
// WM_QUERYENDSESSION
if (m.Msg == 0x11)
{
ReallyCloseApplication();
}
}
// Si elegimos en el menú de contexto “Cerrar aplicación”.
private void muClose_Click(object sender, System.EventArgs e)
{
ReallyCloseApplication();
}
// Si cerramos desde el botón aspa de la ventana, esconder la ventana, si no
// cerrar la aplicación.
private void mainForm_Closing(object sender, System.ComponentModel.CancelEventArgs
e)
{
if(!m_bRealClosing)
{
this.Hide();
e.Cancel = true;
}
}
// Cerrar “de verdad” la aplicación.
private void ReallyCloseApplication()
{
m_bRealClosing = true;
if(this.m_FormAlreadyLoaded)
{
Close();
}
else
{
// Hacemos un dispose de nuestro objeto de área de notificación.
this.m_notifyIcon.Dispose();
}
// Nos salimos de la aplicación (hay que tener en cuenta que la app no tiene
// asociada una ventana principal.
Application.Exit();
}
<<dotNetManía
Arrancar la aplicación cuando
se inicie la sesión y no mostrar
la ventana
24
Para que una aplicación arranque
cuando se inicie la sesión de usuario es
necesario añadir una entrada a las
siguientes direcciones del registro:
Fuente 3. Cerrando la aplicación
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
Windows\CurrentVersion\Run
HKEY_CURRENT_USER\SOFTWARE\Microsoft\
Windows\CurrentVersion\Run
Con la primera conseguimos que la
aplicación se ejecute para cualquier usuario que arranque la máquina, la segunda
es para el usuario que tenga activa la
sesión en ese momento. En dicha entra-
<< dnm.plataforma.net
da le indicaremos el nombre de nuestra aplicación y el
path completo donde podemos encontrarla. El fragmento de código que realiza esta función se puede encontrar en la aplicación de ejemplo (método NotifyHelper.
RunApplicationOnSessionStartup).
Otro punto a tener en cuenta es que la aplicación
se arranque automáticamente de forma “silenciosa”,
es decir, que muestre el icono de notificación pero no
la ventana principal, para ello modificamos el “main”
de la aplicación (ver el fuente 4).
[STAThread]
static void Main()
{
// La siguiente es la línea de código que hemos
// sustituido:
//
// Application.Run(new mainForm());
//
// Creamos el mainForm (el constructor muestra el
// icono en el área de notificación).
mainForm mainform = new mainForm();
// En vez de mostrar la ventana, directamente
// dejamos correr la aplicación.
Application.Run();
}
Fuente 4.Arrancar la aplicación en modo “silencioso”
Permitir sólo una instancia de nuestra
aplicación corriendo a la vez
Por último, no podemos olvidarnos de que la
mayoría de aplicaciones de este tipo no suelen permitir que haya más de una instancia de la misma
corriendo a la vez, esto lo controlamos usando el
objeto de sincronización del sistema operativo, un
mutex local con nombre. Cuando se arranca la aplicación intentamos apropiarnos de dicho mutex, si
ya hay una aplicación del mismo tipo corriendo, la
[STAThread]
static void Main()
{
// __UniqueMutexAppName es sólo un string que contiene
// un nombre único, e.g. “MiAplicacion_GUID”
if(!NotifyHelper.IsOtherInstanceOfTheAppAlreadyRunning(
GlobalConstantsValues.__UniqueMutexAppName))
{
mainForm mainform = new mainForm();
Application.Run();
}
}
Fuente 5. Comprobando que no hay otra instancia de la aplicación corriendo
static public bool IsOtherInstanceOfTheAppAlreadyRunning(
string uniqueName)
{
bool firstInstance;
// Si podemos reservar el mutex, no hay más instancias de
// la aplicación corriendo.
_SingleAppInstanceMutex = new Mutex(false, “Local\\” +
uniqueName, out firstInstance);
// No debemos liberar el mutex, cuando la aplicación se cierre,
// este será liberado automáticamente.
return !firstInstance;
}
Fuente 6. Comprobación con el Mutex
Para saber más
Si quiere ampliar información acerca de este tema, aquí tiene unos enlaces que le pueden ser de interés:
“Adding tray icons and context menus”
http://www.codeproject.com/csharp/trayiconmenu01.asp
“Making a Windows Forms app respond to System Shutdown”
http://www.stevex.org/dottext/articles/155.aspx
“Making a startup Window Form Invisible”
http://msdn.microsoft.com/library/default.asp?url=/library/enus/vbcon/html/vbtsksettingformtobeinvisibleatitsinception.asp
“Adding your application to the Windows Startup”
http://www.codeproject.com/system/windows_startup.asp
“More about single instance Mutex”
http://www.yoda.arachsys.com/csharp/faq/#one.application.instance
<<dotNetManía
...la mayoría de aplicaciones de este
tipo no suelen permitir que haya más
de una instancia de la misma
corriendo a la vez, esto lo
controlamos usando el objeto de
sincronización del sistema operativo,
un mutex local con nombre
apropiación fallará y cerraremos la aplicación (ver
el fuente 5 y 6).
25
dnm.plataforma.net
Carlos Quintero
El modelo de objetos de
Visual Studio .NET
Muchas de las tareas que realizamos a mano en Visual Studio .NET se pueden automatizar mediante macros y muchas otras se pueden mejorar o extender mediante
complementos.En este artículo veremos el modelo de objetos que proporciona Visual
Studio .NET para poder manejar el propio entorno de desarrollo desde código.
<< En el número 16 del mes de junio hablamos de la creación
de complementos (add-ins) para Visual Studio, centrándonos solamente en proporcionar la infraestructura de comandos, barras de herramientas,
menús y botones de nuestro complemento. En este
artículo profundizaremos en el modelo de objetos
que nos proporciona el entorno de desarrollo de
Visual Studio .NET 2002/2003 para su automatización. Este modelo de objetos reside en el ensamblado EnvDTE.dll, que nos proporciona el espacio
de nombres EnvDTE (podemos explorar este modelo mediante el examinador de objetos). La clase raíz
del modelo es DTE, que son las siglas de Development
Tools Environment y representa el entorno de desarrollo. Una instancia de dicha clase nos dará acceso a las ventanas, archivos, documentos, etc. de
Visual Studio .NET. La manera de obtener una instancia de dicha clase depende de cómo estemos
automatizando el entorno de desarrollo:
• Usando el editor de macros (menú “Herramientas”, “IDE de macros…”), existe una instancia implícita con el nombre DTE. Por ejemplo, la
siguiente macro muestra el nombre y la versión
del entorno de desarrollo:
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
Sub Macro1()
MessageBox.Show(DTE.Name & " " & DTE.Version)
End Sub
• Usando
un
complemento,
el
método
OnConnection recibe en el parámetro
Application dicha instancia. Como se recibe del
tipo Object , debemos convertirla al tipo
EnvDTE.DTE. La variable usada por el asistente de
complementos es applicationObject, por lo que
ésta es la instrucción que veremos siempre en
dicho método:
applicationObject = CType(application, EnvDTE.DTE)
• Usando un programa externo al propio Visual
Studio .NET, por ejemplo un archivo VBScript,
se puede crear una instancia de la clase DTE
mediante los ProgID “VisualStudio.DTE.7.1”
para Visual Studio .NET 2003 y
“VisualStudio.DTE.7” para Visual Studio .NET
2002, o bien “VisualStudio.DTE” para usar la
versión más alta de las que haya instaladas. Aquí
se muestra un script en lenguaje VBScript que
abre una instancia de Visual Studio .NET, la
hace visible, muestra su nombre y versión y la
cierra:
Dim objDTE
Set objDTE = CreateObject("VisualStudio.DTE")
objDTE.MainWindow.Visible = True
MsgBox objDTE.Name & " " & objDTE.Version
objDTE.Quit
Con cualquiera de estos métodos tendremos una
instancia de la clase DTE y ya podremos empezar a
“jugar” con ella. En los siguientes apartados veremos
cómo manejar por código las soluciones, proyectos,
archivos y ventanas del entorno de desarrollo, cómo
editar el texto de nuestros documentos de código y
cómo obtener información sobre sus elementos de
código (clases, procedimientos, parámetros, etc.) ¡sin
tener que “parsear” el documento!
<< dnm.plataforma.net
Como sabemos, una solución es un
conjunto de proyectos relacionados y éstos
a su vez se componen de referencias y
archivos. Para manejar una solución disponemos de la clase EnvDTE.Solution, que
se obtiene a partir del objeto DTE mediante su propiedad Solution. Para manejar los
proyectos disponemos de la case
EnvDTE.Project, y podemos obtener los
proyectos de una solución mediante la
colección Solution.Projects. Para manejar los archivos disponemos de la clase
EnvDTE.ProjectItem y los archivos de un
proyecto se obtienen mediante la colección Project.ProjectItems. En este punto hay que indicar que un ProjectItem no
siempre es un archivo, también puede ser
una carpeta y que un archivo puede tener
a su vez otros archivos relacionados. Por
ejemplo, las páginas ASPX tienen archivos de código por detrás, y los archivos de
formularios tienen archivos .RESX relacionados. Para tratar ambos casos, la clase EnvDTE.ProjectItem proporciona una
colección ProjectItem.ProjectItems, la
cual tiene a su vez una propiedad
ProjectItems.Parent para poder realizar
la navegación por la jerarquía en orden
ascendente. Finalmente, cualquier
ProjectItem tiene una propiedad
ProjectItem.ContainingProject para
poder saber cuál es su proyecto padre. Con
todo esto podemos obtener la jerarquía de
proyectos y archivos de nuestra solución,
y obtener las propiedades de cada elemento, como veremos más adelante. Pero
antes veamos cómo obtener información
sobre las referencias de un proyecto.
Si examinamos la clase EnvDTE.Project
veremos que no hay ninguna colección
para obtener las referencias de un proyecto. Esto es así porque no todos los tipos de
proyecto usan referencias (por ejemplo,
los proyectos de instalación). Para proporcionar acceso a propiedades y métodos
específicos de un tipo de proyecto existe
la propiedad Project.Object, que devuelve un tipo System.Object que ha de ser convertido a un tipo específico del tipo de proyecto. En el caso de C# y VB.NET, este
tipo es VSLangProj.VSProject, que está
definido en el ensamblado VSLangProj.dll,
separado del ensamblado EnvDTE.dll y que
por tanto habrá que añadir separadamen-
Sub MacroInformacionSolucion()
Dim objProject As EnvDTE.Project
Dim objVSProject As VSLangProj.VSProject
Dim objReference As VSLangProj.Reference
Try
If DTE.Solution.IsOpen() Then
' Muestra las propiedades de la solución
Debug.WriteLine("Nombre completo de la solución: " & DTE.Solution.FullName)
MostrarPropiedades(DTE.Solution.Properties)
' Muestra los proyectos
For Each objProject In DTE.Solution.Projects
Debug.WriteLine("Nombre completo del proyecto: " & objProject.FullName)
Debug.WriteLine("Nombre del proyecto: " & objProject.Name)
Debug.WriteLine("Nombre único del proyecto: " & objProject.UniqueName)
MostrarPropiedades(objProject.Properties)
MostrarProjectItems(objProject.ProjectItems)
If TypeOf objProject.Object Is VSLangProj.VSProject Then
objVSProject = DirectCast(objProject.Object, VSLangProj.VSProject)
For Each objReference In objVSProject.References()
Debug.WriteLine("Referencia " & objReference.Identity)
Next
End If
Next
End If
Catch objException As Exception
MessageBox.Show(objException.ToString)
End Try
End Sub
Sub MostrarPropiedades(ByVal colProperties As EnvDTE.Properties)
Dim objProperty As EnvDTE.Property
Dim objValue As Object
For Each objProperty In colProperties
Try
objValue = objProperty.Value
Catch
objValue = Nothing
End Try
If objValue Is Nothing Then
Debug.WriteLine(objProperty.Name & ": <vacío>")
Else
Debug.WriteLine(objProperty.Name & ": " & objValue.ToString)
End If
Next
End Sub
Sub MostrarProjectItems(ByVal colProjectItems As EnvDTE.ProjectItems)
Dim objProjectItem As ProjectItem
For Each objProjectItem In colProjectItems
MostrarPropiedades(objProjectItem.Properties)
' Entra en recursión
MostrarProjectItems(objProjectItem.ProjectItems)
Next
End Sub
Fuente 1
<<dotNetManía
Soluciones, proyectos y archivos
27
<< dnm.plataforma.net
<<dotNetManía
También podemos crear soluciones
mediante automatización,añadir proyectos a una solución y añadir archivos o
referencias a un proyecto
28
te. Una vez que hemos convertido Project.Object a
VSLangProj.VSProject, esta clase sí contiene una colección VSProject.References para obtener las referencias
de un proyecto.
La macro del fuente 1 hace uso de todo lo explicado y obtiene información de la solución y sus proyectos, archivos y referencias.
Conviene indicar que algunas de las propiedades de
los objetos del modelo de extensibilidad son de tipo
String y no un valor enumerado como cabría esperar.
Esto es así porque siendo Visual Studio .NET tan extensible que permite albergar nuevos lenguajes de programación o nuevos tipos de proyecto, no se pueden acotar los valores que puede tomar una propiedad. Muchos
de los valores conocidos de dichas constantes están disponibles en la clase EnvDTE.Constants o en clases del
ensamblado VSLangProj (para proyectos VB.NET y C#)
como las clases VSLangProj.PrjKind (para saber el lenguaje de un proyecto), VSLangProj.prjOutputType (para
saber el tipo de proyecto), etc.
También podemos crear soluciones mediante automatización, añadir proyectos a una solución y añadir
archivos o referencias a un proyecto. Esto es muy útil
si deseamos construir una especie de asistente que cree
el esqueleto de una aplicación conforme a los estándares de proyectos de nuestra empresa. Las soluciones se
pueden crear mediante el método Solution.Create, se
pueden guardar mediante el método Solution.SaveAs
y se pueden volver a abrir mediante el método
Solution.Open. Para añadir proyectos a una solución
podemos usar o bien el método Solution.AddFromFile
(para añadir proyectos que ya están creados) o bien el
método Solution.AddFromTemplate (para añadir proyectos nuevos). Para añadir archivos y carpetas a un proyecto tenemos a nuestra disposición varios métodos
como ProjectItems.AddFolder (para crear carpetas nuevas), ProjectItems.AddFromDirectory (para añadir todos
los archivos que se encuentren en una carpeta),
ProjectItems.AddFromFile (para añadir un archivo existente que se deja en su carpeta y se referencia desde ahí),
ProjectItems.AddFromFileCopy (para añadir un archivo
existente que se copia a la carpeta de destino antes de
ser añadido) y ProjectItems.AddFromTemplate (para añadir archivos nuevos).
Para añadir referencias a un proyecto tenemos que
hacerlo a través de la colección VSLangProj.References
que vimos anteriormente. Esta colección proporciona
los métodos References.Add (para añadir una referencia a un ensamblado .NET), References.AddActiveX
(para añadir una referencia a un componente COM) y
References.AddProject (para añadir una referencia a
otro proyecto de nuestra solución).
Ventanas
Para manejar ventanas el modelo de extensibilidad
nos proporciona la clase EnvDTE.Window. Básicamente
Visual Studio .NET proporciona 3 tipos de ventanas:
• La ventana principal del IDE, que se obtiene
mediante la propiedad DTE.MainWindow.
• Las ventanas de documentos.
• Las ventanas de herramientas (ToolWindows), como
el explorador de soluciones, la lista de tareas, la
ventana de propiedades, etc.
La propiedad DTE.ActiveWindow devuelve la ventana activa del IDE. Se puede acceder a todas las ventanas mediante la colección DTE.Windows, que podemos iterar en busca de una ventana en particular. Para
ventanas de herramientas es más óptimo buscar con
índices únicos proporcionados por las constantes de
EnvDTE.Constants.vsWindowKindXXX. Muchas de las
ventanas del IDE proporcionan un modelo de objetos que permite manipular su contenido. Para ello,
las ventanas proporcionan una propiedad
Window.Object que puede ser convertida al tipo adecuado de dicha ventana. Por ejemplo, la macro del
fuente 2 obtiene la ventana de la lista de tareas y muestra las tareas de la lista.
Sub ObtieneListaTareas()
Dim objWindow As EnvDTE.Window
Dim objTaskList As EnvDTE.TaskList
Dim objTaskItem As EnvDTE.TaskItem
objWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindTaskList)
objTaskList = DirectCast(objWindow.Object, EnvDTE.TaskList)
For Each objTaskItem In objTaskList.TaskItems
Debug.WriteLine(objTaskItem.Description)
Next
End Sub
Fuente 2
Las propiedades como Window.Object devuelven
un objeto del tipo _ComObject, así que ¿cómo se
puede saber el tipo del espacio de nombres EnvDTE
al que tenemos que convertirlas? La respuesta viene de la mano de una función poco conocida:
<< dnm.plataforma.net
El modelo de código de Visual Studio
.NET permite descubrir los elementos
de nuestros archivos de código
mos abrir (EnvDTE.Constants.vsViewKindDesigner,
EnvDTE.Constants.vsViewKindCode, etc). Dicho método
devuelve un objeto DTE.Window, cuyo documento podemos obtener con la propiedad Window.Document. Se pueden guardar los cambios de un documento con el método Document.Save y se puede cerrar un documento con
el método Document.Close, que nos permite indicar en
un parámetro si hay que guardar los cambios o no.
Edición de texto
Para los documentos que son de texto, la llamada
devuelto “TaskList”. Otros tipos comunes que
encontraremos en la propiedad Window.Object son:
• EnvDTE.UIHierarchy. Permite navegar la jerarquía
del explorador de soluciones, del explorador de
servidores y del explorador de macros, aunque no
de la vista de clases).
• EnvDTE.ToolBox. Para la ventana de la caja de herramientas)
• System.ComponentModel.Design.IDesignerHost.
Para diseñadores de formularios.
• EnvDTE.TextWindow. Para ventanas de texto.
• EnvDTE.HTMLWindow. Para diseñadores HTML.
Con esas clases podremos descubrir y manipular
el contenido de sus respectivas ventanas.
Documentos
Como hemos visto hasta ahora, un ProjectItem es
un archivo en disco, y una ventana es un elemento de
la interfaz de usuario que, en el caso de archivos, nos
permite editar su contenido. Entre ambos existe una
entidad intermedia que es el documento. El documento proporciona un buffer editable que se mantiene en
memoria hasta que se cierra, permitiendo guardar los
cambios en disco en cualquier momento. Para manejar documentos tenemos las clases EnvDTE.Document (para
documentos en general) y EnvDTE.TextDocument (para
documentos de texto). El IDE nos proporciona la lista de documentos en la colección DTE.Documents, y el
documento activo en la propiedad DTE.ActiveDocument.
La relación de un documento con su ProjectItem es de
uno a uno (propiedad Document.ProjectItem), pero un
documento puede estar abierto en varias ventanas, por
ejemplo, el documento Form1.vb puede tener abierta
una ventana de código y una ventana con el diseñador
de formularios. La propiedad Document.Windows nos
devuelve las ventanas de un documento y la propiedad
Document.ActiveWindow nos devuelve la ventana activa
del documento. Para abrir un documento a partir de
un ProjectItem se usa el método ProjectItem.Open, que
recibe como parámetro el tipo de ventana que quere-
dos más importantes de esta clase están relacionados con
los objetos EnvDTE.TextPoint, EnvDTE.EditPoint y
EnvDTE.TextSelection. Los dos primeros representan
posiciones en el documento de texto, con propiedades
como TextPoint.Line para obtener el número de línea y
TextPoint.LineCharOffset para obtener la columna. La
diferencia entre ambos es que el TextPoint no es editable, mientras que el EditPoint sí lo es. Se puede obtener
un EditPoint a partir de un TextPoint mediante el método TextPoint.CreateEditPoint. La macro del fuente 3
muestra cómo insertar un texto en la cabecera del documento de texto activo.
Sub InsertarEncabezado()
Dim objTextDocument As EnvDTE.TextDocument
Dim sTexto As String
If Not (DTE.ActiveDocument Is Nothing) Then
Try
objTextDocument = DTE.ActiveDocument.Object("TextDocument")
Catch
End Try
If Not (objTextDocument Is Nothing) Then
objTextDocument.StartPoint.CreateEditPoint.Insert("' Archivo " &_
DTE.ActiveDocument.Name & Microsoft.VisualBasic.ControlChars.CrLf)
End If
End If
End Sub
Fuente 3
El explorador de macros contiene un proyecto
de ejemplo con multitud de macros que nos servirán para conocer todo lo relativo a la edición de
código fuente.
El modelo de código
El modelo de código de Visual Studio .NET permite descubrir los elementos (clases, propiedades, procedimientos, parámetros, atributos, etc.) de nuestros archi-
<<dotNetManía
Microsoft.VisualBasic.Information.TypeName(objeto). Para el caso de la macro anterior, nos habría
Document.Object("") o Document.Object("TextDocument")
nos devuelve un objeto EnvDTE.TextDocument. Los méto-
29
<< dnm.plataforma.net
vos de código. La clase central para este
cometido es EnvDTE.CodeElement, cuya
propiedad CodeElement.Kind nos devuelve el tipo de elemento. A su vez, un objeto de la clase EnvDTE.CodeElement se puede convertir a un tipo específico acorde
con su tipo que proporciona funciones y
métodos que son sólo aplicables a ese tipo
de elemento de código (por ejemplo,
EnvDTE.CodeNamespace, EnvDTE.CodeClass,
etc). En C++ existen muchos tipos de elementos (y de hecho C++ usa un modelo
de código distinto), pero en VB.NET y
C# los elementos de código que tenemos
se muestran en la tabla 1.
Hay que señalar que existe una clase
EnvDTE.CodeType para manejar de forma
unificada los elementos de código que son
tipos (clases, estructuras, interfaces, delegados y enums).
Para navegar por los elementos de
código de un archivo usaremos la propiedad ProjectItem.FileCodeModel, y para un
proyecto usaremos Project.CodeModel. En
ambos casos el objeto devuelto tiene una
propiedad CodeElements que nos devuelve la colección de elementos raíz. Para
obtener los elementos de código hijos de
Elemento de código
Propiedad Kind
Sub MostrarElementosDeCodigo()
Dim objProjectItem As ProjectItem
If Not (DTE.ActiveDocument Is Nothing) Then
objProjectItem = DTE.ActiveDocument.ProjectItem
If Not (objProjectItem.FileCodeModel Is Nothing) Then
MostrarElementosDeCodigoRecursivo(objProjectItem.FileCodeModel.CodeElements, 0)
End If
End If
End Sub
Sub MostrarElementosDeCodigoRecursivo(ByVal colCodeElements As CodeElements, _
ByVal iNivel As Integer)
Dim objCodeElement As EnvDTE.CodeElement
Dim colMembers As EnvDTE.CodeElements
For Each objCodeElement In colCodeElements
Debug.WriteLine(New String(" "c, iNivel * 3) & objCodeElement.Name)
colMembers = ObtenerHijos(objCodeElement)
If Not (colMembers Is Nothing) Then
MostrarElementosDeCodigoRecursivo(colMembers, iNivel + 1)
End If
Next
End Sub
Private Function ObtenerHijos(ByVal objCodeElement As CodeElement) As CodeElements
Dim colCodeElements As CodeElements
If TypeOf objCodeElement Is CodeNamespace Then
colCodeElements = DirectCast(objCodeElement, CodeNamespace).Members
ElseIf TypeOf objCodeElement Is CodeType Then
colCodeElements = DirectCast(objCodeElement, CodeType).Members
End If
Return colCodeElements
End Function
Fuente 4
Tipo propio
Espacio de nombres
vsCMElementNamespace EnvDTE.CodeNamespace
Clase
vsCMElementClass
EnvDTE.CodeClass
Estructura
vsCMElementStruct
EnvDTE.CodeStruct
Enum
vsCMElementEnum
EnvDTE.CodeEnum
Interface
vsCMElementInterface EnvDTE.CodeInterface
Delegado
vsCMElementDelegate
EnvDTE.CodeDelegate
Propiedad
vsCMElementProperty
EnvDTE.CodeProperty
Procedimiento
vsCMElementFunction
EnvDTE.CodeFunction
Variable
vsCMElementVariable
EnvDTE.CodeVariable
ría. Para ello, diversas clases disponen
de métodos que
comienzan
con
“Add”. Por ejemplo,
tenemos FileCode
Model.AddNamespace,
FileCodeModel.Add
Class, CodeClass.Add
Function, CodeFunc
tion.AddParameter,
<<dotNetManía
etc. La mala noticia
es que muchos de
Parámetro
vsCMElementParameter EnvDTE.CodeParameter
estos métodos no
Atributo
vsCMElementAttribute EnvDTE.CodeAttribute
están implementados para todos los
Tabla 1
lenguajes, de manera que es posible que
un CodeElement es necesario usar el tipo
un método funcione con C# pero no con
propio de cada elemento de código:
VB.NET o viceversa. En cualquier caso
CodeNamespace.Members, CodeClass.Mem
siempre podemos construir por nosotros
bers, etc. (curiosamente la propiedad
mismos el párrafo de texto con el elemento
CodeElement.Children que intuitivamende código que queremos agregar y usar la
te sería la que emplearíamos no funciofunción EditPoint.Insert como se explinaría, ya que sólo vale para C++). La macro
có en un apartado anterior.
del fuente 4 recorre los elementos de códiY con esto terminamos este artígo del documento de código activo.
culo. Naturalmente se han quedado
El modelo de código también permialgunas cosas en el tintero, porque la
te generar código fuente, al menos en teoextensibilidad de Visual Studio .NET
30
da para escribir libros enteros (o al
menos unos cuantos capítulos), pero
se han tratado los aspectos fundamentales. En un par de meses estará
disponible Visual Studio 2005, que
promete mejorar e introducir novedades en el modelo de extensibilidad
para hacernos la vida más fácil.
Documentación
La documentación de referencia
imprescindible para entender el modelo de extensibilidad de Visual Studio
.NET es la siguiente:
[1] Manipulating the Development
Environment: http://msdn.microsoft.com
/library/default.asp?url=/library/enus/vsintro7/html/vxoriManipulatingDev
elopmentEnvironment.asp
[2] Automation and Extensibility
Reference: http://msdn.microsoft.com/
library/default.asp?url=/library/en-us/
vsintro7/html/vxoriExtensibilityRefere
nce.asp
[3] Libro “Inside Microsoft Visual Studio
.NET 2003”, de Craig Skibo y otros:
http://www.microsoft.com/mspress/books/
6425.asp
dnm.inicio.fundamentos
dnm.incio.taller
Guillermo “Guille” Som
Interfaces
En el artículo sobre las interfaces de dnm.inicio.fundamentos publicado en el nº 16 de
dotNetManía,explicamos lo que son las interfaces y vimos algunos ejemplos de cómo
usarlas.En esta ocasión veremos más ejemplos,con idea de que nos quede claro cómo
utilizar las interfaces en nuestros proyectos, aunque en esta ocasión vamos a usar las
interfaces de una forma diferente a lo “habitual”, con la intención de que nos hagamos
una idea de lo útiles que pueden llegar a ser estos tipos de datos.
<< Usar las interfaces como parámetro de métodos
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
Las interfaces no las vamos a utilizar siempre desde la perspectiva de ofrecer funcionalidades “compatibles” con las clases de .NET Framework, ni con
otras de nuestra propia cosecha, al menos desde el
punto de vista de que al implementar alguna interfaz, nuestra clase tenga la “funcionalidad” aportada
por dicha interfaz.
Por ejemplo, si necesitamos pasar parámetros a distintos métodos, pero no sólo nos interesa indicar el contenido de unas cadenas o unos valores numéricos, sino
que también queremos pasar algo de “acción”, es decir,
algún método que actúe sobre esos parámetros o sobre
los valores que internamente el método tenga que usar...,
en estos casos también nos puede interesar utilizar las
interfaces, ya que éstas nos proporcionan una forma de
utilizar objetos anónimos (o previamente indefinidos),
los cuales dejarán el anonimato en el momento que nuestro código ejecute dicho método.
Aclaremos un poco todo esto para que nos entendamos mejor:
Si tenemos un método declarado de esta forma:
Para VB: Metodo(parámetro As Interfaz)
Para C#: Metodo(Interfaz parámetro)
Es obvio que parámetro es del tipo de una interfaz,
por tanto, el argumento real que pasaremos a este método será de un objeto que implemente la interfaz indicada en el tipo del parámetro. Esa interfaz tendrá cierta
funcionalidad y posiblemente algunas propiedades. Todo
eso lo podemos usar en ese método sin importarnos qué
objeto es el que utilizamos a la hora de llamarlo, o para
decirlo de otra forma: sin importarnos de qué tipo es el
objeto pasado como argumento.
Si usamos las interfaces de esta forma, realmente
los tipos que la implementen no lo harán para tener
la funcionalidad de la interfaz, (aunque también), sino
porque así podrán usarse en otros contextos. En el
fondo es lo mismo, aunque al usarlas de este modo
ampliamos la forma de aprovecharnos de las interfaces y de la filosofía de las mismas: proporcionar funcionalidad anónima y proveer de polimorfismo a nuestras clases y estructuras.
Dos ejemplos de interfaces como parámetros
A continuación veremos un par de ejemplos en
los que utilizaremos esta otra forma de darle utilidad
a las interfaces. El primer ejemplo ya lo vimos en el
nº 7 de dotNetManía (pág. 24), en el que usábamos
una clase específica para clasificar tipos que no estaban “preparados” para ser clasificados, (no vamos a
entrar en detalles sobre cómo hacer una clase que
pueda ser clasificada, ya que de eso nos ocupamos en
el citado número de dotNetManía.)
El caso era que teníamos una clase “normal” que no
estaba preparada para ser clasificada por el propio .NET,
es decir, no implementaba la interfaz IComparable. Pero
queríamos clasificar el contenido de una colección que
contenía objetos de ese tipo no clasificable. La solución
fue usar una de las sobrecargas del método Sort, al que
se le pasa como argumento una clase que implemente
una interfaz (IComparer). La clase pasada como argumento tiene que implementar dicha interfaz, y se encargará de clasificar (o comparar) dos elementos de un tipo
determinado.
<< dnm.inicio.taller
a basar en una interfaz que podemos
implementar en nuestros formularios. La
razón de hacer esto es porque algunas
veces nos podemos encontrar con la situación de que queremos dar cierta funcionalidad a nuestros formularios, pero puede que esa nueva funcionalidad sea diferente en cada uno de ellos.
Una de las formas de proporcionar ese nuevo funcionamiento es crear una clase basada
en la clase Windows.Forms.Form,
(que es la clase base de cualquier
formulario de .NET), y añadirle la nueva funcionalidad con elementos (miembros) virtuales
(reemplazables). Después, sólo
tendríamos que crear nuevos formularios basados en esa clase y
así dispondríamos de todas las
nuevas características añadidas
en nuestra clase base.
Pero es posible que la implementación (el código a usar) de
esa nueva funcionalidad sea diferente dependiendo de lo que queramos
que nuestro formulario haga, por tanto,
no tiene mucho sentido escribir un código que después lo vamos a reemplazar en
la mayoría de las veces que usemos esa clase. En este tipo de situaciones es donde
nos podemos beneficiar del uso de las
interfaces, ya que una interfaz no tiene
código ejecutable, solamente define los
miembros que tenemos que implemen-
[ ]
NOTA
Como ya sabemos las clases que implementan una interfaz solamente están obligadas a definir los miembros de esa interfaz, pero
no hay nada que nos obligue a escribir código dentro de esos miembros. Por supuesto,
implementar una interfaz para después no darle “funcionalidad” no tiene mucho sentido,
pero es conveniente saber que el compilador
no chequeará que esos miembros realmente
hagan algo.
En el fuente 1 tenemos el código
para C#1 de la clase “intermedia” que
podemos usar para clasificar objetos de
un tipo que no implementa la interfaz
IComparable. De esta clase sólo usaremos la parte expuesta por la interfaz
IComparer, es decir, el método Compare;
si esta clase tuviera más miembros, éstos
se ignorarán, al menos al usar el objeto
como argumento del método Sort.
public class ColegaComparer : IComparer
{
public int Compare(object x, object y)
{
Colega c1 = ((Colega)x);
Colega c2 = ((Colega)y);
return string.Compare(c1.Apellidos, c2.Apellidos);
}
}
Fuente 1. Código de la clase que implementa la interfaz IComparer
Pero no solo tenemos que usar interfaces definidas en el propio .NET
Framework, ya que las interfaces usadas
pueden ser de cualquier tipo, lo importante aquí es que el método al que queremos pasar un objeto acepte un tipo de
interfaz, y, como es lógico suponer, el objeto pasado debe implementar esa interfaz.
El segundo ejemplo que usaremos
para pasar interfaces a métodos, lo vamos
1
tar, y cada implementación puede ser diferente unas de otras porque lo único importante es que (en nuestro caso) el formulario implemente esos miembros y le de la
funcionalidad que creamos conveniente.
Por ejemplo, puede ser que queramos
crear un formulario para realizar búsquedas, y queremos que no dependa de ningún formulario en particular. Por tanto lo
podemos usar con formularios que utili-
cen diferentes tipos de controles para
almacenar la información en la que realizaremos la búsqueda. Para darle esa independencia al formulario que pedirá los
datos que queremos buscar, podemos utilizar una interfaz que defina los miembros
que cada formulario tendrá que implementar, de forma que nuestro formulario
de buscar utilice la parte del formulario
que implementa la interfaz para llamar a
los métodos.
Ni qué decir tiene que ese formulario de búsqueda no será el encargado de
buscar nada, ya que no sabe dónde tendrá que realizar dicha búsqueda, por tanto serán los formularios que implementen la interfaz los que se encarguen
de todo el trabajo.
En la figura 1 tenemos el formulario buscar. En el control combo estarán
las últimas palabras usadas en las búsquedas anteriores.
Figura 1. El formulario buscar en tiempo
de diseño.
En el fuente 2 tenemos la definición
de la interfaz IBuscar que además de un
método Buscar al que se le pasará como
argumento la palabra que hay que buscar, también define dos métodos:
• LeerCfg devuelve un array con las
palabras usadas en búsquedas
anteriores
• GuardarCfg tiene un parámetro en
el que se indicará la palabra buscada en la última ocasión.
En el formulario buscar hemos definido un método Show que se usará para
mostrarlo y al que habrá que indicarle
un objeto que implemente la interfaz
IBuscar.
Ese argumento se asignará a una
variable interna del tipo de la interfaz,
con idea de usarla para llamar a los
métodos correspondientes del objeto
pasado. Lo primero que hacemos, después de asignar el objeto recibido a la
variable interna, es llamar al método
En el texto sólo aparecen los fuentes en C# pero puede descargarse también los de VB.NET desde nuestra Web www.dotnetmania.com
<<dotNetManía
Al estar declarado el parámetro
como un tipo concreto de una interfaz,
esa sobrecarga del método Sort se asegura de que el objeto usado como argumento tiene la funcionalidad que se
espera, por tanto, será seguro usarlo, y
se supone que hará el trabajo que debe
hacer.
33
<< dnm.inicio.taller
// Interfaz para proporcionar métodos para buscar
public interface IBuscar
{
string[] LeerCfg();
void GuardarCfg( string palabra);
bool Buscar( string texto);
}
// El formulario de buscar
private IBuscar elForm;
public void Show(IBuscar formulario)
{
elForm = formulario;
// leemos los datos de la configuración
string[] lista = elForm.LeerCfg();
cboBuscar.Items.Clear();
if( lista == null )
cboBuscar.Text = "";
else
{
foreach( string s in lista)
cboBuscar.Items.Add(s);
cboBuscar.SelectedIndex = 0;
}
//
this.Show();
}
<<dotNetManía
private void btnAceptar_Click(object sender, EventArgs e)
{
// Llamamos al formulario para que busque el texto
// y si lo encuentra cerramos este formm en caso
// contrario damos la oportunidad de buscar otra cosa
if( elForm.Buscar(cboBuscar.Text) )
{
// Llamamos al método guardarCfg
// por si quiere guardar la palabra buscada
elForm.GuardarCfg(cboBuscar.Text);
Hide();
}
else
cboBuscar.Focus();
}
34
public class Form1 : System.Windows.Forms.Form, IBuscar
{
public bool Buscar(string texto)
{
// Realizar una búsqueda en el contenido del textbox
// Devolverá True si ha encontrado lo buscado,
// y se encargará de resaltar el texto, etc.
int pos = RichTextBox1.Find(texto);
if( pos > -1 )
RichTextBox1.Select(pos, texto.Length);
return pos > -1;
}
public void GuardarCfg(string palabra)
{
// El código para guardar la configuración en este formulario
// El parámetro será la palabra que se ha indicado en buscar
// Tendremos que decidir si la guardamos o que...
}
public String[] LeerCfg()
{
// El código para leer la configuración en este formulario
// y devolverla como un array de tipo String
return new String[] {"Porque", "no engraso", "los ejes",
"me llaman", "abandonao", "gustan", "suenen"};
}
private void btnBuscar_Click(object sender, EventArgs e)
{
// Mostrar el formulario de búsqueda
FormBuscar fBuscar = new FormBuscar();
fBuscar.Show(this);
}
Fuente 3. Código del formulario que implementa la interfaz.
go en los métodos definidos por la interfaz, y tal
como veremos en el
código implementado en
private void btnCancelar_Click(object sender, EventArgs e)
el formulario que usa
{
IBuscar, no se hace nada
Hide();
en el método GuardarCfg,
}
pero como las interfaces
Fuente 2. Código de la interfaz y el formulario buscar “obligan” a que tengamos que implementar
LeerCfg para asignar al combo las palatodos los miembros definidos en ellas,
bras usadas con anterioridad.
estaremos obligados a crear al menos el
Cuando el usuario pulsa en el botón
cuerpo del método para que nuestro
“Aceptar”, se llama al método Buscar de
código compile.
la interfaz, y si devuelve un valor verLa aplicación de ejemplo utiliza dos
dadero querrá decir que el texto indiformularios que implementan la interfaz
cado ha sido hallado, por tanto llamaIBuscar: en uno de ellos se utiliza un conmos al método GuardarCfg para que el
trol RichTextBox y en el otro un control
formulario sepa que esa es la palabra que
TextBox. Para buscar en el primero utilidebe añadir a su lista de palabras interzamos el método Find, mientras que en el
nas. En caso de que devuelva un valor
segundo llamamos al método IndexOf de
falso, se sigue mostrando el formulario
la propiedad Text de la caja de textos. Esto
de búsqueda hasta que se encuentre algo
simplemente es para que veamos que realo se cancele.
mente al código del formulario buscar le
Tal como comentamos en la nota,
da igual qué tipo de control será el que se
no tenemos por qué implementar códiuse para hacer la búsqueda, ya que será el
propio formulario el que se encargará de
hacer esa búsqueda.
En el fuente 3 tenemos las implementaciones de los tres métodos de la
interfaz IBuscar, además del método que
muestra el formulario de búsqueda, al
que hay que indicarle como argumento
la instancia actual del formulario, aunque ese objeto se “filtrará” para dejar
pasar sólo la parte del mismo que implementa la interfaz.
Esperamos que con lo aquí mostrado tengamos otra visión de cómo usar
las interfaces, pero esto no lo es todo,
en otra ocasión veremos cómo las interfaces tienen un papel muy importante
cuando queremos usar ensamblados de
.NET desde aplicaciones COM, por
ejemplo desde Visual Basic 6, en las que
queremos mantener la compatibilidad
binaria para no forzar a recompilar los
ejecutables cuando añadimos nuevos
elementos a ese ensamblado, pero eso,
será en otra ocasión, cuando veamos el
tema de la interoperabilidad.
¡Nos vemos!
dnm.servidores.sql
Luis Miguel Blanco
Ordenación de datos en
Reporting Services
Uno de los aspectos principales en cualquier generador de informes radica en la
capacidad de ordenar los datos visualizados al usuario del modo más versátil posible. Reporting Services es una herramienta que nos ayuda enormemente en nuestro
trabajo como diseñadores de informes, gracias a la extensa oferta de elementos
que nos ofrece para la creación de informes en general, y la aplicación de ordenamiento a los datos mostrados en particular.
En este artículo, tal y como apunta su título, nos
ceñiremos al modo en cómo podemos ordenar los
datos mostrados por un informe, describiendo las
técnicas que a nuestro alcance pone Reporting Services
para la consecución de dicho fin.
Por tal motivo, se asume que el lector conoce los
aspectos elementales en el proceso de creación de un
informe básico, a efectos de poder entrar directamente en la descripción de los procedimientos necesarios para ordenar un listado.
Respecto a los informes de ejemplo que utilizaremos, todos se encontrarán situados dentro de un proyecto de informes de Visual Studio .NET, y tomarán
como origen de datos la tabla Customers de la base de
datos Northwind de SQL Server. Igualmente, todos
visualizarán los datos en una región de datos de tipo
tabla de Reporting Services. Estos ejemplos se encuentran disponibles para su descarga como material de
apoyo en la dirección www.dotnetmania.com.
Y ya, sin más dilación, comencemos nuestra andadura por el universo de los informes ordenados.
Aplicando un orden simple
Luis Miguel Blanco
es redactor de dotNetManía. Es
consultor en Alhambra-Eidos. Ha
escrito varios libros y decenas de
artículos sobre la plataforma
.NET (lalibreriadigital.com)
El modo más básico de ordenar los datos de un
informe consiste en establecer el criterio de ordenación de forma fija en la región de datos utilizada para
visualizar la información.
Como ejemplo de este tipo de caso crearemos un
informe con el nombre rptOrdenBasico; una vez creado su origen de datos y añadidos los campos a mostrar en la tabla del diseñador, daremos los siguientes
pasos para crear un orden por el campo Country:
En primer lugar, situados en la pestaña “Diseño”
del informe seleccionaremos la región de datos tabla,
y a continuación haremos clic derecho en el indicador de tabla, que es el recuadro situado en su esquina superior izquierda, como muestra la figura 1.
Al aparecer el menú contextual elegiremos la
Figura 1
opción “Propiedades”, que abrirá un cuadro de diálogo en el que nos situaremos en la pestaña
“Ordenación”. En la columna “Expresión” seleccionaremos de la lista desplegable el campo Country, en
la columna “Dirección” dejaremos el valor por defecto, Ascending, como vemos en la figura 2.
Pulsaremos el botón “Aceptar” y pasaremos a la pestaña “Vista previa del informe” para ver el resultado en
ejecución, comprobando que los registros se ordenan
por el campo anteriormente establecido.
Como habrá observado, podemos construir nuestro orden para el informe basado en varios campos;
<<dotNetManía
<< Algunas consideraciones iniciales
35
<< dnm.servidores.sql
Figura 2
tan sólo hemos de ir agregándolos en la
forma que acabamos de explicar, y establecer su prioridad utilizando los botones de flecha arriba/abajo suministrados a tal efecto en esta ventana. La figura 3 muestra este informe en ejecución
con un orden basado en los campos
Country y City.
de informe. Gracias a un parámetro tendremos la capacidad de asignar el campo
de ordenación al ejecutar el informe, evitando la rigidez que supone crear un orden
en diseño que no podemos alterar, como
ocurría en el caso anterior.
Ilustraremos este escenario de trabajo creando un nuevo informe con el
nombre rptOrdenParametro, en el que
incluiremos un parámetro asociado al
orden de su región de datos, que nos
permita seleccionar qué campo queremos utilizar para ordenar.
Crear un parámetro es una labor muy
sencilla; una vez que nos situemos en la
pestaña “Diseño del informe”, seleccionaremos la opción de menú “Informe” +
“Parámetros del informe”, que abrirá el
cuadro de diálogo para el mantenimiento de parámetros. Pulsando el botón
“Agregar”, crearemos un parámetro con
el nombre parCamposOrdenar, de tipo
String, como muestra la figura 4.
Al ejecutar este informe desde la pestaña “Vista previa” no se mostrarán
inmediatamente los datos como sucedía
en el pasado ejemplo, ya que el motor
de Reporting Services no sabe a priori
el campo por el que queremos ordenar.
En esta ocasión aparecerá en la barra de
herramientas del informe una caja de
texto perteneciente al parámetro creado, en la que teclearemos el nombre del
campo de orden y pulsaremos el botón
“Ver informe” para ejecutar el listado,
como vemos en la figura 6.
Figura 6
Téngase en cuenta que utilizando
esta técnica se distinguen mayúsculas y
minúsculas, por lo que al escribir el
nombre del campo en el parámetro
debemos hacerlo exactamente igual que
aparece en la base de datos, o se producirá un error.
Empleando una consulta dinámica
Figura 4
Figura 3
<<dotNetManía
Establecimiento del orden en
tiempo de ejecución
36
Puede ser puntualmente interesante establecer el orden de un informe de
forma fija e inamovible en un campo,
pero la práctica nos dice en la mayoría
de las ocasiones que el mejor diseño en
este sentido es aquel que permite al
usuario realizar la selección de aquellos
campos por los que necesita ordenar el
listado.
Para solventar este tipo de situaciones, Reporting Services pone a nuestra
disposición los denominados parámetros
Tras asignar los valores de configuración necesarios en este cuadro de diálogo y pulsar el botón “Aceptar”, el
parámetro será creado, por lo que nuestro siguiente paso consistirá en asociarlo con la expresión de orden del informe. Para ello, abriremos la ventana de
propiedades de la tabla, y en la pestaña
“Ordenación” escribiremos la expresión
de forma que la colección Fields del
informe utilice el parámetro en lugar de
un campo fijo, como puede ver en la
figura 5.
Figura 5
Nuestra siguiente forma de ordenación consiste en el uso de una consulta
dinámica de Reporting Services; característica que nos permite modificar en
tiempo de ejecución la consulta SQL
incluida en el informe, encargada de
extraer los datos a visualizar.
Una consulta dinámica se destaca
porque dispone de una parte variable
que está representada por un parámetro al que, como ya hemos visto, podemos asignar valor en tiempo de ejecución, siendo lo que dota a este tipo de
consultas de su verdadera potencia.
Como ejemplo de este tipo de
ordenación crearemos el informe
rptOrdenConsultaDinamica , que inicialmente elaboraremos de igual
modo que los ejemplos anteriores en
lo que respecta a su conjunto de datos
y diseño.
Al crear el parámetro para este
informe lo definiremos como una lis-
<< dnm.servidores.sql
Figura 7
Seguidamente volveremos a la pestaña “Datos” del informe y cambiaremos la consulta SQL para convertirla a
dinámica, lo cual conseguimos encerrando entre comillas la parte fija de la
consulta, concatenándola a continuación al parámetro del informe. Como
resultado obtenemos una expresión evaluable por el motor de informes. Ver el
siguiente código fuente:
="SELECT * FROM CUSTOMERS ORDER BY " &
Parameters!parCamposOrdenar.Value
Es importante hacer notar en este
punto, que para que una consulta dinámica se ejecute adecuadamente, debemos eliminar todos los retornos de carro
que pudieran existir. En nuestro ejemplo no se da tal circunstancia, pero téngase en cuenta para el caso de consultas
SQL con mucho código.
Completados todos los pasos de creación de este informe, al ser ejecutado
desde la vista previa nos ofrecerá el parámetro como una lista desplegable, de la
que seleccionaremos el campo para
ordenar los datos. Ver la figura 8.
Figura 9
Figura 8
Cuando diseñemos un informe que
vaya a necesitar una consulta dinámica,
recuerde que es recomendable comenzar el diseño del modo habitual, utilizando una consulta normal que devuelva los campos que vayamos a visualizar.
Una vez que hayamos depositado dichos
campos en el diseñador del informe, volveremos a la pestaña “Datos” y convertiremos la consulta en dinámica. Si
empezamos la creación del informe
directamente con una consulta dinámica, no se generarán automáticamente
los campos que necesitemos emplear en
la zona de diseño, y tendremos que crearlos manualmente.
Ataque directo al código RDL
Todo el proceso de creación de un
informe a través del diseñador tiene
como resultado la producción de un
archivo con la extensión .RDL (Report
Language Definition), que como su
propio nombre indica, consiste en un
lenguaje de definición basado en
XML, que se utiliza en Reporting
Services para escribir el código de los
informes.
Cuando estamos situados en el diseñador de informes, podemos visualizar
el código RDL del mismo, para ello
seleccionaremos la opción de menú de
Visual Studio .NET “Ver” + “Código”.
Adicionalmente, si el informe tiene sus
datos ordenados, existirá un nodo con
el nombre “Sorting”, que incluirá el subnodo “SortBy”, el cual, a su vez, contendrá los subnodos “SortExpression”
y “Direction”, que son los que definen
respectivamente el campo y dirección
de ordenación para el informe, como
vemos en la figura 9.
La generación de código RDL del
informe es un aspecto del que no tenemos
que preocuparnos, ya que es el diseñador
de informes el que se encarga de esta tarea,
sin embargo, vamos a plantear a continuación un escenario de trabajo un tanto
particular.
Supongamos que hemos creado un
informe con el nombre rptOrdenExterno,
ordenado de forma fija por el campo
Country, lo que hace que no podemos
cambiar su orden mediante parámetros;
pero tenemos la necesidad puntual de
cambiar dicha ordenación a otro campo
distinto desde una aplicación externa que
acceda al servidor de informes y haga esta
operación.
Para lograr este propósito tenemos
que comunicarnos con el servicio Web del
servidor de informes, y a través del mismo acceder a nuestro informe, para poder
manipularlo por código. A continuación
describimos los pasos requeridos para llevar esta operación a cabo.
En primer lugar crearemos un nuevo
proyecto de tipo aplicación Windows (o
ASP.NET según se prefiera) con el nombre CambiarOrdenInforme, y seleccionaremos la opción de menú “Proyecto” +
“Agregar referencia Web”, que mostrará
el cuadro de diálogo para la búsqueda de
servicios Web. Haciendo clic en el enlace “Servicios Web del equipo local”, se
realizará un rastreo de los instalados en
nuestra máquina, localizando el correspondiente al servidor de informes: Report
Service, como vemos en la figura 10.
Figura 10
<<dotNetManía
ta de valores, en la que asignaremos
una etiqueta identificativa y el nombre del campo de orden para cada elemento de la lista. La ventaja de crear
el parámetro de esta forma radica en
que facilitamos al usuario la selección
del campo de orden, evitamos potenciales errores por una incorrecta escritura del nombre del campo, y sólo permitimos que la ordenación se haga por
los campos que realmente nos interesa exponer. Adicionalmente, y para
que al comenzar a ejecutar el informe,
este no aparezca vacío, introduciremos también como valor predeterminado uno de los nombres de campo.
Véase la figura 7.
37
<<dotNetManía
<< dnm.servidores.sql
38
Tras hacer clic sobre el nombre de este servicio Web
pulsaremos el botón “Agregar referencia”, lo que establecerá el enlace entre nuestro proyecto y dicho servicio, para así poder manipular los informes publicados
en el servidor de informes a través de los métodos proporcionados por este servicio. Ver la figura 11.
Seguidamente añadiremos al formulario de la aplicación un Combo
Box, que rellenaremos con
los nombres de
los campos so
bre los que orFigura 11
denaremos, y
un Button, que
al ser pulsado, ejecutará el código encargado de modificar el orden de los datos del informe.
Como paso final del
proceso, en el evento
Click del botón escribiremos el código del fuente 1, en el cual, tras insFigura 12
tanciar un objeto correspondiente al servicio Web
e identificarnos como un
usuario válido, obtendremos la definición del informe. Posteriormente, gracias a las clases del espacio de nombres System.Xml, cargaremos la definición del informe en un documento XML y obtendremos el valor del nodo que contiene la expresión de ordenación, modificándola por el campo
que hemos seleccionado en el formulario.
Finalmente, pasaremos el documento XML del
informe a un stream en memoria, y éste a un array
de bytes que grabaremos como nueva definición
del informe. En el fuente 1 se muestran las acciones que acabamos de describir.
Una vez modificado el orden del informe de
esta manera, podemos abrir una ventana del navegador Web e introducir la dirección http://localhost/ReportServer?/InformesOrdenados/rptOrden
Externo, para comprobar que efectivamente, los
datos se ordenan ahora en base al nuevo campo
elegido.
Imports
Imports
Imports
Imports
Imports
'....
Private
Informe de conclusiones
' si hay problemas al actualizar
' se muestran con el array de objetos Warning
If Not (aAvisos Is Nothing) Then
For Each oAviso As Warning In aAvisos
MessageBox.Show(oAviso.Message)
Next
Else
MessageBox.Show("Establecido nuevo orden de datos en el informe")
End If
End Sub
A lo largo de este artículo hemos introducido al
lector en las capacidades de ordenación de datos básica y avanzada con Reporting Services, una de las
muchas características de esta interesante herramienta
de generación de informes. Esperamos que todo lo
aquí comentado le sea de utilidad en la creación de
sus propios listados.
Dim
Dim
Dim
Dim
Dim
Dim
Dim
Dim
Dim
CambiarOrdenInforme.localhost
System.Xml
System.Text
System.Net
System.IO
Sub btnCambiarOrden_Click ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnCambiarOrden.Click
oRS As ReportingService
sInforme As String
aBytDefInforme() As Byte
sCodInforme As String
oXMLInforme As XmlDocument
oNodoOrden As XmlNode
msInforme As MemoryStream
aBytNuevoInforme() As Byte
aAvisos() As Warning
' instanciar un objeto del servicio web
' del servidor de informes
oRS = New ReportingService
' asignar credenciales de identificación
oRS.Credentials = CredentialCache.DefaultCredentials
' informe a manipular incluyendo ruta
sInforme = "/InformesOrdenados/rptOrdenExterno"
' obtener el contenido del informe en formato binario
aBytDefInforme = oRS.GetReportDefinition(sInforme)
' convertir el contenido del informe a texto
sCodInforme = Encoding.Default.GetString(aBytDefInforme)
' crear un documento xml y cargar dentro el texto del informe
oXMLInforme = New XmlDocument
oXMLInforme.LoadXml(sCodInforme)
' localizar el elemento que contiene el campo de orden
' y cambiarlo por el valor del ComboBox
oNodoOrden = oXMLInforme.GetElementsByTagName("SortExpression")(0)
oNodoOrden.InnerText = "=Fields!" & Me.cboCampos.Text & ".Value"
' pasar el informe a un stream
msInforme = New MemoryStream
oXMLInforme.Save(msInforme)
' posicionar el stream saltando
' los códigos de control
msInforme.Position = 3
' pasar el stream a un array de bytes
aBytNuevoInforme = New Byte(msInforme.Length - 4) {}
msInforme.Read(aBytNuevoInforme, 0, aBytNuevoInforme.Length)
' grabar el array de bytes que contiene
' el informe modificado en el servidor de informes
aAvisos = oRS.SetReportDefinition(sInforme, aBytNuevoInforme)
Fuente 1
dnm.servidores.sql
Jorge Serrano
Atención MySQL, aquí dotNet,
¿me recibe?
MySQL es el gestor de bases de datos open source líder en la actualidad.
Independientemente de la plataforma donde se esté ejecutando este, podemos
conectarlo con nuestras aplicaciones .NET usando algunas de las API de comunicación entre MySQL y aplicaciones Microsoft .NET existentes. En este artículo describiremos de forma sencilla cómo realizar esta tarea con VB.NET y C#.
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.
veces con situaciones curiosas a la hora de abordar
un determinado proyecto. De todos es sabido la proliferación y moda por los entornos y productos open
source. Menos extendido en el conocimiento de todos
son las diferencias existentes entre los productos de
pago y los productos gratuitos, y por ello, en muchas
ocasiones, nuestras decisiones están enfocadas y orientadas únicamente en el coste de los productos sin
atender a otras características no menos importantes. Pero no deseo tratar ese tema de debate en este
artículo, tan sólo mentarlo para que quien lo considere oportuno, recapacite sobre ello.
Lo que no es menos cierto también en todo esto, es
que dependiendo del tipo de cliente o del tipo de desarrollo a llevar a cabo, algunas veces es mucho más rentable acudir a entornos o productos de tipo open source.
Ni todo tiene por qué ser de pago, ni todo tiene por qué
ser open source; la virtud, en este caso, está en el camino
medio de ambos puntos distantes, y por supuesto, alcanzarla y saber cuándo y cómo usar estas tecnologías en
el momento preciso, es una tarea compleja.
En el mundo de las bases de datos, está claro que
los productos estrella implantados en las grandes
empresas de todo el mundo son Oracle y Microsoft
SQL Server (por algo será), pero no es menos cierto, que según el volumen o tamaño de una empresa,
a veces estos robustos entornos de gestión de bases
de datos no son muy bien vistos debido a su elevado
coste (otra vez sale el tema dinero a la palestra de la
toma de decisiones).
Aún así, Microsoft dispone también de un entorno
de nombre MSDE 2000, que no es otra cosa que una
versión reducida y gratuita de Microsoft SQL Server
2000. En el año 2005, aparecerá su sustituto, de nombre Microsoft SQL Server 2005 Express (futuro MSDE
2005 para entendernos aunque el nombre de MSDE se
perderá para siempre). Pero una vez más y en numerosas ocasiones, se dejan ver los defensores de otros entornos o productos que no tengan el signo o marca
Microsoft por detrás –como si la marca Microsoft diera alergia– y por eso entre algunos de ellos, tenemos
MySQL, el gestor de bases de datos open source líder en
ese tipo de distribuciones. Una alternativa sin duda, muy
a tener en cuenta también.
Conociendo MySQL
Basado en los términos GNU
(General Public License), este producto es distribuido por MySQL AB, empresa comercial creada por los fundadores de MySQL, como software open source. MySQL tiene un logotipo muy curioso que es un delfín y cuyo nombre corresponde con
Sakila, nombre que fue seleccionado por los fundadores de MySQL AB entre una amplia variedad de nombres sugeridos en Internet por otros informáticos.
MySQL es un sistema gestor de bases de datos
relacional, que cumple los estándares SQL y entre
cuyas características encontramos que es un producto multihilo, capaz de soportar múltiples usuarios
concurrentes. Ha sido escrito en C y C++ y está disponible para un amplio rango de sistemas operativos
diferentes.
Adicionalmente a esto, desarrollos independientes
atesoran el crecimiento de MySQL y proporcionan
<<dotNetManía
<< En el mundo de la informática, nos encontramos muchas
39
<< dnm.servidores.sql
herramientas de muy diversa naturaleza
que nos facilitarán las tareas de mantenimiento, gestión y administración de nuestras bases de datos.
Respecto a su escalabilidad, debemos
tomar como referencias, las dadas por los
usuarios de MySQL. Así, encontramos
datos que indican que MySQL puede
soportar cerca de 50 millones de registros,
60.000 tablas ó 5.000 millones de filas. Sin
embargo, no queda claro el funcionamiento del sistema en cuanto a rendimiento cuando se manejan grandes cantidades de datos, tablas o filas.
Acerca de las plataformas donde se
aloja MySQL, cabe destacar que usarla en
otras plataformas que no sean Microsoft
Windows es una elección muy generalista. Sin embargo, lo que sí está claro, es
que tengamos donde tengamos alojado
nuestro servidor MySQL, en muchas ocasiones podemos tener la necesidad de
conectar una aplicación .NET con este
motor de bases de datos, y esto es justamente lo que veremos en este artículo.
[
Más información
Se puede recabar más información en el sitio web oficial de
MySQL: http://www.mysql.com
]
<<dotNetManía
Sé quien soy y adónde quiero
ir, pero ¿cuál es el camino?
40
Está claro que siempre que queremos
comunicar un origen con un destino,
necesitaremos un canal que nos permita
esa comunicación. Por supuesto que sabemos quienes somos, ¿una aplicación
.NET ejecutándose en un sistema
Windows por ejemplo?. También se
adónde quiero ir, ¿a encontrarme con
MySQL que está instalado en un sitio
localizado? Pero lo que a lo mejor no tengo claro del todo, es qué ruta tomar o qué
rutas o alternativas tengo para llegar a mi
destino sano y salvo. Sin duda necesitaré
un camino, un driver o API que comunique ese origen con ese destino.
Por suerte, para llevar a cabo este
cometido, existen en Internet diferentes fórmulas o caminos que nos permi-
En este artículo utilizaremos estas tres API, observando
como particularidad, que la API
de colaboración MySQLDriverCS,
es un driver escrito enteramente en C#. Se trata en este últiFigura 1. El driver apropiado, nos permitirá establecer
mo caso, de una contribución
en canal de comunicación entre MySQL y nuestras
open source que puede ser conaplicaciones .NET
sultada en la página Web indicada en la tabla anterior.
tirán comunicar nuestras aplicaciones
Para llevar a cabo nuestro propósi.NET con MySQL. A continuación
to, descargaremos por lo tanto cada una
veremos algunos de ellos, gratuitos, de
de las API comentadas, y las instalarefácil acceso y uso.
mos en nuestro sistema. De este modo,
En mi caso y para usar MySQL en mis
tendremos nuestro sistema preparado,
aplicaciones .NET, he usado la versión
para utilizar cualquiera de las API que
MySQL 4.1.7. En el lado de .NET es
hemos seleccionado como óptimas.
independiente el tipo de aplicación o el
lenguaje a utilizar. En mi caso he utilizado como lenguajes de desarrollo, tanto
NOTA
VB.NET como C#, y aplicaciones
Windows como tipo de proyecto. Lo
Existen otras API de pago y
estrictamente importante en sí, es la API
posiblemente gratuitas en Internet.
o driver, el cuál establecerá la comunicaEn este artículo, me he ceñido únición entre nuestras aplicaciones y MySQL
camente al uso de las API marcacomo veremos a continuación.
das como a tener en consideración
por MySQL.com. Advierta además,
que las versiones de las API pueEstableciendo nuestra vía de
den variar cuando las quiera descomunicación
cargar, ya que la mayoría de ellas,
Tenemos dos tipos de API de comucorresponden a proyectos en consnicación entre MySQL y aplicaciones
tante evolución
Microsoft .NET que podemos establecer
como diferentes: las API gratuitas y las
API de pago. Entre las gratuitas, me gustaría destacar las que detalla la página ofiUsando MySQL ODBC 3.5.1
cial de MySQL y en las cuales me he basado para escribir este artículo. Estas son
dos API declaradas como oficiales, y una
MySQL ODBC 3.5.1 utiliza ODBC
tercera API declarada como API de colacomo medio de comunicación, por lo
boración, cuya responsabilidad recae
que si dispone de Microsoft Visual
curiosamente sobre un desarrollador espaStudio .NET 2002, deberá instalar los
ñol independiente. Estas API son las que
drivers de ODBC .NET Data Provider
se detallan a continuación:
para poder acceder a MySQL adecuadamente o a cualquier otra
API de comunicación entre MySQL y aplicaciones
base de datos a través de
Microsoft .NET
ODBC. En el caso de que
disponga de Microsoft
API oficiales
Visual Studio .NET 2003,
Connector/ODBC - MySQL ODBC driver v.3.5.1
ODBC .NET Data Provider
http://dev.mysql.com/downloads/connector/odbc/3.51.html
viene incorporado con
.NET.
MySQL Connector/Net 1.0.1
http://dev.mysql.com/downloads/connector/net/1.0.html
Una vez instalado
ODBC .NET Data Provider
API de colaboración
y MySQL ODBC 3.5.1 en
MySQLDriverCS v.3.0.16b
nuestro sistema, estaremos
http://sourceforge.net/projects/mysqldrivercs
preparados para crear un
[ ]
<< dnm.servidores.sql
[
Más información
ODBC .NET Data Provider lo
encontrará en la dirección web de
Microsoft: http://www.microsoft.com/
downloads/release.asp?ReleaseID=35715
]
nuevo origen de datos ODBC como se
muestra en las figuras 2 y 3.
Figura 2.Antes de conectar con MySQL
a través de ODBC, deberemos crear un
nuevo origen de datos con el driver
MySQL instalado en nuestro sistema
cambio que existe con la inmensa
mayoría de proyectos restantes es despreciable.
Lo importante es importar el espacio de nombres System.Data.Odbc para
poder trabajar con ella. En el formulario Windows, hemos añadido un control DataGrid y un control Button. El
código de nuestra aplicación de ejemplo para VB.NET y C# es el que se
detalla en el fuente 1.
Figura 4. Nuestra
aplicación en
ejecución
conectándose a
través de ODBC
con MySQL
Imports System.Data.Odbc
[...]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)_
Handles Button1.Click
' Declaramos las variables de Conexión
Dim objConexion As OdbcConnection
Dim objDataAdapter As OdbcDataAdapter
Dim objDS As New DataSet
' Establecemos la conexión con el DSN declarado
objConexion = New OdbcConnection("DSN=PruebaMySQL")
' Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = New OdbcDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion)
' Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL")
' Volcamos su contenido al control DataGrid
DataGrid1.DataSource = objDS.Tables("ConectMySQL")
' Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close()
' Expandimos el control DataGrid para mostrar sus datos
DataGrid1.Expand(0)
End Sub
Fuente 1 (VB)
Una vez que estemos ya listos para
iniciar nuestra andadura hacia
MySQL, iniciaremos un nuevo proyecto en Microsoft Visual Studio
.NET. En mi caso y como ya he
comentado anteriormente, todos los
proyectos de este artículo, están basados en proyectos Windows, si bien, el
Fuente 1 (C#)
Nuestra aplicación en ejecución es
la que se muestra en la figura 4.
Usando MySQL Connector
1.0.1
Una vez instalado MySQL Connector
1.0.1, observamos que esta API contiene
<<dotNetManía
Figura 3. Indicaremos los parámetros de
conexión con la base de datos para
establecer el canal que usaremos para
comunicarnos con MySQL. Con el
botón “Test”, podremos probar si la
conexión está correctamente
configurada
using System.Data.Odbc;
[...]
private void button1_Click(object sender, System.EventArgs e)
{
// Declaramos las variables de Conexión
OdbcConnection objConexion;
OdbcDataAdapter objDataAdapter;
DataSet objDS = new DataSet();
// Establecemos la conexión con el DSN declarado
objConexion = new OdbcConnection("DSN=PruebaMySQL");
// Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = new OdbcDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion);
// Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL");
// Volcamos su contenido al control DataGrid
dataGrid1.DataSource = objDS.Tables["ConectMySQL"];
// Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close();
// Expandimos el control DataGrid para mostrar sus datos
dataGrid1.Expand(0);
}
41
<< dnm.servidores.sql
tres componentes preparados para acceder
a fuentes de datos MySQL de forma directa, tal y como se muestra en la figura 5.
Figura 5. Componentes MySQL
Connector 1.0.1 en Visual Studio .NET
Estos componentes, están preparados para ser utilizados en Microsoft
.NET Framework 1.0 y Microsoft
.NET Framework 1.1. De hecho, hay
dos grupos de componentes que podremos utilizar en ambos entornos.
Nosotros, sin embargo, accederemos
a MySQL en este artículo, a través de
código directamente, por lo que iremos a
la carpeta “References” de nuestro entorno Microsoft Visual Studio .NET para
añadir la referencia a MySQL Connector
1.0.1 como muestra la figura 6, teniendo
en cuenta la versión de Microsoft .NET
Framework que estamos utilizando.
<<dotNetManía
Figura 6.Añadiendo la referencia de
MySQL Connector 1.0.1 en
Visual Studio .NET
42
De esta manera, lo primero que
haremos será importar el espacio de
nombres MySql.Data.MySqlClient y
escribiremos a continuación el siguiente código para nuestras aplicaciones.
Este código quedaría, en este caso, como
se indica en el fuente 2.
El resultado de ejecutar estas líneas
de código es el mismo que hemos visto
en los ejemplos anteriores. El cambio
reside en la manera en la que conectamos con MySQL.
Imports MySql.Data.MySqlClient
[...]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
' Declaramos las variables de Conexión
Dim strConexion As String
Dim objConexion As MySqlConnection
Dim objDataAdapter As MySqlDataAdapter
Dim objDS As New DataSet
' Establecemos la conexión con el DSN declarado
strConexion = "Database=test;Data Source=localhost;User Id=root;Password=dotnetmania"
objConexion = New MySqlConnection(strConexion)
' Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = New MySqlDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion)
' Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL")
' Volcamos su contenido al control DataGrid
DataGrid1.DataSource = objDS.Tables("ConectMySQL")
' Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close()
' Expandimos el control DataGrid para mostrar sus datos
DataGrid1.Expand(0)
End Sub
Fuente 2 (VB)
using MySql.Data.MySqlClient;
[...]
private void button1_Click(object sender, System.EventArgs e)
{
// Declaramos las variables de Conexión
string strConexion;
MySqlConnection objConexion;
MySqlDataAdapter objDataAdapter;
DataSet objDS = new DataSet();
// Establecemos la conexión con el DSN declarado
strConexion = "Database=test;Data Source=localhost;User Id=root;Password=dotnetmania";
objConexion = new MySqlConnection(strConexion);
// Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = new MySqlDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion);
// Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL");
// Volcamos su contenido al control DataGrid
dataGrid1.DataSource = objDS.Tables["ConectMySQL"];
// Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close();
// Expandimos el control DataGrid para mostrar sus datos
dataGrid1.Expand(0);
}
Fuente 2 (C#)
Usando MySQL DriverCS
3.0.16b
La instalación de MySQL DriverCS
conlleva la sorpresa adicional, de que se
trata de una API o driver escrito completamente en C#, y el cuál realiza las funciones de conexión entre nuestras aplicaciones .NET y MySQL.
De la misma manera que hemos
hecho en el caso anterior, añadiremos a
nuestro entorno de desarrollo, una refe-
rencia al componente MySQL DriverCS
tal y como se muestra en la figura 7.
Una vez hecho esto, estaremos
entonces preparados para utilizar esta
API o driver y conectar así nuestras
aplicaciones a nuestras fuentes de
datos MySQL. Lo primero que haremos será importar el espacio de nombres MySQLDriverCS para utilizar este
driver en nuestra aplicación, y escribir el código de nuestra aplicación (ver
fuente 3).
riores. La manera en la que deseamos
conectar es la que varía y la que debemos elegir nosotros mismos, según
nuestras necesidades.
Conclusiones
Figura 7
El resultado de ejecutar estas líneas
de código es, una vez más, el mismo que
hemos visto en todos los ejemplos ante-
Como podemos observar, las similitudes de conexión a fuentes de datos
MySQL son bastante cosiderables entre
unas API o drivers y otros, aunque eso
sí, existen algunas diferencias léxicas a
tener en cuenta.
Imports MySQLDriverCS
[...]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
' Declaramos las variables de Conexión
Dim objConexion As MySQLConnection
Dim objDataAdapter As MySQLDataAdapter
Dim objDS As New DataSet
' Establecemos la conexión con el DSN declarado
objConexion = New MySQLConnection( New MySQLConnectionString("localhost", "test", _
"root", "dotnetmania").AsString)
' Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = New MySQLDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion)
' Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL")
' Volcamos su contenido al control DataGrid
DataGrid1.DataSource = objDS.Tables("ConectMySQL")
' Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close()
' Expandimos el control DataGrid para mostrar sus datos
DataGrid1.Expand(0)
End Sub
Fuente 3 (VB)
using MySQLDriverCS;
[...]
private void button1_Click(object sender, System.EventArgs e)
{
// Declaramos las variables de Conexión
MySQLConnection objConexion;
MySQLDataAdapter objDataAdapter;
DataSet objDS = new DataSet();
// Establecemos la conexión con el DSN declarado
objConexion = new MySQLConnection(new MySQLConnectionString("localhost", "test",
"root", "dotnetmania").AsString);
// Asignamos al adaptador la instrucción SQL junto a la conexión a utilizar
objDataAdapter = new MySQLDataAdapter("SELECT Nombre, Apellidos FROM tabla", objConexion);
// Volcamos los datos a un DataSet
objDataAdapter.Fill(objDS, "ConectMySQL");
// Volcamos su contenido al control DataGrid
dataGrid1.DataSource = objDS.Tables["ConectMySQL"];
// Cerramos la conexión porque no la vamos a utilizar más
objConexion.Close();
// Expandimos el control DataGrid para mostrar sus datos
dataGrid1.Expand(0);
}
Fuente 3 (C#)
MySQL ODBC driver v.3.5.1 nos
obliga a establecer una conexión ODBC
y a usar System.Data.Odbc. Además, esta
forma de conexión hace previsible que
exista una diferencia de rendimiento
entre el acceso ODBC y otros métodos
de acceso. El acceso a través de ODBC
siempre ha estado criticado por la falta
de rendimiento y más aún si se compara con un driver de acceso nativo al gestor de bases de datos, como podría ser
por ejemplo System.Data.SqlClient para
Microsoft SQL Server 7.0 ó superior.
MySQL Connector 1.0.1 es quizás el
que más parecido tenga con System.
Data.Odbc y el resto de espacios de nombres que permiten accesos a diferentes
fuentes de datos. Su uso es bastante
intuitivo y sencillo. Los componentes,
nos facilitan asimismo, la posibilidad de
escribir aplicaciones n-tier de forma
rápida y sencilla.
MySQL DriverCS es quizás a la hora
de establecer la conexión con MySQL
el driver más curioso. La forma en la
que establece la conexión no es a la que
nos tienen acostumbrados otros drivers,
pero es igual de efectiva. No es tan completo como lo podría ser MySQL
Connector 1.0.1 pero su simplicidad es a
veces mucho más interesante que las
características que nos pueda aportar
otra API de conexión.
Nótese además, que en nuestros
ejemplos, hemos utilizado la instalación
que MySQL realiza por defecto, por lo
que el puerto de MySQL para establecer la comunicación es el puerto por
defecto, el 3306. Si por razones que considerara oportunas, deseara modificar
ese puerto a la hora de instalar MySQL,
debe tener en cuenta que quizás deba
hacer referencia al puerto directamente como parámetro de conexión, como
puede ser el caso de la creación del origen de datos a través de ODBC o en el
uso de MySQL DriverCS como parámetro del método MySQLConnection
String.
Aún así, hemos podido ver con ejemplos prácticos, cómo establecer comunicaciones con nuestras aplicaciones
.NET y MySQL, utilizando para ello,
diferentes API o drivers que nos han
permitido establecer de una manera
muy sencilla la comunicación efectiva
con MySQL.
<<dotNetManía
<< dnm.servidores.sql
43
dnm.arquitectura
Daniel Mazzini
¡Mi madre es un Singleton!
Siguiendo con el tema del último artículo, volvemos a tratar algunos patrones
de diseño básicos. En este caso veremos el singleton. Si bien puede tener dos
lugares distintos de donde se llaman, siempre es la misma instancia que atiende a la petición cliente.
<< Resumen
Se asegura que solo se crea una instancia de una
clase. Todos los objetos que usen una instancia de esta
clase siempre usarán la misma instancia.
Objetivo
En principio se desea que se pueda acceder en una
manera centralizada a un recurso único en el sistema.
También puede usarse en los casos donde la creación de un objeto implique consumir demasiados
recursos. De esta manera se crearía el objeto y quedaría guardado.
Contexto de uso
Es uno de los patrones que más utilizo cuando trabajo. Lo utilizo para centralizar la información como
puede ser la información de conexión a un servicio
Web, o de rendimiento, como puede ser crear la capa
de datos solo una vez.
Implementación: ¿Cómo se hace un
Singleton?
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.
Lo primero que hay que tener claro es que nadie
desde fuera de la clase puede crear una instancia, por
tal motivo el constructor debe ser privado.
Para poder obtener la instancia, necesitaremos de
un método o propiedad. Este método no puede ser
de instancia, sino de clase, es decir un static (o shared en Visual Basic) que siempre devuelve la misma
instancia.
La instancia que retorna es privada y static.
El resto de lo que contenga la clase depende de la
lógica de negocio que maneje.
En el diagrama UML 1 se puede ver como queda.
Diagrama UML 1
Una de las primeras preguntas que se me ocurrió
cuando vi este patrón por primera vez fue “¿y por qué
no usar todos los métodos estáticos?”. De hecho, la
plataforma .NET tiene clases con todos métodos estáticos, como System.Console. Algunas de las razones
puede ser que se debe usar una interfaz. Por ejemplo,
si se crea una clase para reproducir audio y otra clase
para reproducir vídeos, los dos deberían ser Singleton
para no reproducir dos temas al mismo tiempo, y tener
una interfaz IMovimientos, con métodos para adelantar o atrasar un tema. En el diagrama UML 2 se visualiza el resultado.
Diagrama UML 2
<< dnm.arquitectura
Evitando copias
Ya hemos visto que la idea de un Singleton es que
sea una instancia única. Para mantenerla así, existen
temas a tener presentes:
• Serialización. Un objeto se serializa por distintas razones; generalmente porque es un objeto
que se transfiere entre capas y debe pasar como
binario o XML a otra capa, o simplemente para
persistir su información en un archivo de disco.
Un objeto Singleton no debe incluirse en ningún proceso de serializacion.
• Clonación. El segundo tema a tener presente es
la clonación. Un objeto Singleton no debe
implementar la interfase IClonable, ni directa
ni indirectamente.
• Herencia. En cuanto a herencia, para que nadie
pueda heredar de esta clase y crear más de una
subclase, lo que generaría, en tiempo de ejecución, más de una instancia, se le indica a la
clase del Singleton que no podrá ser heredada
(sealed).
• Sincronización de threads. El último tema, la sincronización de threads, es el más difícil de controlar a primera vista. El método que crea el
Singleton es estático, es decir, que distintos thread podrían llamarlo, pudiendo pasar de tener 0
instancias a tener 2 instancias si dos thread entran
por vez primera a crear la instancia. Para mitigar este problema usamos una técnica de programación de múltiples hilos llamado doble check,
donde se chequea dos veces un valor, antes y después del bloqueo del thread.
Evitando confusiones
Algo que suele suceder con bastante frecuencia
es que cuando desarrollamos una aplicación tenemos
un objeto que es único para toda la aplicación, y queremos poder compartirlo desde distintas aplicaciones. En este caso, el Singleton que usaremos es el de
remoting. Remoting me permite crear un objeto que
vive en el servidor y que es el mismo para distintos
clientes porque se comparte por referencia. El patrón
Singleton me permite crear algo único para el mismo cliente de formulario Windows, como puede ser
la información referente al menú y sus opciones visibles según los roles que tenga en la aplicación.
Con aplicaciones Web la cosa cambia un poco
porque tengo el objeto Application, colocando un
objeto ahí será el mismo para todos los que accedan
a la Web.
Ventajas de este patrón
• Existe solo una instancia de la clase.
• Acceso de forma controlada a la instancia. No
usamos variables globales.
• Otras clases que hagan uso de la clase Singleton
obtendrán una instancia por medio de un método estático, antes que construyéndolo.
• El método que me trae la instancia encapsula el proceso de creación; a veces el proceso
de creación puede significar realizar otra tarea,
por ejemplo, abrir un archivo que hará de log.
Podemos valernos de los archivos de configuración.
Desventajas
• Subclases. Debido a que el método estático es
la clave para llegar a la instancia que está dentro de la clase Singleton, y como los métodos
estáticos no pueden ser virtuales, y por ende
sobrescribirse, esto genera problemas a la hora
de crear una clase que herede del Singleton.
Tendríamos que ocultar con el comando new.
Roles
El Singleton es un patrón muy sencillo en cuanto a roles porque solo consta de una clase.
Singleton: Clase de de la cual queremos tener
una única instancia.
Ejemplo
Podemos seleccionar en tiempo de ejecución a
qué destino enviar un mensaje, a una cola de mensaje de MSMQ o a una colección cola. Para esto podemos hacer una interfaz llamada IMensajeria, que tenga dos métodos: uno para enviar mensajes y otro para
cerrar la cola. El fuente 1 muestra el código de la
interfaz.
public interface IMensajeria
{
void Send(EntidadBase body);
void Close();
}
Fuente 1
<<dotNetManía
Quizás la razón más importante para usar un
Singleton antes que los métodos estáticos son los cambios; es posible, agregando no más de 10 líneas de código, hacer que una clase normal pase a ser Singleton,
mientras que de la otra forma, tendría que pasar todo a
estáticos, con el importante cambio que significa en la
clase cliente. Por lo tanto, me da la posibilidad de pensar mi arquitectura sin interesarme la cantidad de instancias necesarias, luego agregaré las líneas necesarias
si es de una sola instancia.
En la sección de ejemplo se ven las líneas de código necesarias para crear el Singleton, todas ellas encerradas en una región.
47
<< dnm.arquitectura
...se desea que se pueda acceder de una manera centralizada a un
recurso único en el sistema.También puede usarse en los casos donde la
creación de un objeto implique consumir demasiados recursos.
De esta manera se crearía el objeto y quedaría guardado.
Una vez creada la cola, debemos enviar el mensaje. Deseamos no tener que crear la cola cada vez, sino
solamente enviar el mensaje. Para esto usaremos el
patrón Singleton. El diagrama UML 3 muestra la
estructura final.
También estoy asociando lo explicado en el artículo anterior, un modelo SuperClase Abstracta. La
razón es que me interesa enviar cualquier objeto siempre y cuando herede de EntidadBase.
Todo esto se ejecuta desde una aplicación
Windows, donde puede seleccionar si lo
envió a una cola normal o a MSMQ.
También puedo enviar un objeto u otro.
Diagrama UML 3
Para facilitar la escritura desde el código cliente,
he cambiado el método ObtenerInstancia por la propiedad Instancia de solo lectura. También se puede
ver la creación retardada de la instancia, es decir, que
hasta que no la necesita no se crea, así como el constructor privado. El fuente 2 muestra los pasos para
crear la instancia única.
private static Cola instanciaUnica;
private static object lockObject= new object();
Queue queue;
<<dotNetManía
private Cola(){
queue= Queue.Synchronized( new Queue());
}
48
Figura 1
public static Cola Instancia{
get{
//doble check:
//Es posible que un segundo thread este creando la
//instancia mi entras se bloquea al primer thread
//Por tal motivo, se vuelve a preguntar despues
//del bloque si es null
if (instanciaUnica==null)
{
lock(lockObject)
{
if (instanciaUnica==null)
instanciaUnica= new Cola();
}
}
return instanciaUnica;
}
}
Fuente 2
Patrones asociados
Este sigue siendo un patrón básico, por lo tanto,
encontramos muchos otros patrones:
• Factory method: Generalmente las factorías de objetos son Singleton. Con una sola factoría alcanza.
• Builder: Separa la construcción de un objeto de su
representación, de forma que el mismo proceso pueda crear diferentes representaciones. La manera más
fácil de entenderlo es la serializacion, donde tenemos un conjunto de caracteres con un determinado
formato (XML, binario, SOAP) y a partir de aquí
vuelve a crear distintos objetos.
<< dnm.mvp.online
Jorge Serrano
Campus MVP
mayor vicio es la tecnología son algunas de las características de este grupo de personas afín a productos
Microsoft.
Lo que está claro, es que si usted está leyendo
este artículo es porque tiene cierto interés sobre
Microsoft .NET y la tecnología en general, su divulgación, expansión, aprendizaje, etc. En resumen, todo
lo que sea aprender le llama la atención.
El artículo de la sección dnm.mvp.online de este
mes nos acerca a la iniciativa emprendida por Krasis
(http://www.krasis.com), empresa especializada en las
tecnologías de la información, y en la persona de José
Manuel Alarcón, MVP de ASP/ASP.NET, que en
su afán por divulgar la tecnología nos facilita enormemente la formación en línea a distancia sobre las
tecnologías Microsoft en general y sobre .NET en
particular. Todo en nuestro idioma.
CampusMVP, la formación al poder
Para hablar de esta interesante iniciativa, hay que
hablar de campus
, y para hablar de campusMVP en
profundidad hay que explicar primero lo que es.
campusMVP es una iniciativa promovida por Krasis
y José Manuel Alarcón, y realizada con la colaboración
de otros MVP en la que se ofrecen cursos de formación en línea sobre tecnologías Microsoft (tanto de programación como de sistemas) y en los que los contenidos y la tutorización es realizada exclusivamente por
MVP. Este es su gran valor diferencial.
No se trata de cursos pensados para obtener una
certificación o título, sino que se dirigen a personas
con la intención de progresar en sus conocimientos
y en definitiva, hacer formación continua para ser
cada vez mejores profesionales. Por eso son cursos
cortos, de temas muy concretos y normalmente especializados, con un precio muy asequible tanto a nivel
personal como empresarial.
Aún así, las miras de campusMVP son mucho más
amplias; entre otras cosas, permite incluso licenciar
contenidos a empresas de formación que quieran
comercializarlos por su propia cuenta.
MVP
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.
Algunas cosas sobre CampusMVP
El hecho de que campusMVP haya apostado por la
formación en línea a distancia no es casual. José
Manuel, consciente de los ritmos de trabajo y desa-
rrollo profesional, y las dificultades que hoy existen
para acudir a lugares donde se pueda recibir formación sobre un producto en concreto (en muchas ocasiones la propia empresa prefiere contratar al formador para que vaya a su empresa a dar la formación),
ha decidido este medio de formación debido a que
esto permite al alumno elegir el horario más satisfactorio para él, y marcar así su propio ritmo de aprendizaje. Adicionalmente, la importante figura del tutor
añadida a los cursos, respalda los conocimientos adquiridos y resuelve cualquier contratiempo o duda planteada en un momento en particular.
Obviamente, si hablamos de formación en línea,
hablamos de Internet y por ello, es razonable que el
usuario disponga de una conexión a Internet a través
de la cuál, poder llevar a cabo su aprendizaje.
Todos los cursos están divididos en lecciones, y
cada una de las lecciones en epígrafes. Los epígrafes
son de pequeña duración, por lo que la flexibilidad
a la hora de parar o continuar en un momento dado
de la formación en línea es muy grande.
El sistema informático implantado en la formación
en línea, le permite siempre elegir qué quiere hacer cada
vez que se sienta delante del PC. Puede retomar la formación en el lugar en el que lo dejó la última vez o puede ir a la parte del curso que desee.
Otra de las características a reseñar de los cursos
en línea de campusMVP es la información indirecta
de apoyo de que dispone el alumno. De esta manera, los cursos se complementan con trucos, enlaces,
preguntas frecuentes, etc.
¿Y los tutores?
Los tutores son conocidos MVP con una larga
experiencia en formación, escribiendo libros y artículos y preparando material técnico. A la hora de
escribir este artículo, los MVP que participan como
tutores de alguno de los cursos impartidos en
campusMVP son:
•José Manuel Alarcón (MVP ASP/ASP.NET)
•Alejandro Mezcua (MVP Compact .NET
Framework)
•Alex A. Solano (MVP ASP/ASP.NET)
•Guillermo Som “El Guille” (MVP Visual Basic)
•Iván González (MVP Windows Server)
•Jesús López “SQL Ranger” (MVP SQL
Server)
•Rodrigo Corral (MVP C++)
<<dotNetManía
<< Que el objetivo principal de los MVP es compartir y que su
49
<< dnm.mvp.online
Los tutores no sólo preparan el material y contenido de
los cursos, sino que además, colaboran con el alumno en las
dudas o problemas que pueda encontrar en su aprendizaje. Se
puede incluso enviar un mensaje de correo electrónico sobre
una duda o problema puntual al tutor, o quedar con él en un
chat a una hora determinada.
¿Qué cursos hay actualmente?
•
•
•
•
•
•
•
•
campusMVP está en continuo crecimiento.
Actualmente hay 8 cursos, aunque la idea y objetivo principal es ampliar ese número de cursos
en el futuro.
Los cursos actuales son los siguientes:
C# para programadores de Visual Basic 6.
Desarrollo de aplicaciones Web ASP.NET para dispositivos móviles.
Fundamentos de desarrollo de aplicaciones Web con
ASP.NET.
Planificación, implementación y mantenimiento de
Directorio Activo en Windows 2003.
Programación asíncrona avanzada en la plataforma .NET.
Programación de aplicaciones distribuidas con .NET
Remoting.
Seguridad avanzada de Internet Information Server.
Técnicas de escritura de código seguro.
Los costes de los cursos
Los costes de los cursos son siempre un tema importantísimo. Hemos indicado ya que los cursos resultan bastante
económicos. Dependiendo del curso seleccionado el coste
suele rondar entre los 65€ y los 130€.
La duración de los cursos también varía según el curso
seleccionado.
Si está interesado en conocer más a fondo esta forma de
aprendizaje pero no se termina de decidir, debe saber que
existe un curso gratuito y que le puede ayudar a familiarizarse con este innovador medio de formación en línea a distancia. El curso de Seguridad avanzada de Internet Information
Server, le permitirá no sólo aprender conceptos sobre la seguridad de IIS sino que además podrá conocer de primera mano
cómo funciona campusMVP. Más fácil no se nos puede poner
¿verdad?
<<dotNetManía
¿Dónde está CampusMVP?
50
campusMVP es una iniciativa virtual, por lo que deberemos acudir a la página Web http://www.campusmvp.com para
poder acceder a todo el material referente a los cursos.
Allí encontraremos todo lo que necesitamos, precios, duraciones, cursos que se pueden recibir, descripción de los cursos, preguntas y respuestas frecuentes, precios especiales a
empresas, etc.
Para cualquier duda respecto a los cursos, se recomienda
visitar la página Web de campusMVP, donde podrá plantear
sus dudas o preguntas.
Sobre Jose Manuel Alarcón
José Manuel Alarcón es MVP de
Visual Developer ASP/ASP.NET desde
abril de 2004.
Ingeniero superior industrial especializado en diseño de máquinas, posee el título de Especialista Universitario en
Consultoría de Empresa.
Estos antecedentes no lo conducían
precisamente al mundo de la informática,
José Manuel Alarcón
hasta que un soleado día de mayo de hace
ya muchos años (demasiados) se contagió del “vicio del sicilio”,
como él lo llama.
Comenzó programando calculadoras HP-48 en lenguaje
RPL para resolver problemas técnicos, pero enseguida se introdujo en el mundo de la informática profesional desarrollando
también aplicaciones de ingeniería. Su primer gran proyecto
“serio” fue un entorno de simulación de ciclos termodinámicos
aunque realizó algunos desarrollos más relacionados con la ingeniería. Eso fue antes de dejarla definitivamente de lado para dedicarse a la informática de modo profesional.
Desde entonces ha visto publicados varios libros de programación e ingeniería, y es colaborador en diversas publicaciones
del sector TIC, como dotNetManía, PC World, Windows TI
Magazine, etc., siendo autor de cerca de 300 artículos. Colabora
con Microsoft en la impartición de seminarios y en su revista
empresarial (www.empresas.microsoft.com).
En la actualidad es socio de Grupo Femxa, un grupo empresarial gallego de servicios profesionales donde dirige diversos
proyectos tecnológicos centrados en la teleformación y los servicios a ISP fundamentalmente.
Puedes encontrarlo en su blog sobre programación .NET
en www.jasoft.org.
Desde aquí mandamos un cordial y afectuoso abrazo a José
y nuestros mejores deseos para su pronta recuperación después
del percance que sufrió cuando se estaba elaborando este artículo. Por suerte para todos y sobre todo para el bueno de José y
quienes le rodean, todo quedará en una mera anécdota.
Si quieres saber más sobre el programa MVP puedes consultar la página de Microsoft en: http://mvp.support.microsoft.com
Conclusión
Como vemos, Internet nos proporciona todas las herramientas
para aprender y formarnos a distancia. Sólo hace falta tener cursos y contenidos de calidad y campusMVP los proporciona.
Las empesas de hoy en día son muy reticentes a la formación; en los costes de formación no sólo se deben tener en cuenta el propio coste del paquete de formación en particular, sino
los costes derivados en traslados, horarios, dietas, etc.
Los métodos de formación como los que nos presenta
campusMVP, permite a la empresa tener una flexibilidad
mucho mayor y acondicionar el ritmo de formación al ritmo de trabajo y desarrollo profesional del trabajador. De
esta manera, es posible sacar un mayor provecho de a la formación y al trabajador.
dnm.todotnet.qa
Dino Esposito
ASP.NET 2.0 está aterrizando
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]
otra el control DataGrid. Y no me refiero a controles de terceros, sino al DataGrid que viene con el producto de forma nativa. En ASP.NET 2.0, este control está totalmente soportado (no podía ser de otra
forma), pero parece que su hermano mayor, el control GridView, va a sustituirlo en muchas situaciones
comunes. Aparte de unos pocos miembros cambiados de nombre y un modelo de objetos ligeramente
diferente, ambos controles se parecen mucho. Sí que
es cierto, que GridView dispone de un modelo de
objetos más claro y refinado y unos cuantos miembros adicionales, aparte de incorporar el feedback de
dos años de experiencia real. Pero a primera vista,
ambos parecen iguales, y muchos desarrolladores se
preguntan si son necesarios los dos.
No hay duda de que DataGrid debe estar en
ASP.NET 2.0 para garantizar la compatibilidad hacia
atrás y migración suave de aplicaciones. Así que la
pregunta real es ¿por qué necesitaríamos un nuevo
control GridView? ¿Cuál es el nuevo valor real que
ofrece? La primera pregunta de este mes tiene que
ver con el DataGrid, pero la he seleccionado también por que puede ilustrar las diferencias respecto
al nuevo control.
Tengo una columna Identity en una tabla enlazada a un DataGrid. Quiero que los usuarios puedan
seleccionar una fila y ejecutar ciertas acciones sobre
la tabla vinculada con ella. ¿Cómo hago esto sin mostrar la columna Identity en el DataGrid? Si la columna fuera visible, podría encontrar su valor buscando
el dato literal asociado. Pero no quiero que se muestre la columna. Ayuda, por favor.
Bueno, esta es una pregunta típica de principiantes en el DataGrid. Pero, marca una diferencia significativa entre el DataGrid y el GridView. Veamos
primero lo relativo al DataGrid. La solución propuesta es válida tanto para ASP.NET 1.x como para
ASP.NET 2.0.
Para mantener accesibles los valores de una
columna Identity sin mostrarla, basta con añadir esa
columna al DataSet vinculado al control. Para que
no se vea, se la mantiene fuera de las columnas enlazadas al DataGrid. Al mismo tiempo, tienes que informar al DataGrid de la existencia de una columna cla-
ve. Eso lo harás asignando a la propiedad DataKeyField
el nombre de la columna Identity. Pongamos que la
columna identidad se llama EmployeeID. En ese caso,
sería:
<asp:DataGrid … datakeyfield="employeeid" … />
Cuando se asigna DataKeyField, el DataGrid rellena la propiedad DataKeys (un array de objetos) con
los valores de la columna especificada correspondientes a los registros mostrados. Este array contiene tantos elementos como filas se muestran en el DataGrid.
Cada elemento contiene el valor del campo clave para
el registro enlazado. En este punto, si conoces el índice de la fila seleccionada, (cuyo primer elemento es
el 0), puedes ejecutar el siguiente código. Vamos a
suponer que el campo clave es un entero:
int key = (int) grid.DataKeys[rowIndex];
El índice de la fila seleccionada puede obtenerse
de varias formas, dependiendo de la interfaz de usuario de la rejilla de datos. Si la rejilla tiene una columna Select, la propiedad SelectedIndex devuelve el
índice de la fila. Si necesitas la clave de la fila en edición, la propiedad es EditIndex. Si quieres lanzar una
acción personalizada (por ejemplo desde un botón
“Columna”), se obtiene el índice de la fila seleccionada a partir del evento de la estructura de datos. Por
ejemplo, el parámetro pasado al evento ItemCommand
–de la clase DataGridCommandEventArgs– dispone de
una propiedad Item.ItemIndex.
En cualquier caso, es importante que el campo
clave sea parte del origen de datos enlazado al
DataGrid.
Podría pensarse que el mismo modelo es aplicable igualmente al control GridView. Sin embargo,
aunque el modelo no es radicalmente diferente, existen ciertas diferencias que merecen la pena considerarse.
De acuerdo, ya me ha picado la curiosidad. Estoy
deseando saber cuáles son las diferencias entre los
dos controles.
Imagina un escenario en el que tienes una columna Grid Button, para lanzar cualquier acción, por ejem-
<<dotNetManía
<< Muchas aplicaciones ASP.NET emplean de una forma u
51
52
[email protected]
<<dotNetManía
[email protected]
<< dnm.laboratorio.net
plo, añadir un elemento al carrito de la compra. Con
los GridView el índice de la fila seleccionada no es
transportado por la estructura de datos del evento
(como en el DataGrid). Para buscarlo, tienes que recurrir a la propiedad CommadArgument. Sería de la siguiente forma:
void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("AddToCart"))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
}
}
<asp:GridView ID="GridView1" runat="server"
DataSourceID="SqlDataSource1" BackColor="white"
DataKeyNames="productid,productname,unitprice"
AutoGenerateColumns="false" AllowPaging="true"
OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:boundfield datafield="productname"
headertext="Product" />
<asp:boundfield datafield="quantityperunit"
headertext="Packaging"/>
<asp:boundfield datafield="unitprice"
headertext="Price" DataFormatString="{0:c}" />
<asp:buttonfield buttontype="Button" text="Add"
CommandName="Add" />
</Columns>
</asp:GridView>
Fuente 2
Fuente 1
Hay que notar que el evento ItemCommand del
DataGrid es reemplazado por RowCommand en un
GridView. Cierto código de ejemplo en la documentación de la Beta 2, sugiere que el usuario debería de
poner el índice en el CommandArgument manualmente
escribiendo su propio manejador para el evento
RowCreated. Pero otro código fuente de ejemplo en la
misma documentación utiliza el código indicado antes,
y funciona perfectamente. Así que vamos a asumir un
bug comprensible y temporal en la documentación.
El código muestra cómo obtener el índice de la fila
seleccionada. El evento RowCommand se produce para
cada botón pulsado de cada fila del grid. Si dispones
de múltiples columnas de botones, podrías necesitar
asegurarte de que el evento que manejas es el adecuado. Para ello, puedes comprobar la propiedad
CommandName.
El siguiente problema a abordar, es cómo obtener
los datos correspondientes a la fila seleccionada.
Donde esos datos pueden ser de cualquier clase almacenada en el origen de datos. Si el grid está vinculado a un objeto DataTable, los datos correspondientes
serán un objeto de tipo DataRow. Si el grid se enlaza a
una colección personalizada, como por ejemplo una
colección de Clientes, el ítem de datos se corresponderá con un cliente individual.
Lo mejor que puedes hacer es aprovechar la colección DataKeys, que ha sido ampliada en esta versión
para soportar múltiples campos y no solo un campo
clave (con los DataGrid, el campo clave debe ser único, aunque la tabla subyacente no posea ningún campo de este tipo).
Así que estableces uno o más campos clave para
ser manejados por la colección DataKeys. Puedes considerar a la colección DataKeys como una colección de
datos personalizados para ser recuperados de forma
inmediata y sencilla. En el fuente 2 puede ver un
GridView de ejemplo.
Puedes usar la nueva propiedad DataKeyNames para
establecer la lista de campos cuyos valores se almacenarán en la colección de DataKeys para acceso rápido.
La propiedad DataKeyNames es la contrapartida de la propiedad DataKeyField en los DataGrid. Es un array de
strings en lugar de una cadena simple. Los valores de
todos los campos en la propidad DataKeyNames se empaquetan en un elemento de la colección DataKeys. La forma de obtener los valores asociados es la siguiente:
void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("AddToCart"))
{
// Get the index of the clicked row
int rowIndex = Convert.ToInt32(e.CommandArgument);
// Add the item to the shopping cart
AddToShoppingCart(rowIndex);
}
}
private void AddToShoppingCart(int rowIndex)
{
DataKey data = GridView1.DataKeys[rowIndex];
ShoppingItem item = new ShoppingItem();
item.NumberOfItems = 1;
item.ProductID = (int) data.Values["productid"];
item.ProductName = data.Values["productname"].ToString();
item.UnitPrice = (decimal) data.Values["unitprice"];
MyShoppingCart.Add(item);
ShoppingCartGrid.DataSource = MyShoppingCart;
ShoppingCartGrid.DataBind();
}
Fuente 3
Es esta página de ejemplo, ShoppingCartGrid es un
grid de apoyo que utilizo para mostrar los elementos
del carrito de la compra. Esta enlazado a una colección personalizada de tipos ShoppingCart poblada con
objetos ShoppingItem. La colección personalizada del
carrito se almacena en el objeto Session, y se recupera a través de la propiedad MyShoppingCart. A continuación se ilustra esto con un pseudo-código:
<< dnm.laboratorio.net
tores de expresiones predeterminados, tal y como aparecen en la tabla adjunta:
Syntax
Description
Y por último, DataKeys. Por diseño, devuelven un array
de objetos DataKey, con tantos campos como elementos
haya en la propiedad DataKeyNames del GridView. La forma de recuperar un campo concreto es la siguiente:
AppSettings:XXX
Devuelve el valor de la configuración especificada en la
sección <appSettings> del fichero configuración
ConnectionStrings:XXX
Devuelve el valor de la cadena especificada en la sección
<connectionStrings> del fichero de configuración.
Resources:resourcefile, XXX
Devuelve el valor del recurso global especificado en el
fichero .RESX.
item.ProductID = (int) data.Values["productid"];
En general, las propiedades contenidas en el nuevo GridView son una extensión y mejora de las existentes en el antiguo control DataGrid. Como consejo final, ten en cuenta que, cuantos más campos se
almacenen en la colección DataKeys, más sobrecargado estará el campo ViewState. Como puedes suponer,
los contenidos de DataKeys son almacenados en la propiedad ViewState de la página, para no tener que recuperarlos entre viajes al servidor.
Soy relativamente nuevo en ASP.NET 2.0 y no
acabo de comprender exactamente cuál es el significado de esos símbolos $ que he visto en código fuente de ejemplos. En concreto, parece que está relacionado con las cadenas de conexión y los controles
DataSource. ¿Puede explicárnoslo?
Por suerte, el símbolo $ no significa costes ocultos de ninguna clase; ni tampoco que haya que pagar
ninguna clase de “royalties” por página. Es solamente el identificador de un nuevo tipo de expresiones en
tiempo de ejecución. En ASP.NET 2.0 existen 3 tipos
de expresiones, de las cuales, las dos primeras estaban
soportadas por ASP.NET 1.x:
1) Bloques clásicos de ASP: <% … %> y <%= … %>
2) Enlaces a datos de ASP.NET 1.x <%# … %>
3) Nuevos enlaces a datos ASP.NET 2.0 <%$ … %>
No son sinónimos, así que explicaremos las diferencias.
Los primeros existen por compatibilidad con ASP
clásico. La línea de código interna se integra con la
página y se ejecuta cuando ésta es interpretada. Las
expresiones con el prefijo # son expresiones de enlaces que solo son interpretadas después de una llamada al método DataBind(). En realidad, no son expresiones dinámicas, ya que son evaluadas solo dentro del
contexto de la propia llamada de enlace.
ASP.NET 2.0 suministra una infraestructura hecha
a medida para expresiones dinámicas, basadas en un
nuevo juego de componentes, los constructores de
expresiones (Expression Builders). Las expresiones dinámicas tienen una sintaxis similar a la del DataBinding,
excepto que utilizan el prefijo $ en lugar de la almohadilla (#). Las expresiones dinámicas se evalúan cuando se compila la página. El contenido de la expresión
es extraído, transformado en código, e insertado en el
código asociado con la página. Existen unos construc-
Para enlazar una propiedad de un control al valor de
una expresión de forma declarativa se sigue el esquema
<%$ expresión %>. La sintaxis exacta es definida por el
constructor asociado a cada tipo de expresión. Sólo se
pueden usar expresiones dinámicas para asignar un valor
a una propiedad de un control. No puedes incrustar el
valor devuelto en el cuerpo de una página.
DotNetNuke ha estado haciendo mucho ruido últimamente y existen un par de libros publicados sobre el
tema. Nuestra compañía lo ha estado revisando como
una posible plataforma para una consola de administración basada en Web. Con la venidera versión de ASP.NET
2.0 Portal Framework, parece que muchas de las características que poseía se encuentran en esta versión. ¿Crees
que DotNetNuke desaparecerá cuando salga la nueva versión de ASP.NET 2.0?
Creo que DotNetNuke es una forma sencilla, o
–mejor aún– asequible, de construcción de aplicaciones Web ASP.NET para muchos desarrolladores que
no conocen suficientemente la plataforma, o no tienen
tiempo de hacerlo. DotNetNuke suministra un modo
rápido de construir sitios Web de ciertos tipos. El
ASP.NET Portal Framework (o sea, ASP.NET 2.0 Web
Parts) es una forma de construir fácilmente ciertos tipo
de páginas Web. Más en general, existen ciertas similitudes entre DotNetNuke y los kits de inicio de
ASP.NET. Sin embargo, los kits de inicio, se enfocan
más bien a aplicaciones verticales, mientras que la plataforma DotNetNuke es de tipo horizontal.
Una consola de administración es un tipo de aplicación Web relativamente simple, con pocas páginas y un
diseño sencillo. ¿Podría hacerse con DotNetNuke? Por
lo poco que conozco de la herramienta, creo que sí. ¿Es
la mejor opción? Eso es difícil de decir. Necesitarías un
alojamiento Web que lo soporte específicamente, y algunos conocimientos concretos. Probablemente no muchos,
y nada que un buen equipo de desarrollo no pueda abordar, pero para el caso que propones, un tipo de aplicación así, podría ser enfocado más fácilmente mediante
los mecanismos tradicionales. DotNetNuke es estupendo
si tienes que construir muchos sitios Web en muy poco
tiempo, o si el equipo de desarrollo no tiene experiencia
en aplicaciones Web. Por último, el producto estará disponible con toda seguridad después de la aparición de la
nueva versión de ASP.NET.
Traducción por Marino Posadas
<<dotNetManía
public ShoppingCart MyShoppingCart
{
get {return Session["MyShoppingCart"];}
set {Session["MyShoppingCart"] = value;}
}
53
dnm.laboratorio.net
Pedro Pozo
Component Art Web UI 2.1
Cuando se analizan las características de las aplicaciones Web siempre se pone
como desventaja de las mismas que tienen un interfaz más pobre que las aplicaciones Windows. Pues bien, gracias a Component Art podemos llegar a conseguir un
interfaz de usuario para aplicaciones Web tan atractivo como el de una aplicación
Windows.
<< Component Art Web UI 2.1 son un conjunto de componentes cuya utilidad principal es la mejora del interfaz de usuario en aplicaciones Web. Estos componentes permiten al desarrollador de aplicaciones Web
mejorar las capacidades de navegación a través de las
páginas Web, manteniendo la compatibilidad con los
principales navegadores del mercado.
Así, mediante estos componentes, tendremos características tan poco comunes en las aplicaciones Web como
drag & drop, menús interactivos, scroll de contenidos, desplazamiento y alineación de controles, entre otros.
Cabe destacar que aunque son componentes de
pago, podemos utilizar una versión de prueba durante 30 días y que si finalmente nos decidimos por comprarlos además de la licencia de uso también nos proporcionan todo el código fuente de estos componentes, con las ventajas que esto supone. También incluye numerosos ejemplos de cómo utilizar cada uno de
los componentes, que ofrecen mucha funcionalidad y
son bastante sencillos de programar.
La ultima versión de Component Art Web UI está
formada por los siguientes componentes:
Menu
Pedro Pozo
es redactor de dotNetManía. Es
es consultor e-Bussines.
Ingeniero Técnico Informático
de Sistemas y Webmaster
del portal para desarrolladores
.NET Framework Clikear.com
Este componente para crear menús se
basa en XML y CSS, de forma que podemos
personalizar los menús de nuestros desarrollos Web sin necesidad de volver a compilar.
Tan solo modificando el XML que define nuestro
menú podemos modificar el contenido y modificando
la hoja de estilos CSS podremos modificar su aspecto.
Pero, por supuesto, si queremos programar nuestro menú disponemos de eventos de servidor, para
poder desarrollar las acciones que queremos que ejecute cada una de las opciones de nuestro menú.
En cuanto a la personalización del menú, nos ofrece una gran variedad de posibilidades como menús
Componente Menu
contextuales, teclas de acceso rápido, inserción de iconos en las opciones de menú, submenús anidados y
numerosas posibilidades de diseño.
Además, los menús que generamos son compatibles,
como el resto de componentes, con los principales navegadores como Internet Explorer, Netscape, Mozilla,
Safari y Konqueror, entre otros.
TreeView
Este componente merece la pena que le
dediquemos una especial atención, ya que ofrece unas posibilidades de interactuar con él que
no suelen ser habituales en un componente para Web.
Si bien se trata de un componente clásico que nos
permite mostrar una lista de cosas en forma de árbol que
se puede ir desplegando por nodos, las características de
este componente lo hacen especialmente atractivo para
crear un interfaz de usuario interactivo.
Este TreeView nos permite por ejemplo arrastrar y
soltar cualquiera de sus nodos para cambiarlo de localización dentro del árbol. También nos permite cambiar
el nombre de cualquiera de sus nodos y todo esto sin
tener que recurrir a recargar la página. Así como otras
<< dnm.laboratorio.net
NavBar
Con este componente
podremos generar menús, al
estilo de los menús desplegables que ofrece Outlook. Disponemos de
varias opciones y cuando seleccionamos
alguna de esas
opciones se nos
despliega una lista desplegable
que puede ser un
sencillo texto que
puede ir acompañado con iconos y diseños
más complejos.
Cabe destacar que la creación del contenido de este comComponente NavBar
ponente puede
tener como origen una consulta a una base de datos, un
fichero XML o una programación personalizada.
TabStrip
Se trata del típico control
de pestañas que nos podemos
encontrar en numerosas aplicaciones Windows para clasificar contenidos de un mismo formulario, pero
para aplicaciones Web.
Con este componente podremos
personalizar hasta el último detalle de
las pestañas, pudiendo incluir gráficos,
modificar tamaños y colores, colocán-
dolas en horizontal o vertical e incluso
añadirles scroll.
También nos proporcionan numerosos ejemplos que nos permitirán utilizar
diseños ya prefabricados, y la posibilidad
de incluir cualquier componente dentro
del TabStrip para personalizarlos.
MultiPage
Este componente sirve
para generar varias subpáginas que están incluidas en
una única
página, y
que puden
ser mostradas en
cualquier
momento
activándolas desde la
página que
Componente MultiPage
las contiene.
Este componente es similar al control multipágina que ya pudimos ver en
los IE WebControls. Cabe destacar que
los controles de este componente pueden ser cargados y accedidos directamente desde la página Web sin necesidad de usar el método FindControl.
SiteMap
Este componente nos permite crear un mapa de nuestra
Web basándose en XML. Los
diseños que nos ofrece son muy variados
a través de plantillas predefinidas, aunque
también se puede crear un diseño personalizado con hojas de estilo CSS e iconos.
Rotator
Este componente nos permite crear una rotación de contenidos en una página Web sin
necesidad de recargar la página, ni de plugins. Tan solo utilizando HTML, Javascript
y ASP.NET podemos obtener unos efectos realmente interesantes en los que
podemos ver rotar desde banners publicitarios hasta contenidos con texto.
Muy útil cuando se quieren poner
contenidos que van rotando de forma que
aprovechamos un pequeño espacio de
Componente Rotator
nuestra
Web para
p o d e r
mostrar
varios contenidos
que van
cambiando
en interva-
los de tiempo predefinidos.
Los diseños que nos permite crear son
muy variados y todos ellos fácilmente configurables a través de las propiedades del
componente. En cuanto a los contenidos
se pueden cargar a través de un enlace a
una base de datos, mediante un XML o
mediante programación.
Snap
Este componente permite
definir zonas donde poder
posicionar nuestros controles,
incluyendo las opciones de movimiento, arrastrar y soltar, alinearlos y cambiar su tamaño, entre otras.
Conclusión
Si queremos
crear un interfaz
de usuario profesional para nuestras aplicaciones Web que
permita al usuario tener un entorno similar al de una aplicación Windows,
Component Art Web UI nos ayudará en
gran medida en esta labor. Estos componentes nos ofrecen la posibilidad de crear una capa de presentación completa,
interactiva y amigable para el usuario y
muy sencilla de crear y mantener para el
programador.
Quizá se echa en falta una versión
light gratuita, pero en este caso la calidad de estos componentes justifica su
precio.
Ficha técnica
Nombre
Component Art Web UI
Versión
2.1
Fabricante Component Art
Web
http://www.componentart.com
Categoría Componentes
Precio
Valoración
A partir de 499$
<<dotNetManía
características
como teclas de
acceso rápido,
posibilidad de
utilizar plantillas, inclusión de
iconos y diferentes efectos
para expandir y
cerrar
los
nodos.
Componente TreeView
La carga de
datos del árbol
es muy sencilla, pudiendo hacerlo a través de un enlace a una base de datos, a través de XML o simplemente programándolo a gusto del desarrollador.
55
Suscríbase y llévese el
CD Volumen 1 GRATIS
AG
OT
AD
O
AG
OT
AD
O
Aún está a tiempo
❑ Nº5
❑ Nº6
❑ Nº 7
❑ Nº8
❑ Nº9
❑ Nº11
❑ Nº12
❑ Nº13
❑ Nº14
❑ Nº15
Nº16
❑ Nº10
AG
OT
AD
O
Nº4
Nº17
Oferta válida sólo para España hasta el 30 de septiembre 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.biblioteca.net
dnm.biblioteca.net
Visual Studio Hacks
James Avery
Editorial: O'Reilly
ISBN: 0596008473
Páginas: 478
Publicado: Marzo, 2005
Idioma: Inglés
Avery es colaborador habitual de MSDN Magazine y ASP Today, además de autor de varias
obras para las editoriales Wrox y Microsoft Press.
Hackers de sitios Web
Joel Scambray y Mike Schema
Editorial: McGraw-Hill
ISBN: 8448133781
Páginas: 412
Publicado: Enero, 2003
Idioma: Castellano
Aunque no es la temática habitual de desarrollo, no podemos por menos de recomendar esta
obra, ahora que la seguridad está cobrando cada vez más importancia en la construcción de las
aplicaciones. Scambray, que ya había colaborado anteriormente en varias obras del mismo estilo, analiza esta vez la problemática de la construcción de aplicaciones Web seguras, desde el punto de vista del hacker que las ataca. Cuenta con la colaboración del asesor para seguridad Mike
Schema, especialista en soluciones seguras para grandes corporaciones en Foundstone Inc.
La obra recorre muchos aspectos de seguridad práctica, tanto desde el punto de vista del servidor Web, como del cliente. Los mecanismos de autenticación, la autorización, ataques a la administración de estado de la sesión, validaciones, SQL-Injection, y muchos otros, concluyendo con
el análisis de un par de casos reales y unas valiosas listas de comprobación de seguridad antes de
la implantación.
<<dotNetManía
<<
Se trata de un libro sobre trucos y optimización de uso del IDE de Visual Studio. Aunque sólo
su temática ya lo convierte en suficientemente interesante, es raro que cualquiera que utilice el
IDE como herramienta habitual no encuentre un montón de cosas útiles, de esas que no miramos en los manuales y que nos hubieran ahorrado horas de trabajo. Recorre todo lo que es posible hacer con el IDE, desde la organización de proyectos hasta las extensiones o add-ins, pasando por el editor, la depuración, personalización del entorno, trucos de optimización, e incluso
Visual Studio Tools for Office. Como curiosidad, en su sitio Web, pueden descargarse pequeños
fragmentos en formato PDF (ver http://www.oreilly.com/catalog/visualstudiohks)
57
<< dnm.desvan
noticias.noticias
Marino Posadas
Presentado por primera vez un dispositivo de pantalla en 3D
La empresa IO2 Technology (cuya Web estuvo colapsada
desde pocos minutos después de producirse el anuncio oficial), ha presentado al público por primera vez un dispositivo de pantalla en 3 dimensiones. Los principios en los
que se basa su funcionamiento son los del holograma láser
que proyecta imágenes o vídeo proveniente de TV, DVD
u ordenadores. Permite a las aplicaciones interactivas que
lo manejen utilizando los dedos, en lugar del ratón. Para
más datos, ver el sitio de IO2: http://www.io2technology.com/
dojo/204/v.jsp?p=/home. La noticia es independiente del
anuncio por parte de Japón de una iniciativa a nivel nacio-
Documentos y código en la Red
Un vistazo a la seguridad en ASP.NET 2.0: Esa es la propuesta del artículo que J.D. Meier, Alex Mackman, Blaine
Wastell, Prashant Bansode, Andy Wigley, Kishore
Gopalan firman para MDSN y que está accesible en el sitio
http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnpag2/html/PAGPractices0001.asp. Un extenso documento que ha obtenido la mejores calificaciones de todos
sus lectores, y que está siendo recomendado por los sitios
más populares.
EssentialXML Quick Reference: Guía rápida en formato PDF de la, más extensa, obra de Don Box y Aaron
Skonnard, firmada por éste último y Martin Gudgin.
Puede descargarse desde http://65.214.43.45/books/addisonwesley/EssentialXML/index.tss
A Trustworthy Vision for Computing: El sitio Web oficial
de Microsoft donde se explica la forma en que la compañía está siguiendo la iniciativa de Informática Fiable, y
las prácticas que se llevan a cabo y se recomiendan o exigen en todos sus desarrollos. Disponible en
http://www.microsoft.com/mscorp/twc/overview.mspx
nal para crear
un sistema de
TV Digital
que permita
ver, tocar e
incluso disponer de la capacidad de "oler" ambientes virtuales, en las que están
implicados el propio gobierno japonés, algunas de las más
relevantes universidades niponas y compañías del volumen
de Matsushita y Sony (http://news.com.com/Japan+project+aims+to+create+3D+TV+by+2020/2100-1041_35839341.html?tag=nefd.top)
Utilidades del mes
Google desarrolla un add-in gratuito para Microsoft
Word que permite la edición y publicación de blogs.
El Add-in se intala (una vez descargado gratuitamente del sitio
http://buzz.blogger.com/bloggerforword.html), fácilmente y una
vez activo, presenta un menú adicional dentro de Word, con opciones de edición y publicación, guardado, control de borradores. Eso sí,
requiere la creación de una cuenta
personalizada en Blogger y como
puede verse en la pantalla capturada
después de su instalación, puede realizarse una previsualización del código HTML que se genera, previo a
su publicación.
Remora USB file guard Interesante utilidad gratuita que realizar copias de seguridad de
los datos en USB con compresión/descompresión
automática, y varias opciones de sincronización.
Se puede descargar de
http://www.richskills.com/products/6/freeversion.asp
<<dotNetManía
Sitios recomendados
58
The Server Side.NET: Uno
de los sitios que desde su aparición acapara más visitas, movimiento y noticias de actualidad sobre .NET. Disponible en
http://65.214.43.45/index.tss.
Sitio Web de Rubén Vigón: Excelente sitio de este MVP
de Visual Basic .NET con montones de artículos interesantes, recursos, código fuente, tutoriales, manuales y mucho
más sobre .NET en general y VB.NET en particular.
http://www.mvp-access.com/rubenvigon

Documentos relacionados