Post on 05-Oct-2018
WWeboo Messengereboo Messenger. Un sistema de. Un sistema demensajería distribuido sobrmensajería distribuido sobre .NETe .NET
Lo que nos traerá OrLo que nos traerá Orcas: Novedades en C# 3.0cas: Novedades en C# 3.0
dotNetManíanº
24 m
arzo
200
6 •
6,50
€(E
spañ
a)Visual Basic • C# • Delphi • ASP.NET • ADO.NET • .NET Framework • Windows Server System
dotNetManíawww.dotnetmania.com Dedicada a los profesionales de la plataforma .NET
Bienvenido al número 24, de marzo de2006, de dotNetManía.
Este mes nos hemos ido al 3GSMWorld Congress celebrado en Bar-celona, uno de los eventos a nivel mun-dial de la GSM World Series. En realidadno es un evento propio de los desarrolla-dores, aún así allí hemos estado, de lamano de José Miguel Torres quien nosha enviado su crónica desde allí. Y hemosestado porque ya va siendo hora que ledediquemos el tiempo que merecen estosdispositivos chiquitos. Los operadores detelefonía móvil llegan a acuerdos conMicrosoft para distribuir teléfonos conWindows Mobile 5.0, éstas ponen enmarcha programas para desarrolladorescomo Amena con su Área Libre (www.are-alibre.es), etc. En fin, que aún siendo unevento más de negocios y usuarios, allíhemos estado para contárselo.
Aprovechando hemos entrevistado aDavid Fernández Viñuales, Director dela División de Negocio de Movilidad yDispositivos Embebidos de Microsoft Ibérica.
El artículo de portada es de Antonio deRojas, al que aprovecho para dar la bienve-nida, que se estrena con su “Programacióneficiente de dispositivos móviles con VisualStudio 2005”.
Espero que podamos ofrecerle artícu-los sobre programación de dispositivosmóviles más frecuentemente.
Nos ha dado por crear una secciónespecífica para hablar de los productos ytecnologías que aún no están en el merca-do. Se llama dnm.futuro, que servirá para
contener nuestra natural tendencia a lle-nar la revista con este tipo de artículos.Encauzamos pues, bajo este nombre nues-tros esfuerzos, sin olvidarnos de nuestroprincipal objetivo que es formar e infor-mar sobre las tecnologías actuales. Estasección la coordinará Octavio Hernándezy comienza con “Lo que nos traerá Orcas:Novedades en C# 3.0”.
Desde la universidad de La Habana,Miguel Katrib junto con LeonardoPaneque publican el artículo “WebooMessenger. Un sistema de mensajería dis-tribuido sobre .NET.” Este mensajero norequiere de servidor y puede integrarse aotros servicios. Puede descargarse, inclu-yendo el código, desde dotnetmania.com.
No quiero terminar sin hacer unapequeña mención a la triste noticia de estemes: Borland ha puesto el cartel de “SeVende” a Delphi y al resto de sus IDE.Con esto termina una época en la queBorland, inventora de éstos, los deja porno poder rentabilizarlos y/o atenderlos.Visual Studio y Eclipse le han ganado labatalla y lideran el negocio de los IDE enla actualidad. Por mucho que se empe-ñen en la compañía, el 8 de febrero nofue un día de fiesta, precisamente, paralos usuarios de sus IDE, sino más bienpara marcarlo como uno de esos díasnegros de la historia de la informática.Ahora... será otra cosa, pero conservaráel nombre: BORLAND. Suena bien parauna compañía que vende herramientasALM, me recuerda a una que fabricabaherramientas de desarrollo...
dotN
etM
anía
<<
3
Esos dispositivos chiquitos
dotNetManíaDedicada a los profesionales de la plataforma .NET
Vol. III •Número 24 • Marzo 2006Precio: 6,50€
EditorPaco Marín
(paco.marin@dotnetmania.com)
Atención al suscriptorPilar Pérez
(pilar.perez@dotnetmania.com)
Redactor JefeMarino Posadas
(marino.posadas@dotnetmania.com)
Consejo de RedacciónDino Esposito, Guillermo 'guille' Som, Jorge
Serrano, José Manuel Alarcón, LorenzoPonte, Luis Miguel Blanco, Miguel Katrib
(Grupo Weboo) y Octavio Hernández.
Colaboradores habitualesAntonio Quirós, Braulio Díez, Javier
Aragonés, José Miguel Torres, Pepe Hevia ySergio Vázquez.
Además colaboran en este númeroLeonardo Paneque, Antonio de Rojas
IlustracionesYamil Hernández
Edición, suscripciones y publicidad.netalia
c/ Robledal, 13528529 Rivas-Vaciamadrid (Madrid)
www.dotnetmania.com
Tf. (34) 91 666 74 77Fax (34) 91 499 13 64
ImprimeGráficas Vallehermoso
www.graficasvallehermoso.com
ISSN1698-5451
Depósito LegalM-3.075-2004
>>
<<
dnm.editorial
Paco MarínEditor de dotNetManía
24dnm.sumario
dnm
.sum
ario
No lo pienses más, pásate a Visual Studio 2005 10-11Hace pocos días, uno de nuestros bregados Directores de Proyectos de Desarrollo deSoftware entró en mi despacho a comentarme, audaz, que tenía intención de comenzarun próximo e importante proyecto con Visual Studio 2005. Y venía a contármelocomo quien propone un atrevido plan a su general para desbaratar las líneas delenemigo y triunfar en una arriesgada batalla.
Entrevista a David Fernández Viñuales 12-13El posicionamiento de Microsoft y sus productos en el entorno móvil empiezan a ganarterreno y más desde la aparición de Windows Mobile 5.0, que está contando con unaexcelente acogida. David Fernández, al frente de la división de movilidad y productosembebidos en Microsoft Ibérica, nos cuenta desde un fundamento técnico, el presentey futuro de la movilidad.
3GSM World Congress 14Durante 4 días, Barcelona fue el centro de atención mundial en cuanto a novedadesy productos tecnológicos de movilidad se refiere.
Weboo Messenger. Un sistema de mensajería distribuido sobre .NET. 17-22Si bien el correo electrónico es un servicio de comunicación ampliamente utilizado,es un mecanismo pasivo y relativamente lento cuando se quiere establecer un diálogoy una comunicación más cercana al tiempo real. Es por ello que millones de personasen todo el mundo utilizan sistemas de comunicación instantánea, incluso haciendouso de transmisión de voz y video sobre la red.
Programación eficiente de dispositivos móviles con Visual Studio 2005 24-34Desarrollar aplicaciones eficientes para dispositivos móviles es realmente complicado. Elreducido tamaño de los dispositivos y sus limitados recursos producen vértigo hasta en elprogramador más experimentado. En las siguientes páginas daremos unas pautas básicaspara que las aplicaciones desarrolladas bajo este entorno tengan un rendimiento óptimo.
Lo que nos traerá Orcas: Novedades en C# 3.0 35-40En el pasado PDC celebrado en Los Angeles, Microsoft desveló por primera vez variasde las características previstas para la siguiente versión de Visual Studio, Orcas. La“joya de la corona” en lo que a los lenguajes de programación respecta es LINQ(Language INtegrated Query).
Usar componentes .NET desde aplicaciones COM 41-48En este artículo veremos cómo crear componentes en .NET que se puedan usar desdeaplicaciones que utilicen componentes COM. Pero no lo haremos de la forma fácil,sino que veremos cómo hacer que esos componentes funcionen de la misma forma quelo harían con cualquier entorno de desarrollo capaz de generar componentes COM(o ActiveX), de forma que tengan compatibilidad binaria, para no tener que volvera generar la aplicación cliente si decidimos modificar el componente.
dnm.todotnet.qa 49-51Windows Vista, patrones y colecciones
dnm.laboratorio.net 52-53SafeMailLink HttpModuleHecktech.ImageHandler Microsoft XML Diff and Patch 1.0
dnm.biblioteca.net 54Professional C#. 2ª EdiciónIniciación a VB.NET Bases de Datos
dnm.desvan 58
Según la compañía, ambas acciones significan unhito dentro de la estrategia de Borland para asegurarsu liderazgo dentro del mercado de ALM y amplía laposibilidad de ofrecer a las empresas soluciones queproporcionen software más predecible que mejore losprocesos de negocio.
“Los productos y servicios de Segue, orientados aoptimizar la calidad del software, se suman a nuestroportfolio de soluciones para la gestión del ciclo de vidade las aplicaciones” comenta Tod Nielsen, actualPresidente y CEO de Borland. “La decisión de enfocar-nos en ALM, y al mismo tiempo posibilitar que nuestronegocio de IDE tenga la atención que se merece, nospermite hacer lo correcto para nuestro negocio, que eslo correcto para nuestros clientes, y lo que es correctopara el futuro del desarrollo del software”.
Las áreas en las que Borland hará foco durante2006 son: IT Management & Governance, Gestión yDefinición de Requisitos, Gestión del Cambio y Gestión dela Calidad en el Ciclo de Vida.
Borland y Segue han llegado a un acuerdo de fusióndonde Borland adquirirá Segue en un solo paso, com-prando las acciones por un valor total de la transacciónes aproximadamente de 100 millones de dólares. Segúnla compañía, el negocio de de las herramientas IDE esta-ría entorno a 60-100 millones de dólares.
Desde que en los principios de los años 80, Borlandinventara el primer IDE con el Turbo Pascal de AndersHejlsberg hasta la fecha, ha desarrollado productos míti-cos que ahora tienen un incierto futuro. Borland no ven-derá más Delphi, C++ Builder, C# Builder, JBuilder, Kylixo InterBase. ¿Qué compañía se hará cargo de este nego-cio? Nielsen ha dicho que se está buscando un compra-dor para este segmento de negocio que mantenga intac-ta la unidad e invierta y haga crecer estas tecnologías.
El mítico David Intersione, vicepresidente derelaciones con los desarrolladores de Borland, y empe-lado más antiguo de la compañía ha dicho que se uni-
rá a la nueva compañía que compre esta parte del nego-cio después de 20 años de servicios a Borland.
No podemos estar sorprendidos. Si bien el 8 defebrero de 2006 tendremos que marcarlo como unafecha negra en la historia de las herramientas paradesarrolladores, esto ya se venía gestando desde elverano pasado, si no desde antes.
En julio de 2005, Dale Fuller CEO de Borlanddejó su puesto tras un mal año económico para la com-pañía y tras 6 años de servicios, siendo sustituido porinterinamente por Scott Arnold hasta que en noviem-bre fue sustituido por Tod Nielsen, quien fue curio-samente, vicepresidente de herramientas de desarro-llo de Microsoft, entre otros puestos y compañías.
Ya por entonces Bob Coates, un importante accio-nista de Borland (tal y como él mismo se describe), enuna entrevista realizada para SD Times en julio decía“Delphi y los otros productos ya no tienen sitio enBorland”. Poco después intentó sin éxito comprárse-lo a la compañía por ¿150 millones de dólares?.
En resumen, Borland se centrará en sus herramien-tas ALM y abandona sus lenguajes de programación, segúnNielsen, porque son negocios muy diferentes y Borlandno puede atender a ambos como se merecen. En mimodesta opinión, y cada uno que saque sus propias con-clusiones, esta parte del ciclo de vida de las aplicaciones(porque el desarrollo también es parte de este ciclo devida, obviamente) no es rentable para Borland porque noha podido con Visual Studio y Eclipse, que dominan conclaridad el negocio de los IDE. Vístalo como quiera, señorNielsen, pero abandonar Delphi, JBuilder, etc., no es másque “soltar lastre”, como ya hizo la compañía con otrosproductos como dBase, Paradox, etc.
Tendremos que estar atentos para ver qué compa-ñía se hará cargo, o si se crea una nueva a tal efecto.Esperemos que Borland haga bien las cosas y deje enbuenas manos estas herramientas y no acaben por desa-parecer. Pero si yo tuviera que apostar...
dotN
etM
anía
<<
6
dnm.noticias<<
Borland compra Segue Software y vende sus herra-mientas de desarrollo
no
ticia
s.n
oti
cia
s.n
oti
cia
s.n
oti
cia
s.n
oti
cia
s.n
oti
cia
s
La compañía anuncia sus planes para vender su negocio relacionado con los IDE.Delphi, C# Buileder, JBuilder, etc., están tristemente en venta
Disponibles la CTP de febrero de Windows Vista y WinFX El 22 de febrero, Microsoft anunció la versión CTP de
febrero de Windows Vista, sólo para betatesters, la build 5308,la primera edición “con todas sus características”. Microsoft haprometido una edición de testeo para el público para el próxi-mo trimestre (¿en abril quizá?)... Para los desarrolladores, seha anunciado la versión CTP de febrero de WinFX para su
libre descarga, con sus correspondientes versiones de WindowsPresentation Foundation, Windows Communication Foundation, yWindows Workflow Foundation.
Más información en el centro para desarrolladores deWindows Vista en Microsoft: msdn.microsoft.com/windows-vista/getthebeta.
dnm.noticias
dnm.noticias
dotN
etM
anía
<<
7
Desde 2000, el añoanterior al lanzamientode Visual Studio .NET,cuando ya se empezabaa hablar de .NET comouna tecnología que cam-biaría nuestra forma deprogramar, Danysoftimpulsa la realización de
unas sesiones de orientación totalmente técnica, dedicadas aprofundizar en las novedades que Microsoft ofrece.
En este año, aprovechando el lanzamiento de TeamSystem, se abordará la administración del ciclo de vida deldesarrollo del software, como un conjunto de técnicas desti-nadas a impulsar la productividad y coordinación de nuestrosequipos. Según José Luis Castaño, responsable de la organi-zación de este evento, “...apoyados por las herramientas de
Team System iremos transitando desde el inicio del proyec-to, por cada una de sus fases hasta su implementación. Porsupuesto, la programación en .NET seguirá siendo protago-nista principal de las sesiones donde también daremos un lugarde importancia a uno de los lanzamientos más influyentes ennuestra forma de construir software, como es SQL Server2005, con todas sus herramientas destinadas a la creación deinformes y la explotación de la información.”
Este evento, que ya se está convirtiendo en un clásico paralos desarrolladores, es totalmente gratuito.
V Encuentro Desarrolladores Microsoft y DanysoftPor 5º año consecutivo Danysoft y Microsoft Ibérica organizan conjuntamente su “Encuentro de Desarrolladores”
De acuerdo a lo publicado en el blogde Rob Caron (http://blogs.msdn.com/robcaron), referenciado en la pági-na principal de Visual Studio TeamSystem (http://msdn.microsoft.com/vstu-dio/teamsystem), puede descargarse des-de http://msdn.microsoft.com/vstudio/extend la última versión del VisualStudio 2005 SDK, la CTP de febrero(para lo que tiene que darse de alta comoVSIP, Visual Studio Industry Partner ,si no lo está todavía como VSIP).
Esta versión incluye las DSLTools, ejemplos y documentación
actualizada sobre la integración conVisual Studio, incluyendo el ejemplode integración end-end de Iron-Python, el runtime y el kit de exten-sibilidad de Visual Studio Tools forApplications (VSTA) y el TeamPlanning & Documents del VS SDKProduct Team. Estos documentosincluyen su plan de 12 meses y un planpara liberar la release de marzo.
Más información sobre Visual StudioTools for Applications en: http://blogs.msdn.com/vsta/archive/2006/02/03/524676.aspx
Nueva CTP de febrero de Visual Studio2005 SDKLa CTP de febrero es el próximo hito en el camino hacia la versión v2de abril 2006
Iron Python Beta 3
Si el mes que viene anunciábamos la dis-ponibilidad de la beta 1 de Iron Python parasu libre descarga, para este mes ya está dispo-nible la beta 3. Iron Python es el nombre enclave del lenguaje Python para .NET queMicrosoft está desarrollando con la idea de
hacer fácilmente disponibles las librerías de.NET a los programadores de Python. Puededescargarla desde el Download Center enhttp://www.microsof t . com/downloads/details.aspx?FamilyID=F22E51E5-B82E-4A54-9CCC-3418E0BF5639&displaylang=en
Visual StudioFoundation ServerRelease Candidatedisponible
Según Soma Somasegar, VicePresident for Development technologies,comunicó en el pasado VSLive! cele-brado en San Francisco, el desarrollode Visual Studio Foundation Server,la pieza de Visual Studio Team Systemque centralizará la integración y cola-boración cuyo desarrollo está tocandoa su fin. Lo asistentes a este evento yapudieron disponer de una release candi-date y para el resto de los mortales -mor-tales suscriptores a MSDN, eso sí- estádisponible para su descarga desde el 3de marzo.
Más información en: http://msdn.microsoft.com/vstudio/teamsystem/team
Asimismo está disponible desde prin-cipios de febrero para su descarga la guíade instalación de Visual Studio 2005 TeamFoundation Server y Team Explorer.Puede descargarse desde: http://www.microsoft.com/downloads/details.aspx?famil-y i d = e 5 4 b f 6 f f - 0 2 6 b - 4 3 a 4 - a d e 4 -a690388f310e&displaylang=en
Fecha: 29-30 Mayo 2006Lugar: Oficinas Microsoft en MadridInscripción: Gratuita, previo registro (plazas limitadas).Más información: eventos@danysoft.com
www.danysoft.com902 123146
dotN
etM
anía
<<
8
dnm.noticias<<
dnm.noticias
Microsoft ha actualizado las fechasde lanzamiento de los service packs 1 delas dos últimas versiones de VisualStudio, como puede verse en el sitiode MSDN dedicado a informar sobrelas actualizaciones de Visual Studio:http://msdn.microsoft.com/vstudio/support/servicing.
En el evento de lanzamiento deVisual Studio 2005 y SQL Server2005, el 7 de noviembre pasado, seanunció el service pack 1 para VisualStudio 2003 para abril de 2006 y el ser-vice pack de Visual Studio 2005,menos preciso, se anunció para la pri-mera mitad del año 2006, dependien-
do de la respuesta de los usuarios (aúnno había salido la versión final al mer-cado) (ver nº21 de dotNetManía dediciembre de 2006).
El service pack 1 para Visual Studio2003 se presentará en el segundo trimes-tre de 2006 en lugar de en el primero.El beta testing de este service packcomenzará este mismo mes de marzo.
El service pack 1 para Visual Studio2005 se presentará en el tercer trimes-tre de este año. Microsoft no ha hechopública aún la fecha de inicio del perí-odo de beta testing. Estén atentos enel sitio mencionado o a través de nues-tra sección de noticias.
Service Pack de VisualStudio:Actualizaciónde fechas
Visual Studio 2005 WebApplication Projects (Beta V2Preview) y Visual Studio 2005Web Deployment Projects(Beta V2 Preview) disponibles
Microsoft Ibérica ha presentado susúltimas iniciativas de apoyo a la comuni-dad universitaria y al colectivo técnico dedesarrolladores de nuestro país, centradasen la creación de encuentros y diversosrecursos de formación de variada índoleen torno a la plataforma .NET.
Entre las distintas acciones queMicrosoft lleva a cabo con estos grupos deusuarios destaca la cesión de los últimosproductos y tecnologías de la compañía,los programas MSDN Suscripciones yMSDN Académico y la puesta en marcha yapoyo a la amplia comunidad online sobre.NET. Existe más información sobre lasactividades de Microsoft para estudian-tes y desarrolladores en la direcciónhttp://www.microsoft.com/spanish/msdn
Actualmente, existen 20 Clubs .NETrepartidos por la geografía española y7 grupos de usuarios .NET en todaEspaña, con un total de 650 miembros.Podrá ver la lista de unos y otros endotnetmania.com.
Como parte del material de ayuda queMicrosoft entrega a los estudiantes de losClubs se encuentran libros técnicos, acce-
so a tutoriales sobre nuevas tecnologías,descargas de software online a través delprograma MSDN Academic Alliance y elreconocimiento como Most ValuableStudent a aquellos alumnos que hayan mos-trado un especial interés por la tecnolo-gía. Además, la compañía les ofrece la posi-bilidad de asistir a eventos técnicos forma-tivos como Tech-Ed y Train the Trainers.También se organizan encuentros perió-dicos, para que puedan reunirse e inter-cambiar conocimientos, como el taller decódigo CodeCamp.
A través del Programa MSDN paradesarrolladores, Microsoft ofrece soportecontinuo a este colectivo técnico, organi-zando eventos como el Microsoft DeveloperDay, jornada de referencia para esta comu-nidad, que presenta las últimas noveda-des en tecnologías de la compañía; losseminarios interactivos MSDN Talleres,que pretenden ser un acercamiento a latecnología .NET al tiempo que comple-mentan la formación de los profesionalesespañoles, así como las sesiones periódi-cas sobre desarrollo de aplicaciones ISVCommunity Days.
Microsoft refuerza sus programas de colaboración con los estu-diantes y los desarrolladores españoles
Web Application Projects
Visual Studio 2005 Web ApplicationProjects aporta una nueva opción demodelo proyecto Web complementa-rio para Visual Studio 2005 que traba-ja como el modelo de proyecto Web deVisual Studio .NET 2003 pero con lasnuevas características de Visual Studio2005 (refactoring, diagramas de clase,test development, genéricos, etc.) yASP.NET 2.0 (master pages, data con-trols, membership/login, role manage-ment, Web Parts, personalización, sitenavigation, temas, etc.).
Más información en:http://msdn.microsoft.com/asp.net/refe-rence/infrastructure/wap
Web Deployment Projects
Si tienes un proyecto Web de VisualStudio 2005 complejo que requierediferentes configuraciones web.configpara su despliegue o prefieres más con-trol sobre el proceso de compilación,revisa el Web Deployment Projects,una nueva herramienta para VisualStudio 2005. Esta última versión aña-de soporte para Web ApplicationProjects, conserva la codificación defichero cuando se usa la nueva herra-mienta de fusión y más…
Más información en:http://msdn.microsoft.com/asp.net/refe-rence/infrastructure/wdp.
Fuente: http://blogs.msdn.com/bgold/archive/2006/02/10/529846.aspx yhttp://webproject.scottgu.com.
La idea es que ambos esténdisponibles en versión definitivapara el próximo service pack 1 deVisual Studio 2005
Actualmente existen veinte Clubs .NET distribuidos en centrosuniversitarios de toda España y ya son 650 los usuarios agrupados entorno a la tecnología de desarrollo de la compañía.
No lo pienses más,pásate a Visual Studio 2005
Hace pocos días,uno de nuestros bregados Directores de Proyectos de Desarrollo deSoftware entró en mi despacho a comentarme, audaz, que tenía intención de comen-zar un próximo e importante proyecto con Visual Studio 2005.Y venía a contármelocomo quien propone un atrevido plan a su general para desbaratar las líneas del ene-migo y triunfar en una arriesgada batalla.
El hombre esperaba mi reprimenda, lareflexiva valoración del conservador abuelo que ve conmalos ojos cualquier cosa que suponga un mínimo deriesgo. Sin embargo, sólo encontró apoyo, ánimo ymuchas más razones para convencerle de que su deci-sión era la correcta por más que a nuestro clientepudiera suponerle un mínimo de riesgo.
Parafraseando a Hamlet, habremos de decir si noes más arriesgado para el espíritu quedarse quietosufriendo los golpes del inmóvil pasado que tomar lasnuevas armas y arriesgarnos contra las turbulenciasde un desconocido aún, pero prometedor, futuro. Quéduda cabe, lancémonos al riesgo y al futuro, nada hayescrito de los cobardes y en la apuesta corremos elpeligro de perder, pero también nos lloverán las posi-bilidades de ganar. Máxime en un entorno donde nues-tras cartas, como si tahúres del Missisipi fuéramos, seencuentran totalmente marcadas.
Pero qué reticente es el ser humano al cambio.Todos nos apoltronamos en nuestro cómodo estatusactual y rechazamos cualquier cosa que nos saque delmismo. Avisemos, sin embargo, que esta estrategiaparece atentar contra nuestros fundamentos comoespecie. Sólo en la superación de continuos inconve-nientes, sólo en el universo móvil de tener que hacerfrente cada día a un nuevo y diferente reto se planteanuestra evolución sistemática y nuestra mejora desdelos primeros homínidos hasta nuestros días. La como-didad es un camino sin retorno, cuanto más cómodoestás y menos cambio quieres, más avanzas hacia lainmovilidad absoluta, o sea, hacia la muerte.
¡Cuántas veces nos hemos visto en este dilema! Losque llevamos ya unos pocos años en la profesión sabe-
mos que el cambio lo preside todo y que en el cambiode tecnologías se da siempre una mezcla de riesgo y opor-tunidad donde los mediocres suelen naufragar y dondelos mejores siempre salen triunfantes. No aprovecharestas oportunidades nos va dejando atrás; otros las deci-den aprovechar, sin duda, y, por tanto, se colocan pordelante de nosotros en esta alocada carrera por estarsiempre con una posición de privilegio tecnológico. Yahí es donde está el error, cada vez que nos plantamosen la posición segura tenemos que pensar que hay alguienque ha asumido la arriesgada. Otra cosa sería que nadieasumiera el riesgo, pero como siempre hay alguien quelo asume, no te quedará más remedio en el futuro quecompetir con él. Un buen amigo mío, cada vez que obser-va el bajo rendimiento escolar de sus hijos, planteadodesde una postura cómoda, les recuerda que mientrasellos toman esa actitud habrá al menos una docena depersonas por cada uno de ellos que estén pensando enesforzarse a tope en el proceso de estudio, en hacer algúnmaster adicional, en pasar algún tiempo trabajando en
Antonio Quirós
dnm.opinion
<< Así son las cosas.
Antonio Quirós es redactor de dotNetManía.
Co-fundador de las revistasclippeRManía, FOXManía yAlgoritmo.Actualmente es
Director de Operaciones enAlhambra-Eidos
La comodidad es un camino sin retorno, cuanto más cómodo estás
y menos cambio quieres,más avanzashacia la inmovilidad absoluta, o sea,
hacia la muerte
el extranjero y, en fin, en hacer todo unconjunto de cosas que les molestan aho-ra pero que harán que en el futuro seanlos jefes de las empresas donde los que sehan esforzado menos tendrán que traba-jar en un ambiente, sin duda, muchomenos cómodo y agradable.
Todo esto, por supuesto, es extra-polable a nuestro entorno empresarial.Quizá en un principio, el cliente al quele proponemos hacer su aplicación conla nueva versión de un producto tem-blará pensando en retrasos, fallos enherramientas aún no suficientementeprobadas, peor conocimiento por partedel equipo técnico de las nuevas versio-nes, mayor inestabilidad y, como con-secuencia, quizá menos robustez de lasolución desarrollada. Frente a este dra-mático paisaje habría que pintarle otroque podría ser al menos tan veraz comoel anterior. Se trata de que con el nue-vo universo de posibilidades que tienenlas versiones recientes de producto, lassoluciones desarrolladas se adelantan almercado, ofrecen cosas que las realiza-das con versiones antiguas no poseen ysuponen, para quien se arriesga con ellas,una ventaja competitiva importante ensu segmento de negocio. Y al fin y alcabo ese es el objetivo de cualquier com-pañía cuando decide fabricar softwarepara apoyar a cualquiera de sus proce-sos de negocio: obtener ventaja de sucompetencia y lograr un mejor posicio-namiento de mercado.
Pero tengamos en cuenta que todoesto no va a ser cómodo para nosotros.Nos enfrentamos a una nueva versión denuestra querida base de datos, con la queestamos acostumbrados a trabajar desde
hace la friolera de cincoaños. Tendremos queabandonar SQL Server2000 y pasar a SQLServer 2005, si trabaja-mos en entornos de inte-gración nos removerántambién la versión deBizTalk Server y, para ter-minar el año, WindowsVista nos acabará dandola puntilla. Y, desde lue-go, lo más importante,nuestra nunca bien ponderada herra-mienta de desarrollo, Visual Studio queentra en una nueva era de colaboración,ingeniería de producto y trabajo en equi-po. Para qué hablar ya de nuevas tecno-logías con las que tendremos que vérnos-las en cualquier caso, tales como 3G, iden-tificación biométrica, tópicos de seguri-dad avanzada, cada vez más necesarios enun mundo inseguro como el nuestro, mul-titud de nuevos dispositivos móviles, etc.
Con Visual Studio 2005 se nos pre-senta un horizonte de este calibre. Laherramienta se encuentra cada vez másintegrada y sólida. Ahora tendremos laposibilidad de usar Visual Studio 2005Team System que ofrecerá a los equiposde desarrollo cosas que hasta ahora tení-an que buscar fuera de la herramienta,una integración adecuada para dar res-puesta a todo el ciclo de vida de la apli-cación, integrando el ciclo de diseño conel desarrollo y, por tanto, dando un paso
más en el proceso de industrializar laconstrucción de software. Cuando des-de hace tiempo venimos hablando eneste mismo foro de metodologías dedesarrollo, de técnicas para industriali-
zar la fabricación de software muchosdebían pensar que se trataba de una par-te más del verso con que la prensa téc-nica rellena huecos. Nada más lejos dela realidad. Más que el estrictamente tec-nológico éste es el auténtico reto de laconstrucción de software en la actuali-dad. Todo lo que rodea al método deconstrucción es, si cabe, más importan-te que lo que rodea a la ingeniería deproducto. No en balde, la mayor partede los proyectos fallidos en el ámbitodel software a medida vienen dados porproblemas del modelo de colaboraciónplanteado con el cliente o del modelode equipo con que se gestiona al perso-nal que produce software. El hecho deque ahora casi la principal innovaciónde Visual Studio 2005 sea Visual Studio2005 Team System, abona claramenteesta hipótesis.
Quizá lo peor de todo es que ten-dremos que convivir con ambos entor-nos durante tanto tiempo como nues-tros clientes decidan mantener sus anti-guos sistemas. Una vez que ya estáscómodo con tu nueva situación lo quemás te molesta es tener que retrotraer-te a la antigua para hacer cosas a las queya te has deshabituado. ¡Qué pedazo decontradicción! No queríamos cambiary al poco tiempo lo que nos molesta esdar marcha atrás en nuestro proceso decambio.
En fin que hemos tenido un perio-do de inusitada calma en lo que a nue-vas versiones y tecnologías se refiere. Lode los cinco años de SQL Server es algodesconocido e inusual en nuestro sec-tor de conocimiento. Ahora las pagare-mos todas juntas, pero no olvidemos queel horizonte que se abre ante nosotroscompensa sobradamente el esfuerzo quedebamos realizar.
dotN
etM
anía
<<
11
dnm.opinion<<
…en el cambio de tecnologías se da siempre una mezcla de riesgo y oportunidad donde los mediocres suelen
naufragar y donde los mejores siempre salen triunfantes
Entrevista a David Fernández Viñuales
El posicionamiento de Microsoft y sus productos en el entorno móvil empiezan aganar terreno y más desde la aparición de Windows Mobile 5.0, que está contan-do con una excelente acogida. David Fernández Viñuales, al frente de la divi-sión de movilidad y productos embebidos en Microsoft Ibérica, nos cuenta desdeun fundamento técnico, el presente y futuro de la movilidad.
pasado se han producido claros movimien-tos por parte de Microsoft con la finalidad de potenciarla adopción de los dispositivos móviles programables.¿Qué nuevas campañas o iniciativas tiene Microsoft encartera en ese sentido?
Como sabes se ha lanzado Visual Studio 2005, quees un producto totalmente alineado con la estrategia demovilidad de Microsoft. Cualquier persona que tengaconocimientos de algún lenguaje .NET (C#, VB, C++),puede desarrollar en un entorno móvil igual que lo haceen la plataforma básica, con lo que no tienes que dedi-car ni un solo recurso en aprender a desarrollar en unentorno de movilidad específico. Otra de las cosas impor-tantes es la posibilidad de hacer debug en tiempo realmientras la aplicación se está ejecutando en el móvil através de tu portátil, por ejemplo. Es una de las nuevascaracterísticas que los desarrolladores con los que hemoshablado han destacado, pudiendo obtener una soluciónmucho más rápida ante algún problema sin necesidadde tener que pasar por la plataforma de desarrollo.
Otro aspecto muy destacable es la posibilidad desoporte de Web services, que aparte de ser un estándarde mercado, hace que seamos capaces de que en cuatroo cinco líneas de código, podamos enviar un SMS o uncorreo electrónico a un ordenador que por ejemplo esel que está proyectando preguntas en una pantalla.
¿Crees que la programación para móviles despega-rá definitivamente más allá de las aplicaciones de ocio ysoporte básico?
Sí, ya ha sido así. De hecho tenemos muchos part-ners que están desarrollando aplicaciones en entornoempresarial y que además se han traducido en casos deéxito. Desde aplicaciones en ámbito empresarial hastacasos que se han visto por la televisión de cómo la poli-cía, por ejemplo, va utilizando dispositivos con WindowsMobile. Todo ello no sólo hay que entenderlo desde el
punto de vista de desarrollo, que es muy importante, sinotambién desde el punto de vista de interfaz de usuario,ya que al final se trata de desarrollar aplicaciones quesean optimizadas para la empresa desde tres puntos devista: desde el punto de vista de desarrollo, que se desa-rrollen rápida y fácilmente, cosa que se consigue conVisual Studio .NET 2005 y Windows Mobile 5.0; ensegundo lugar que me permita un retorno de inversiónalto porque evidentemente desde la empresa siempre sebusca la rentabilidad; y en tercer lugar que cuando yo lavaya a desplegar no me suponga una barrera de entradapara que mis usuarios no la reconozcan como algo quesea fácil e intuitivo, y eso me lo da Windows Mobile 5.0.
Cuando se habla de estos temas, la gran mayoría dela gente imagina una aplicación típica en la que un alma-cén es actualizado por alguien que simplemente se conec-ta después a un servidor de datos para actualizar infor-mación. Como pensamos que las posibilidades sonmucho más ricas, ¿podrías citarnos las que tú subrayarí-as o te gustaría que la gente conociese?
Existen aplicaciones, por ejemplo, como las desa-rrolladas por Bankinter o BBVA que han desarrolladoun broker online para que clientes desde el móvil puedanrealizar operaciones en bolsa. En cuanto al caso deBankinter tenemos incluso un vídeo que hablan de élpor qué eligieron Windows Mobile y cómo en pocotiempo podían desarrollar una aplicación que permitie-ra operar con hasta 35 bolsas distintas de alrededor delmundo, y todo ello desde un entorno gráfico.
Además existen aplicaciones que permiten reali-zar impresiones directamente por impresora, aplica-ciones que leen a través de un código de barras, e inclu-so utilizar una tarjeta y poder enviar esa informacióna un banco y poder realizar una transacción bancariaonline. Te puedo contar también ciertas visiones, porejemplo, que a través de bluetooth puedas saber hacer
Marino Posadas
dnm.directo.entrevistas
Marino Posadas esasesor técnico y
redactor dedotNetManía, MVP de
C# y formador deAlhambra-Eidos
<< A finales del año
José Miguel Torres
dotN
etM
anía
<<
13
dnm.directo.entrevistas<<
un listado mediante una aplicación todala situación actual de ventas y estado deuna máquina de ventas. Hablando debluetooth que, por ejemplo, cuando vayacon mi móvil reciba un anuncio a tra-vés del mismo, lo que se conoce comomarketing de proximidad.
En definitiva, la tecnología ya no estáponiendo limitaciones; si existe algunalimitación es cuestión más de crear el con-cepto y ser creativo a la hora de poderimplantar esa idea, ya que luego imple-mentarlo es francamente sencillo.
José Miguel: Windows Mobile 5.0,un entorno profesional orientado al con-sumo o un entorno de consumo orienta-do al profesional.
Se ha pensado para que esté en sujusta medida. Una empresa que vaya aelegir tanto desde el punto de vista deconsumo o profesional, va a encontrar-se con todos los medios necesarios y dis-ponibles a su alcance y no sólo eso sinoque además existen dispositivos especí-ficos que te permiten incluso ampliaresa experiencia del usuario, lo quecomenté antes, lectores de código debarras y tarjetas, impresoras e inclusolectores biométricos si además quieresañadir un nivel más de seguridad. Pero,por otro lado, en cuanto a aplicacionesde consumo, yo he llegado a ver hastaun Sudoku. Creo que es un tema más decreatividad y de generación de ideas quede limitaciones para poder hacerlo.
Ya que has hablado el tema de seguri-dad, ¿algo específico al respecto?
Los criterios de desarrollo de Win-dows Mobile 5.0, siguen los mismos cri-terios de seguridad que Windows. Desdeluego es una plataforma muy segura, muyestable, además de la incorporación deciertos mecanismos de seguridad que sehan implementado a propósito, en el casodel mercado profesional, el hecho de quelas comunicaciones estén encriptadas, laposibilidad de poder restringir el accesoal dispositivo mediante contraseña.Pensemos que en el correo, en archivos ydemás aplicaciones, pueden haber datosconfidenciales de la empresa y todas estasmedidas se están tomando para que sialguien te roba el dispositivo no puedarobarte la información, habiendo meca-nismo de eliminación de la informaciónal intentar acceder al dispositivo en reite-radas ocasiones, por parte de personal aje-
no o no autorizado o incluso en la pérdi-da del dispositivo que alguien pueda enviarun comando para eliminar la informacióndel dispositivo. Además contamos con lacertificación FIPS 140-2 que es la máxi-ma certificación de seguridad del gobier-no norteamericano; esto nos avala ydemuestra que Windows Mobile es unaplataforma totalmente segura.
Si pudieras citar los 3 puntos fuertesde esta nueva versión de .NET CompactFramework, ¿Cuáles serían?
Facilidad de desarrollo, entorno dedepuración (ambientes de testeo, prue-bas y simulación), e interoperabilidadcon Web services.
José Miguel: Ante Windows Mobile5.0, .NET, Compact Framework 2.0 ySQL Mobile 2005 se abre un nuevo esce-nario ante nosotros mucho más produc-tivo., más fácil. Sin embargo, como desa-rrollador, encuentro que en temas tancomunes en un entorno móvil como lascomunicaciones por GPRS o por blueto-oth, aún debemos echar mano del códi-go nativo.
Voy a explicar una cosa que estamoshaciendo desde Microsoft. Tenemos unCentro de Innovación de Movilidad, enBoecillo, que lo que está tratando es de
trasladar el conocimiento de WindowsMobile a las TIC para que éstas puedandesarrollar con un valor añadido. Encuanto a la pregunta, ellos han desarro-llado un módulo bluetooth para que pue-da ser utilizado por una empresa sin queéstas tengan que llegar a desarrollarlo.
Este año es el lanzamiento de Win-dows Vista, y todos imaginamos un granmovimiento en ese sentido a medida quevaya llegando octubre. Nos gustaría saberde qué forma Vista va a ofrecer un sopor-te mejorado de dispositivos móviles...
Windows Vista incorporará un nue-vo interfaz de sincronización con dis-positivos móviles, algo más que lo queahora incorpora ActiveSync, permitién-dote mucha más integración entre orde-nador de desarrollo y dispositivo, de unamanera más amigable. Es decir, que vol-vemos otra vez a la base, que la interfazsea intuitiva y fácil de utilizar.
José Miguel: Le gustaría recalcaralgo más…
Sobre todo el gran momento que estáviviendo Windows Mobile 5.0, y el granrespaldo que estamos teniendo por partede los operadores móviles, por parte delos fabricantes y por parte de los partnersque desarrollan las aplicaciones.
David Fernández Viñuales
dotN
etM
anía
<<
14
3GSM World Congress
dnm.directo.eventos<<
fue el centro de atenciónmundial en cuanto a novedades y productos tecnoló-gicos de movilidad se refiere. Más de 960 exposito-res, 50.000 visitantes, 300 altos ejecutivos de las másimportantes compañías del sector y 96.000 metroscuadrados de exposición son sólo algunos datos de loque dio de sí el evento, calificado por muchos comoexcelente. Personalidades como Steve Ballmer(Microsoft), Ed Zander (Motorola), Olli-PekkaKallasvuo (Nokia), Mr Wang Jianzhou (ChinaMobile) o Shane Robison (HP), estuvieron presen-tes en diferentes keynotes en unas jornadas que fueronmarcadas por presentaciones de nuevos productos yanuncios de colaboraciones ente empresas.
En el aspecto tecnológico el protagonista fue HSD-PA (acceso de alta velocidad de descarga de paquetes)que es una evolución de 3G que mejora UMTS, pasoprevio al 4G (HSUPA), y que promete lle-gar a velocidades comparables a las ADSLdomésticas, hasta más de 3Mb/s en el casode HSDPA y hasta algo más de 15 Mb/sen el caso de HSUPA, aunque si bien escierto ambas están en fases de preexpan-sión. Además, se presentaron más de 100nuevos productos (40 de ellos son dispo-sitivos), muchos de ellos ya con HSPDAintegrado y con mensajería instantánea.
Sobre este último aspecto, los máxi-mos responsables de Vodafone, Telefónica,Orange, China Mobile, Telecom Italia yT-Mobile anunciaron la fuerte apuesta quellevaran a cabo sus compañías para que afinales de año sea ya una realidad aña-diendo, además, la compatibilidad conmuchos de los programas de mensajería instantáneaactuales, tales como AOL, GMail, Yahoo o el Messengerde Microsoft.
Dentro de la agenda de 3GSM, estuvo presente elWireless Developer Forum (WDF), que llevaron a caboSymbian, UIQ Technology, QUALCOMM y SunMicrosystem para la comunidad de desarrolladores móvi-les allí presentes. Cada una de las empresas participan-tes ofrecieron charlas sobre qué técnicas de desarrollose utilizan actualmente así de cómo los futuros cambiosdel sector van a influir en el desarrollo de aplicacionesmóviles. Además mostraron las últimas herramientas dedesarrollo así como técnicas y tendencias en cuanto al
desarrollo de servicios móviles. La integración de strea-ming en aplicaciones y aspectos de seguridad cerraron laserie de ponencias de WDF.
Microsoft por su parte, y a través de su CEO, SteveBallmer, anunció la disponibilidad de Microsoft OfficeCommunicator Mobile, una solución empresarial cuyaprincipal característica son las capacidades de colabora-ción en tiempo real. Entre otros, presentó por primeravez Windows Mobile Device Center, que formaráparte de Windows Vista, mostrando la facilidad e inte-gración de sincronización entre PC y dispositivo móvil.Además de la apuesta que muchos fabricantes y opera-doras están realizando a la gran acogida de WindowsMobile 5.0, y de los muchos servicios que desde el mis-mo se podrán ofrecer a través de Windows Live (T.V.,mensajería, búsquedas, música...), mostró como con elnuevo .NET Compact Framework y Windows
Mobile 5.0, se podrán utilizar las API de Windows LiveMobile para que desarrolladores y operadoras puedanlanzar productos con los últimos avances y servicios tec-nológicos con un menor coste de desarrollo. En estalínea la flexibilidad del nuevo marco de desarrollo per-mite que la comunidad de desarrolladores puedan bene-ficiarse de todos estos servicios y muchos más.
Por último, se presentó el nuevo dominio de Internet.mobi, orientado a la navegación desde dispositivos móvi-les para el hospedaje de sitios Web embebidos (comoejemplo del propio evento http://3gsm.mobi), sin dudafueron cuatro días en los que se presentó, en buena par-te, el futuro de la movilidad a nivel mundial.
<< Durante 4 días, Barcelona
José Miguel Torres
❑ Deseo suscribirme a dotNetManía por un año (11 números) por un precio de 65,00€ IVA incluido y recibir el CDVolumen 2 con los ejemplares desde el 12 al 22 en formato PDF de alta calidad de forma gratuita. Si su dirección está fuera deEspaña el precio es de 65,00€ transporte incluido (más información sobre envíos internacionales en www.dotnetmania.com)
❑ Deseo que me envíen los números atrasados marcados según el precio de portada. Otros:
FORMA DE PAGO❑ Talón nominativo a nombre NETALIA, S.L.❑ Transferencia bancaria a nombre de NETALIA, S.L. a:
La Caixa - Número de cuenta 2100 4315 48 2200014696 (Indique su nombre en la transferencia)
❑ Domiciliación Bancaria (con renovación automática, previo aviso)Indique su número de cuenta:
❑ Tarjeta de crédito❑ VISA ❑ MASTERCARDNúmero de su tarjeta: Fecha de caducidad: / (imprescindible)
Firma y/o sello
a de de 2006
DATOS DE ENVÍO
CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DATOS DE FACTURACIÓN (sólo si son distintos a los datos de envío)
CIF/NIF. . . . . . . . . . . . . . . . . . . . Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Usted autoriza a la mecanizaciónde estos datos. El responsable ydestinatario de éstos es Netalia,S.L. Usted tiene derecho a acce-der a sus datos, modificarlos ycancelarlos cuando lo desee. Susdatos no serán cedidos en ningu-na de las formas posibles a terce-ras partes y no se utilizarán másque para el buen funcionamien-to de su suscripción a la revistadotNetManía y para informar-le de las actividades comercialesque realice la editorial Netalia,S.L. Si no desea recibir informa-ción comercial de dotNetManíamarque la casilla siguiente ❑Puede enviar sus datos por Fax al 91 499 13 64, o por teléfono al 91 666 74 77,
o por email a la dirección suscripciones@dotnetmania.com, o también puedeenviarlos por correo postal a la siguiente dirección:
Netalia, S.L.C/ Robledal, 13528529- Rivas Vaciamadrid (Madrid)
❑ Nº11 (6,00€) ❑ Nº12 (6,00€) ❑ Nº13 (6,00€) ❑ Nº14 (6,00€)❑ Nº10 (6,00€)
Suscríbase y llévese el CD Volumen 2 GRATIS
Oferta válida hasta el 31 de marzo de 2006 o hasta agotar existencias
(en preparación)
✃
❑ Nº15 (6,00€) Nº16 (6,00€)
❑ Nº18 (6,00€) ❑ N19 (6,00€)
AGOTADO
❑ Nº20 (8,50€)Nº17 (6,00€) ❑ Nº21 (6,00€) ❑ Nº22 (6,50€) ❑ Nº23 (6,50€)
IRC(Internet Relay Chat)[1], MSN Messenger[2],Yahoo! Messenger[3], ICQ[4], Jabber[5] y última-mente GoogleTalk[6] son algunos de estos sistemas.Las características varían de uno a otro, pero todastienen en común que nos permiten la comunicaciónen tiempo real con otras personas.
Cuando esta comunicación, utilizando algunosde los sistemas anteriores, se hace dentro de una mis-ma empresa o institución se está consumiendo anchode banda para acceder a los proveedores de estos ser-vicios en Internet, es decir, se están gastando recur-sos de la conexión con el exterior, para resolver unproblema de comunicación interior.
Una alternativa podría ser la adaptación de algu-nos de estos sistemas para que sea factible su uso inter-no, (como son los casos específicos de MSN, Jabbery LAN Messenger de Softros), sin embargo ningunode estos resuelve completamente el problema de tenerlos miembros de una institución comunicados de for-ma estable y factible.
Por otra parte las políticas de confidencialidad yseguridad propias de cada institución pueden res-tringir o prohibir el uso de estos sistemas de comu-nicación que tienen base en el exterior de la institu-ción. Incluso una institución puede no dar serviciode acceso a Internet pero tener necesidad de comu-nicación interna entre sus miembros para agilizar eltrabajo y mejorar el rendimiento.
En este trabajo se presenta un sistema de mensa-jería (WEBOO Messenger) implementado sobre laplataforma PON (P2P Over .NET)1
PON, la plataforma
La presencia de una plataforma de comunicaciónes imprescindible para la creación de cualquier mode-lo de intercambio de información por redes. Dichaplataforma deberá proveer a los desarrolladores decierta abstracción de los procesos que tienen lugaren las capas más bajas, así como de una interfaz ami-gable, un modelo lógico para la implementación deaplicaciones, y extensibilidad para crear diferentestipos de aplicaciones.
PON es una plataforma de comunicación imple-mentada sobre .NET Framework 1.1, que reúne estosrequisitos, y además ofrece ciertos extras, entre los quese encuentra el hecho de haber sido modelada paracrear redes P2P, de forma descentralizada siguiendoel esquema de un “Modelo de Red P2P Puro” perocon ciertas funcionalidades adicionales.
El modelo de PONPON está basado en un modelo P2P puro que
incluye además las siguientes características para sermás distribuido, independiente y robusto. Algunosde los cambios hechos son los siguientes:
1. Todos los nodos de PON son Servents, es decir,servidores y clientes a la vez.
2. No hay conexiones forzadas. Dos nodos no tie-nen que conectarse entre sí para intercambiarinformación sino que ésta puede viajar por unacadena de nodos intermedios, siguiendo el cami-
dotN
etM
anía
<<
17
Weboo Messenger Un sistema de mensajería distribuido sobre .NET
Si bien el correo electrónico es un servicio de comunicación ampliamente utili-zado, es un mecanismo pasivo y relativamente lento cuando se quiere establecerun diálogo y una comunicación más cercana al tiempo real. Es por ello que millo-nes de personas en todo el mundo utilizan sistemas de comunicación instantánea,incluso haciendo uso de transmisión de voz y video sobre la red.
<<
Leonardo Paneque
dnm.plataforma.net
Las redes
Leonardo PanequeEs estudiante del Departamento
de Ciencia de la Computación dela Universidad de La Habana y
programador y administrador dela red del grupo WEBOO.Paneque es un entusiastadesarrollador de sistemasdistribuidos y redes P2P.
Miguel KatribEs Dr. y Catedrático del Depar-
tamento de Ciencia de laComputación de la Universidad
de La Habana y jefe del grupoWEBOO.Es un especialista en
lenguajes de programación yentusiasta de la tecnología .NET y
el lenguaje C#.
Miguel Katrib
1 Ver artículo de los mismos autores de este trabajo publicado en dotNetManía [7]
no más corto en términos de velo-cidad de transmisión existente entreambos nodos.
3. Los mensajes en PON son objetos.NET. Esto permite encapsular enun mensaje no solo informacióndescriptiva sino también funciona-lidad en los protocolos a imple-mentar y utilizar.
4. El traspaso de objetos como men-sajes combinados con el uso de cua-lidades de .NET como son la refle-xión y el “nombrado fuerte” (strongname), hacen posible implementarla interacción y cooperación entreaplicaciones distintas.
Weboo Messenger,elMensajero
La aplicación WebOO Messenger[12]se implementó para dar solución a lasnecesidades de mensajería instantánea enredes empresariales de manera eficiente.Pero,… ¿por qué no utilizar alguno delos sistemas ya establecidos? Para dar res-puesta a esto veamos a continuación lasprincipales características de los sistemasde mensajería instantánea actuales paraposteriormente exponer las nuevas carac-terísticas que aporta WebOO Messenger.
Yahoo Messenger
Usar un sistema de mensajería comoYahoo! Messenger para la comunicacióndentro de una red de una empresa pre-senta los siguientes inconvenientes:
1. Consumo innecesario del anchode banda disponible de conexióna Internet.
2. La calidad e integridad de la comu-nicación interna del sistema estaríacomprometida por la estabilidad dela conectividad a Internet.
3. Se subutilizarían las capacidadeslocales de la red.
MSN y Jabber
Algunos sistemas existentes son adap-tables a las condiciones de una empresa,y ofrecen soluciones para el uso internoen compañías. Las dos opciones más cono-cidas son MSN Messenger o Jabber.
MSN Messenger es la aplicación demensajería instantánea del sistema ope-rativo Windows, dicho programa sepuede configurar a integrar a una redWindows con un servidor MicrosoftExchange, teniendo de forma integra-da correo, mensajería, calendarios yotras funcionalidades. Sin embargo, suutilización presenta los siguientes incon-venientes:
1. Necesidad y Dependencia de servi-dores.
2. Instalación de un servidor Exchange(aún cuando Microsoft Exchangees un buen servidor debe conside-rarse que la empresa u organizaciónpuede tener ya su servidor de correoen otra plataforma o software.)
3. Tráfico centralizado. Todo el tráfi-co necesita pasar por los servido-res lo que puede comprometerinnecesariamente la calidad de lacomunicación.
Jabber es una excelente propuestapor su arquitectura, su protocolo abier-to y cientos de clientes disponibles. Sinembargo, Jabber necesita de servidores(aún cuando muchos declaran queJabber es de arquitectura distribuida y
descentralizada, no lo es en realidad, sumodelo resulta ser articulado, teniendoservidores que cooperan entre sí, peroque son imprescindibles para los clien-tes). Es por ello que en Jabber el tráfi-co es centralizado y al igual que en MSNMessenger toda la información entreclientes viaja por los servidores, pudien-do sobrecargarlos en caso de tener unnúmero grande de clientes activos.
La figura 1 nos ilustra un ejemplode las redes de dos empresas A y B quese encuentran conectadas con un siste-ma como Jabber.
Los clientes de la A podrían inter-cambiar información con los de la B, perosi uno de los dos servidores saliera de ser-vicio, dado que Jabber no es realmentedescentralizado sucedería lo siguiente:
1. Los clientes de la red que perdiósu servidor Jabber quedarían inco-municados.
2. Los clientes de la red que perma-nece activa no podrían comunicar-se con los clientes de la otra red.
Weboo Messenger ofrece completalibertad de conexión entre nodos asícomo independencia de servidores.
Figura 1.Modelo hipotético de mensajería basada en Jabber entre dos empresas A y B
<<dnm.plataforma.net
18
<<do
tNet
Man
ía
<<dnm.plataforma.net
19
<<do
tNet
Man
ía
Arquitectura de WebOO Messenger
Este mensajero ofrece las funcionali-dades básicas de un mensajero común,pero su funcionamiento a bajo nivel, escompletamente diferente al de las arqui-tecturas mencionadas porque no exige deservidores. El uso opcional de servidoresen Weboo Messenger es solo para brin-dar funcionalidades de encuentro (disco-very server) y autenticación.
Los servicios de autenticación yencuentro están implementados comocapa de servicios Web utilizandoASP.NET, y aunque son entidades inde-pendientes de la arquitectura, pudieranencontrarse en la misma ubicación física.El gestor de bases de datos utilizado parael servicio de autenticación ha sidoMicrosoft SQL Server 2000.
La arquitectura se ilustra en la figura2. Note que la capa intermedia basada enservicios Web hace posible que la imple-mentación de ambos servidores de auten-ticación y encuentro use otra tecnologíano .NET, simplemente cumpliendo conel WSDL2 de ambos servicios.
El tráfico de información no pasapor los servidores, sino directamenteentre los nodos de la red PON.
La forma clásica de un Mensajero alestilo MSN o Yahoo! se ilustra en lafigura 3.
La arquitectura de Weboo Messen-ger (figura 4) permite la transmisión dedatos directamente entre los nodos sinpasar por el servidor.
La autenticación es opcional, solonecesaria si el usuario quiere tenerfuncionalidades como lista de contac-tos, y detalles de su perfil (fotos y otros
datos), los cuales son almacenados enel servidor de autenticación. Por otraparte, el servidor de encuentro tam-bién es opcional, de no existir servi-
dor de encuentro PON busca losnodos de la red mediante difusión(broadcasting). También es posible abriruna conexión directa de forma explí-cita a cualquier nodo del que se conoz-ca su IP.
Weboo Messenger está diseñadoentonces como un Sistema de Men-sajería Instantánea de Tráfico Descen-tralizado, que al estar implementadousando PON como plataforma decomunicación disfruta de cualidadesque no están presentes en los otros sis-temas mencionados:
1. Tráfico descentralizado. No hay trá-fico de datos en los servidores.
2. Enrutamiento de mensajes den-tro de la red de nodos, evitandoque para intercambiar datos losnodos tengan que conectarsedirectamente.
3. Recuperación ante fallas paragarantizar la conectividad de lared.
Detalles de Implementación
Para la implementación de WebooMessenger sobre PON se ha diseñado el
Figura 2.Modelo de Capas de Weboo Messenger
Figura 3. Esquema clásico de sistemas de mensajería
Figura 4. Esquema de Weboo Messenger
2 WSDL: siglas en inglés de Web Service Description Language.
mensajero modularmente, separan-do la interfaz grafica del motorprincipal, este motor principalimplementa toda la funcionali-
dad (API) del mensajero y utili-za PON para la transmisión deinformación. Las principalesclases son WebooMessengerUser,
WebooIMEngine, WebooConferencey VisibilityManager.
WebooMessengerUser
Identifica a un usuario dentro del la red de nodosPON del mensajero, como estructura contiene losdatos que identifican al usuario en el mensajero.
WebooIMEngine
Es el núcleo del mensajero, es construido a partirde un nodo PON instanciado. Ofrece eventos a loscuales el cliente se puede anotar para manejar los men-sajes recibidos por el mensajero, además de ofrecer elAPI básico, como enviar mensajes, crear conferencias,consultar si un usuario determinado esta en línea ono. En el siguiente ejemplo:
WebooConference
Las conferencias en los mensajeros existentes sonpor lo general manejadas siguiendo un modelo clien-te-servidor. En Weboo Messenger están basado enPON y por tanto son completamente descentraliza-das. De modo que si un grupo de usuarios de la reddesean hacer conferencias, uno cualquiera de ellospodrá hacer de una suerte de “servidor de la confe-rencia”, éste será a la vez el administrador de la con-ferencia, y será quien podrá invitar personas a la con-ferencia o expulsar a quien desee. En el siguiente frag-mento de código:
Se crea un motor del mensajero, a través de éstese crea una conferencia y luego envía una invitaciónal usuario “Juan”.
VisibilityManager
Esta clase ayuda a cada nodo del mensajero amanejar sus opciones de visibilidad mediante lasiguiente interfaz:
Un usuario puede poner su estado en visible o invi-sible, pero esto se ignora si especificó de forma expli-cita si desea aparecer “SIEMPRE INVISIBLE” o“SIEMPRE VISIBLE” a otro determinado usuario.En caso de aparecer visible podría mostrarse un esta-do como: “Salí a comer”, “Al teléfono” y otros, espe-cificados en la propiedad CurrentState.
En envío de ficheros
Adicionalmente se utiliza en la implementación delnúcleo del mensajero la librería FileTransportEngine,para el envío de archivos entreusuarios del mensajero. Estalibrería fue programada sobrePON, y es indepen-diente del men-sajero; su únicafunción es en-viar archivos deforma explícitade un nodoPON a otroindependiente-mente del usoque se le de adicho nodo.
dotN
etM
anía
<<
20
dnm.plataforma.net<<
WebooIMEngine engine = new WebooIMEngine(…);engine.Start();if (engine.IsOnline("juan"))
engine.SendPrivateMessage("juan", "¿qué tal colega?");
Fuente 2
WebooIMEngine engine = new WebooIMEngine(…);WebooConference conf = engine.CreateConference("Reunion");conf.InviteUser("Juan", "Unete a mi conferencia");
Fuente 3
public class VisiblityManager{
public bool Visible{get;set}public string CurrentState {get;set}public bool VisibleTo(string alias){}public void MakeMeAlwaysVisibleTo(string alias){}public void MakeMeAlwaysInvisibleTo(string alias){}public void ResetCustomVisibilityTo(string alias){}public bool AlwaysVisibleTo(string alias){}public bool AlwaysInvisibleTo(string alias){}
}
Fuente 4
public class WebooMessengerUser{
public string Alias;public string eMail;public string Name;public string FirstLastName;public string LastName;public string Description;public string NodeName;public Hashtable ExtraInformation;...
}
Fuente 1
Interfaz Cliente de WebooMessenger
Weboo Messenger ofrece una fun-cional interfaz (figura 5) al estilo XP. Lasección en el rectángulo verde indicadocon 1 contiene un menú y una barra deherramientas, permitiendo acceso rápidoy redundante a las opciones del sistema.
La sección 2 (dentro del rectánguloen rojo) es una barra exploradora que con-tiene dos hojas principales, “Chat” y“Configurar”, para acceso rápido a lasopciones mostradas. Weboo Messengeres abierto; a este explorador se le puedeagregar hojas mediante la implementa-ción de addins. Por ejemplo, la aplicaciónWeboo Share It3 para el intercambio dearchivos, cuya funcionalidad es similar asistemas de intercambio P2P como eMule,Kazaa y otros, ha sido incorporada comoaddin dentro de Weboo Messenger.
El rectángulo indicado en verde, conel número 3, nos muestra el panel prin-cipal en el que se muestran diferenteshojas de contenido y funcionalidad (enla figura se muestra la lista de amigos).
Algunas de estas hojas y opcionesestán deshabilitadas cuando el sistemano usa servidor. Tal es el caso de la lis-ta de amigos, los datos del perfil, cam-biar contraseña y otras.
Iniciando sesión
La decisión de utilizar el sistema cono sin servidor de autenticación, debe sertomada por el usuario de la aplicacióna través de la ventana de inicio de sesión,simplemente desactivando o activandola opción “No usar servidor (anónimo)”tal como muestra la figura 6. Si el usua-rio selecciona iniciar sesión de forma
anónima, el nombre que se utilizará paraidentificar4 al usuario será “<userna-me>@<hostname>”.
Una vez iniciado el sistema en cual-quiera de los modos, se intentará acce-der a servidores de encuentro disponi-bles, pero en caso de no existir ningunoel sistema continuará funcionando.
Abriendo conexiones
El cliente también podrá abrir cone-xiones directas utilizando la ventana delmismo nombre (figura 7), accesible des-de el menú (“Opciones/Abrir Conexión”)y la barra de herramientas (primer icono).
Puesto que dentro de una empresa uorganización es común el hecho de queciertas personas utilicen siempre un mis-mo ordenador, es conveniente entoncespoder especificar una lista de direccioneshacia las cuales abrir conexiones de for-ma automática una vez que inicia WebooMessenger. Por esto se puede configuraruna lista de direcciones IP predetermina-da (figura 8).
Funcionalidades
La lista de funcionalidades varíadependiendo de si se dispone o node un servidor, pero la diferencia estásolo en lo referente al acceso a infor-mación descriptiva que puede alma-cenarse en los servidores. Esta infor-mación claro está que ayuda a darfacilidades en el uso de la mensaje-ría, pero que no limita las posibili-dades de comunicación cuando seopera sin servidores. De entre lasfuncionalidades se pueden citar:
1. Chat Privado (conversaciones1 a 1).
2. Conferencias (conversacionescon más de 2 personas).
3. Soporte para iconos gestuales,sonidos, audibles, texto enri-quecido etc.
4. Transferencia de archivos.5. Visibilidad y lista de estados
personalizada (especificaciónde cómo queremos que nos veaun determinado usuario).
6. Lista de contactos (requiereservidor).
7. Perfil de usuario (requiere ser-vidor).
8. Búsqueda de usuarios en línea(se realiza a través de la redPON, no requiere servidor, ysólo se ve afectada por las pre-ferencias de visibilidad, esdecir, usted no verá en línea alusuario que decidió estar invi-sible a usted).
9. Mecanismo de addins.10 .Distribución de addins por la
red PON.
No se han listado aquí otras opcio-nes y/o facilidades que son parte de lasopciones de configuración.
De esta forma el mensajero proveede las funcionalidades que garantizancompleta comunicación dentro de redesLAN, o a través de la Web, de formacompletamente autónoma, permitiendoa sus clientes conversar en pareja o gru-pos y enviarse archivos de cualquier tipoy tamaño. A su vez, Weboo Messengersirve de anfitrión a otras aplicacionesbasadas en PON, que solo tienen queimplementarse o adaptarse como addinsdel mensajero.
dotN
etM
anía
<<
21
dnm.plataforma.net<<
Figura 5.Ventana principal de Weboo Messenger
Figura 6.Ventanas de inicio de sesión en ambos modos.
Figura 7.Ventana de conexión directa
Figura 8. Lista de Direcciones IP
3 Implementado también por el grupo WEBOO4 El nombre de usuario o "login" utilizado es independiente del usado físicamente por PON,de esta forma es posible tener infinidad de usuarios con el mismo nombre en
el sistema sin causar problema alguno.
Extensibilidad y distribución de addins
Para hacer Weboo Messenger más extensible se leha incorporado un mecanismo de extras (addins), el cualpermite agregar funcionalidades al sistema. Dicho mode-lo de extensibilidad convierte al mensajero en un anfi-trión de aplicaciones PON, ya que prácticamente cual-quier aplicación PON puede ser adaptada a funcionarcomo parte del mensajero e interactuar con éste.
El mecanismo para la creación de addins es en esen-cia sencillo y consiste en implementar una interfaz .NETque permita al mensajero extraer, mediante ingenieríainversa (reflection), información de los ensamblados deladdin e instalarlos en el ordenador5.
En otras aplicaciones, específicamente aquellas quesoportan addins, la vía más común de distribuir los addinsconsiste en publicar estos en un sitio Web, normalmen-te el sitio Web de la organización que programó la apli-cación. Incluyendo mecanismos en las aplicaciones paraque detecten la existencia de estos addins en el servidorasí como nuevas versiones, actualizaciones, noticias etc.Aunque este mecanismo es factible, su inconveniente esque se consume ancho de banda tanto del cliente comodel creador de la aplicación para el trasiego de estos addins.
En Weboo Messenger esto es diferente. Si bien sepermite utilizar el mecanismo clásico, pudiendo publi-car los addins en servidores FTP o Web, se explotan lascapacidades de distribución de datos de la plataformaPON haciendo posible que los clientes del mensajeroque ya tengan algún conjunto determinado de addins,los compartan con el resto, por lo que la propagación denuevas herramientas para el mensajero se hace de for-ma automática, solo bastará que un grupo pequeño des-cargue estos addins y los instale para que el resto de lared se pueda beneficiar de ellos. Por razones de seguri-dad, la instalación de los addins es una acción volunta-ria y explícita de los usuarios del sistema.
También se ofrecen las bibliotecas de extensibilidaddel mensajero, para que los clientes que sean a su vez desa-rrolladores .NET puedan programar sus propios addinsy que estos se puedan distribuir de forma espontánea,permitiendo ampliar las capacidades y funcionalidadesexistentes en la red de nodos de Weboo Messenger.
Un ejemplo de addin representativo es el menciona-do Weboo Share It, una aplicación desarrollada sobre
PON que posibilita que los usuarios no solo puedan con-versar o hacer conferencias entre ellos sino también com-partir de forma explicita películas, música, documentos,y software en sentido general.
ConclusionesEl sistema de mensajería instantánea presentado posi-
bilita libertad de comunicación entre usuarios de redesLAN (incluso Internet), permitiendo comunicarse entreellos de forma directa sin necesidad de utilizar softwarede terceros proveedores y aun así mantener facilidadescomo chat privado, conferencias e intercambio de archi-vos de forma rápida y eficiente.
No se exige disponer de servidores por lo que laconectividad depende solo de la conexidad de la red, bas-tará con que dos nodos en dos redes diferentes se conec-ten para que ambas partes queden totalmente conecta-das a través del mensajero.
Solo se exige tener instalado .NET Framework 1.1[13] o superior e instalar Weboo Messenger que está dis-ponible a los lectores de dotNetManía.
Actualmente se trabaja en la creación de nuevos addinspara el sistema, como la transmisión de vídeo y sonidopor la red utilizando estándares de comunicación comoH323, así como en la integración con un mecanismopara la localización de la interfaz a diferentes idiomas.
Los lectores pueden descargarse libremente la apli-cación Weboo Messenger, incluido el código fuente, enel sitio de dotNetManía (http://www.dotnetmania.com/arti-culos/024/apoyo/WebOOmessenger.zip)
dotN
etM
anía
<<
22
dnm.plataforma.net<<
Referencias
[1] IRC, http://www.irc.org
[2] MSN Messenger, http://messenger.msn.com
[3] Yahoo! Messenger, http://messenger.yahoo.com
[4] ICQ, http://www.icq.com
[5] Jabber, http://www.jabber.org
[6] GoogleTalk, http://www.google.com/talk
[7] Paneque L, Katrib M, “PON: P2P Over .NET”dotNetManía nº 13, Marzo 2005, España. ISSN 1698-5451
[8] Napster, http://www.napster.com
[9] Kazaa, http://www.kazaa.com
[10] eMule, http://www.emule-project.net, http://www.emule.com
[11] Gnutella, http://www.gnutella.com
[12] WebOO Messenger, http://www.dotnetmania.com/articu-los/024/apoyo/WebOOmessenger.zip
[13] CLR: Common Language Runtime, http://www.microsoft.com/downloads
Los lectores pueden descargarse libremente la aplicación Weboo Messenger, incluido el código
fuente, en el sitio de dotNetManía (http://www.dotnet-mania.com/articulos/024/apoyo/WebOOmessenger.zip)
5 Por cuestiones de seguridad y características de la carga de ensamblados del CLR[13] (Common Language Runtime) de .NET, es recomendableinstalar estos ensamblados en ubicaciones hijas de la del mensajero en lugar de ponerlos en ubicaciones arbitrarias.
Programación eficiente de dispositivos móviles con Visual Studio 2005
Desarrollar aplicaciones eficientes para dispositivos móviles es realmente com-plicado. El reducido tamaño de los dispositivos y sus limitados recursos produ-cen vértigo hasta en el programador más experimentado. En las siguientes pági-nas daremos unas pautas básicas para que las aplicaciones desarrolladas bajo esteentorno tengan un rendimiento óptimo.
<< aplicación para un dispositivo móvil no es tareafácil. Cuando comenzamos el desarrollo de este tipode aplicaciones corremos el riesgo de subestimar ladificultad que entrañan. No se trata solo de que nues-tra aplicación funcione, sino además que lo haga deforma óptima.
Seguramente pensaremos: ¡Si tan solo es necesariodesarrollar unos pocos formularios! ¡Si la base de datoscontiene muchas menos tablas y campos que nuestraaplicación de escritorio! ¡Si además los dispositivos móvi-les son dispositivos monousuarios y por tanto no debe-mos preocuparnos por el control de concurrencia! Enfin, podríamos continuar con otras muchas afirmacio-nes, tan ciertas, como ingénuas al mismo tiempo.
Lo realmente cierto, es que el desarrollo de apli-caciones móviles requiere una formación específica,que difiere bastante de nuestros conocimientos en laprogramación de aplicaciones de escritorio, por muyexpertos que nos consideremos.
¿Y cuál es la causa de esta dificultad? Existen doselementos principales:
• Los recursos limitados del dispositivo. Por sus pecu-liares características debemos orientar nuestraprogramación a manejar eficientemente cada unode los recursos. Contamos con limitaciones entodos los aspectos: visualización de los formula-rios en la parte gráfica, escasa memoria, y ridí-cula velocidad de procesador. Todo ello compa-rado con un PC de escritorio. Así pues, no sólodebemos pensar en qué vamos a desarrollar, sinotambién en cómo lo vamos a hacer para que elusuario final no se impaciente trabajando connuestra aplicación.
• Las carencias inherentes a Compact Framework. Unade las primeras cosas con las que nos encontra-mos a la hora de programar, es que muchas delas características que posee .NET Frameworkbrillan por su ausencia en su hermano pequeño,el Compact Framework. Afortunadamentemuchas de estas características se han incorpo-rado en la nueva versión 2.0 con Visual Studio2005. Ciertamente, con la llegada de VisualStudio 2005 resulta más sencillo la programa-ción de los dispositivos móviles.
En este artículo, como indica su título, nos cen-traremos en el desarrollo de aplicaciones móviles queusen de forma eficiente cada uno de los limitadosrecursos de nuestro dispositivo.
Se verán aspectos fundamentales en la elaboraciónde una aplicación y consejos en la utilización de deter-minadas instrucciones y estructuras de CompactFramework.
Le aconsejo que descargue el material de apo-yo que acompaña este artículo de www.dotnetma-nia.com para una mejor comprensión de los con-ceptos que aquí se explican.
Optimizando el interfaz de usuario:Construyendo el Framework de nuestraaplicación
Lo primero que tenemos que plantear a la horade comenzar nuestra aplicación, es la construcciónde un framework totalmente orientado a mejorar su
Desarrollar una
Antonio de Rojas
dnm.movilidad
Antonio de Rojas ejerce su labor profesional en
Clave Informática S.L., comoresponsable de un grupo deprogramación. Es Ingeniero
Superior en Informática yMCP en SQL Server
y Visual Basic .Net
rendimiento además de facilitarnos undesarrollo claro y de fácil evolución.
La construcción de este frameworkse fundamentará en dos pilares básicosque paso a explicar a continuación:• Por una parte haremos subclassing de
la clase formulario de .NET para dar-le toda la funcionalidad que necesita-remos en el desarrollo de cada una laspantallas de nuestra aplicación, con lamente siempre puesta en la optimiza-ción de su funcionamiento. Además,como veremos, la llegada de VisualStudio 2005 nos brinda la gran facili-dad de aplicar la herencia de formatotalmente visual.
• El otro elemento principal de este fra-mework que contribuirá a mejorar con-siderablemente el rendimiento denuestra aplicación es la construcciónde un contenedor multi-formulario,de tal forma que permita la reutiliza-ción de los mismos cuando previa-mente el usuario de nuestra aplicaciónlos haya abierto para su uso. En defi-nitiva, se trata de emular un sistemaclásico de ventanas en un entorno don-de originalmente no es posible. Elusuario final notará la carga inicial delformulario la primera vez que lo use,pero a partir de ese momento el acce-so a esos mismos formularios será total-mente inmediato.
La genial idea de construir este siste-ma se debe a Chris Tacke, MVP enCompact Framework), elaborada en el artí-culo “Creating a Multiple FormApplication Framework for the Microsoft.NET Compact Framework”(ver el enla-ce al final del artículo).
En este artículo básicamente utili-zaré la misma estructura descrita porTacke, aunque he efectuado algunasmodificaciones, principalmente con elfin de aprovechar las facilidades en laherencia visual de los formularios que
he descrito en el puntoanterior, además de intro-ducir una importante modi-ficación que nos brindarárealmente la posibilidad deacceder al clásico menú“Ventana” para seleccionarcualquier formulario pre-viamente abierto.
Una vez explicadas las premisasprincipales comenzamos el desarrollodel framework.
Nuestra clase base formulario
Con Visual Studio 2005 se nos abreuna importante puerta para poder rea-lizar formularios de forma más óptimay sencilla que en versiones anteriores.En esta versión vamos a tener la posi-bilidad de aplicar la herencia, y ver losresultados de forma visual, facilitán-donos de esta forma la creación de unframework que nos permita trabajarcómodamente con cada una de las dife-rentes pantallas que tengamos que dise-ñar en nuestra aplicación. Podemos deesta forma crearnos un formulario basecon aquellos controles que van a sercomunes al resto de nuestros formula-rios, como, por ejemplo, la toolbar, ade-más de todos los métodos y su códigoasociado.
En este caso y como nuestro objetivoes mejorar el rendimiento de carga denuestros formularios y de forma añadidamejorar la percepción que el usuario denuestra aplicación va a tener del tiempotranscurrido en acceder por primera veza la opción de programa y tener dichaopción disponible para operar con ella,nos centraremos en el diseño de las carac-terísticas esenciales para logarlo.
En el fuente 1 se muestra aquella par-te de nuestro formulario base, FormBase,expresamente destinada a mejorar la car-ga de cada uno de nuestros formularios.
Y en el fuente 2 se lista la parte del códi-go empleado en cada uno de los formu-larios que vayamos a heredar de nuestroFormBase, y que corresponde al fichero decódigo <Miformulario>.Designer.vb, queautomáticamente crea Visual Studio 2005y que hemos modificado para aplicar laherencia.
La figura 1 muestra gráficamentecómo será el proceso de carga de nues-tro formulario.
Paso a explicar los entresijos deldesarrollo expuesto en los fuentes 1 y 2,para lo que el lector me va a permitirque vaya intercalando la explicación delcódigo de ambos fuentes.
En el fuente 2 se muestra el códigobásico para crear cada uno de nuestrosformularios a partir de nuestro formu-lario base FormBase:
• Con la llegada de Visual Studio2005 se introduce el concepto declases parciales, como la posibilidad
dotN
etM
anía
<<
25
dnm.movilidad<<
Con Visual Studio 2005 se nos abre una importantepuerta para poder realizar formularios de formamás óptima y sencilla que en versiones anteriores
Figura 1. Funcionamiento del Formulario Base
En el blog del equipo de desarrollo del .NET Compact Framework deMicrosoft (http://blogs.msdn.com/netcfteam),aparece una estupenda entra-da (como no podía ser de otra forma viniendo de sus creadores),acer-ca de algunos consejos para mejorar el rendimiento de nuestras apli-caciones con Compact Framework 2.0. En dicha entrada, se describeclaramente que el uso de llamadas virtuales son alrededor de un 40%más lentas que las llamadas a métodos estáticos o de instancia.Realmentees una cuestión totalmente lógica, teniendo en cuenta que interpretaruna llamada virtual supone buscarla en la jerarquía de llamadas de laclase,y esto es más lento que localizarla directamente en la tabla inde-xada vtable,que el compilador crea inicialmente.Como comenta el mis-mo documento cuando una llamada virtual es resuelta se almacena enuna caché que consta de un tamaño fijo y que ha sido mejorada sus-tancialmente con Compact Framework 2.0, beneficiándonos por tan-to en subsiguientes llamadas. En general debemos evitar llamadas vir-tuales innecesarias,e intentar agruparlas en la medida en que sea posi-ble en una sola con el fin de evitar demasiada sobrecarga. No obstan-te,bajo mi opinión y como el mismo equipo de desarrollo de CompactFramework declara, no debemos diseñar malas aplicaciones desde elpunto de vista arquitectónico con el fin de evitar las llamadas virtuales.
Uso de los métodos sobrescribibles (Overridables)
de dividir el contenido de una clase en variosarchivos de código. Este mismo concepto, VisualStudio lo aplica a la construcción de formularios,creando dos archivos: <Miformulario>.desig-ner.vb, que contiene todo el código creado auto-máticamente para mostrar toda la interfaz de usua-rio, y <Miformulario>.vb que albergará el códi-go que nosotros incorporemos para la funciona-lidad del formulario.Inicialmente modificaremos el archivoMiformulario.designer.vb para cambiar la cláu-sula: Inherits System.Windows.Forms.Form por:Inherits FormBase.Con ello ya hemos conseguido incorporar todala funcionalidad de nuestro formulario base enel que estamos creando.
• Creamos el método New en nuestro formulario,que consta de los siguientes pasos: la llamadaal método Antes_New que inicia varias opera-ciones, entre ellas la carga de datos a ser mos-trados, la propia llamada al método InitializeComponent para mostrar los controles de esteformulario, y la activación de un timer, que nospermitirá la finalización de operaciones parapoder mostrar la interfaz de usuario prepara-da para ser totalmente operativa.
Veamos ahora con detenimiento la funcionalidaddel método Antes_New y del timer, cuyo código estáestrictamente detallado en el código del fuente 1, ypor tanto originario de nuestro FormBase. Todos losprocesos que realizamos al ejecutarse el código delmétodo Antes_New son los siguientes:
• Se activa el cursor en formato de espera. Unpequeño detalle, pero de gran importancia siqueremos indicarle de forma clara al usuariofinal que la aplicación está en el proceso de car-ga del formulario.
• Se crea un manejador para el evento Tick de nues-tro timer oTimer y se indica que éste entrará enfuncionamiento al milisegundo de activarse. Eltimer se activará tras la llamada a InitializeComponents de cada uno de los formularios quecreemos, tal y como se ha explicado anteriormente,y su principal utilidad es la de permitir la visuali-zación de la interfaz de usuario, antes de conti-nuar con el resto de operaciones necesarias paradejar el formulario operativo. Al fin y al cabo, noes más que un truco para que el usuario pueda verel contenido de la pantalla a utilizar antes que real-mente pueda llegar a usarla.
• Se llama al método DataThread. Este métodointroduce un aspecto de vital importancia paramejorar la carga de nuestro formulario: la cre-ación del thread oHebra, que se encargará de lacarga de datos a manipular en el formulario.El método empleado para ello, y que deberemos
dotN
etM
anía
<<
26
dnm.movilidad<<
Imports System.XmlImports System.Threading
Public Class FormBase#Region “ Propiedades “‘ Delegado para cerra el formulario.Public Event FormClose()
‘ Objeto Binding de los controles de la pantalla.Protected oBMB As BindingManagerBase
‘ Tabla a manipular en el formulario.Protected dtTabla As DataTable
‘ Propiedad para el nuevo Thread.Protected oHebra As Thread
‘ Timer para arrancar el Binding de los objetos.Protected oTimer As New System.Windows.Forms.Timer()
#End Region
#Region “ Optimización Presentación Formulario “‘ HAY QUE COPIARLO EN CADA NUEVO FORMULARIO.‘ Operaciones para el Contructor del Formulario.Protected Sub Antes_New()
‘ Cursor de Espera.Cursor.Current = Cursors.WaitCursor
‘ Manejador del timer.AddHandler oTimer.Tick, AddressOf oTimer_TickoTimer.Interval = 100 ‘ 1 ms.
‘ Carga de los datos iniciales.Me.DataThread()
End Sub
‘ Creación de la Hebra para la carga de datos.Protected Overridable Sub DataThread()
oHebra = New Thread(AddressOf CargarDatos)oHebra.Start()
End Sub
‘ Carga los datos del mantenimiento desde un nuevo Thread.Protected Overridable Sub CargarDatos()End Sub
‘ Activa el Timer para la ejecución de los Bindings.Protected Sub oTimer_Tick(ByVal Sender As Object, ByVal e As EventArgs)
oTimer.Enabled = FalseMe.Despues_New()
End Sub
Protected Sub Despues_New()‘ Esperar finalización de la carga de datos.oHebra.Join()oHebra = Nothing
‘ Binding de los controles.Me.BindingControles()
‘ Refrescar Controles para habilitar/deshabilitar según situación‘ del registro inicial.Me.HabilitarControles()
‘ Cursor Normal.Cursor.Current = Cursors.Default
End Sub
Fuente 1. El formulario Base (continúa...)
codificar en nuestro formulario, según nuestrasnecesidades, lo hemos llamado CargarDatos.El principal objetivo para la creación de este thre-ad es la de ejecutar paralelamente la carga de loscontroles del formulario, y por otro lado la de losdatos a manipular en dicho formulario. Los aspec-tos referidos a la carga de datos los trataremos enel apartado “Optimizando la manipulación dedatos con SQL Server Mobile”.
Como hemos comentado, tras la llamada al méto-do InitializeComponents, que crea todos los contro-les de la pantalla, se activa el timer y por consiguien-te su evento Tick.
En nuestro FormBase el manejador de dicho even-to será el método oTimer_Tick, cuya principal finali-dad será de la de finalizar algunas cuestiones básicasacerca de la presentación de nuestro formulario porpantalla. Éstas son:
• Esperamos a que finalice el thread de la cargade datos.
• Llamamos al método BindingControles que seencargará de enlazar nuestros datos, posiblementeen un DataSet, con los controles en pantalla.
• Por último podemos llamar al métodoHabilitarControles, que nos permitirá encada formulario activar o desactivar los con-troles del formulario en función de los datoscargados o de la operación que en esemomento estemos realizando (añadir, borrar,modificar datos, etc.)
En resumen, con la construcción de nuestra cla-se base FormBase preparamos un marco de trabajo idó-neo para optimizar la presentación de nuestro for-mulario y los datos a manipular.
Tenemos que tener también en mente el no sobre-cargar en demasía nuestros formularios con excesi-vos controles, puesto que en ese caso la carga de lainterfaz será totalmente desesperante, así como evi-tar la carga de demasiadas estructuras de datos (variosDataSets o DataReader por ejemplo), que igualmen-te penalizarán gravemente la carga inicial.
dotN
etM
anía
<<
27
dnm.movilidad<<
‘ Binding de los controles del formulario.Protected Overridable Sub BindingControles()End Sub
‘ Se codificaría en cada formulario.Protected Overridable Sub HabilitarControles(ByVal pControl As Control)
End Sub
#End Region
#Region “ Métodos básicos para la creación del sistem multi-formulario “‘ Para controlar el evento de cerrar el formulario, puesto que realmenteno se cerrará‘ definitivamente.Private Sub FormBase_Closing(ByVal sender As Object,
ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.ClosingMe.Visible = Falsee.Cancel = TrueRaiseEvent FormClose()
End Sub
‘ Operaciones personalizadas a realizar cuando se ective el formulario‘ desde el menú Ventana.Protected Overridable Sub OperacionesActivaFormularioEnd Sub
‘ Operaciones a realizar para recargar o refrescar algunos controles del‘ formulario al activarse de nuevo.Public Sub ActivarFormularioEnd Sub#End Region
#Region “ Métodos Comunes a todos nuestros formularios “‘ Aquí codificaríamos los métodos comunes en todos nuestros formularios.#End Region
End Class
Partial Public Class FrmActividadesInherits FormBasePublic Sub New()
MyBase.New()
Me.Antes_New()
‘ LLama inicial a los componentes de los formularios.Me.InitializeComponent()
‘ Enable timer.oTimer.Enabled = True
‘TODO: Add any initialization after the InitializeComponent() callEnd Sub
<System.Diagnostics.DebuggerStepThrough()> _Private Sub InitializeComponent()
‘Aquí iría el código que Visual Studio crea para mostrar ‘nuestros controles
End Sub
‘Resto de código que Visual Studio crea de forma automática.End Class
(...continuación) Fuente 1. El formulario Base
Fuente 2. El cógigo de nuestro formulario de trabajo.
Tenemos que tener también en menteel no sobrecargar en demasía nuestrosformularios con excesivos controles,puesto que en ese caso la carga de lainterfaz será totalmente desesperante
En el apartado “Optimizando formularios conmuchos controles” daremos algunas pistas para mejo-rar el rendimiento de este tipo de formularios.
Emulando un sistema multiformulario
Una vez creado el esqueleto de nuestro formula-rio base, del cual heredarán el resto de formulariosde nuestra aplicación, el siguiente paso para la crea-ción de nuestro framework es la elaboración de unaserie de estructuras que nos posibiliten el manteni-miento de un sistema multiformulario. Con ellopodremos emular el funcionamiento tradicional deuna aplicación típica de escritorio en Windows, consu correspondiente menú “Ventana” que nos permi-ta recuperar en todo momento cualquiera de las pan-tallas abiertas durante nuestra sesión de trabajo. Setrata en esencia de guardar una caché de cada unosde los formularios visitados por el usuario.
Como mencioné anteriormente este sistema sebasa en el desarrollo realizado por Chris Tacke, alcual he introducido algunas variaciones como poste-riormente explicaré.
El fuente 3 muestra el código completo de la cla-se FormStack, la clase sobre la que se sustenta esteingenioso sistema.
La clase FormStack se deriva de la clase baseCollectionBase, lo cual nos va a permitir mantenerla caché de formularios en la estructura List de lacolección. El control de cada uno de los formulariosllamados se mantiene en una estructura pila, el obje-to Stack¸ el cual es implementado a través de unArrayList. Esta pila implementa la operación Pushque guarda el nombre del último formulario usadoen la cabecera de la pila y a su vez lo ejecuta o lo extraede la caché, en caso de haber sido usado previamen-te. Por medio de la clase Monitor se restringe el acce-so exclusivo a este trozo de código. La figura 2 mues-tra la operativa de este método.
dotN
etM
anía
<<
28
dnm.movilidad<<
Imports SystemImports System.CollectionsImports System.Runtime.InteropServicesImports System.ThreadingImports System.Text
Public Class FormStackInherits CollectionBasePrivate stack As ArrayList = New ArrayList()‘ Formulario Principal de la Aplicación.Public oFormPrin As FrmPrincipalPublic Sub Run()
‘ Se encarga de ejecutar cada uno de los formularios llamados.Do
System.Windows.Forms.Application.DoEvents()Loop While List.Count > 0
End Sub
Public Sub Detener()For Each sf As FormBase In List
sf.Dispose()Next
‘ Limpia la lista de formularios.List.Clear()
End Sub
Public Sub Push(ByVal FormType As Type)Monitor.Enter(Me)
For Each sf As FormBase In ListIf sf.GetType.Name.Equals(FormType.Name) Then
sf.Visible = True‘ Se llama a este método nuevo del FormBase para que refresce ‘ correctamente algunos controles del formulario.sf.ActivarFormulario()stack.Add(FormType.Name)Exit Sub
End IfNext
‘ No se encuentra en la pila.‘ Creo la instancia.Dim form As FormBase = CType(Activator.CreateInstance(FormType), _
FormBase)List.Add(form)
‘ Manejador del evento de cerrar el formulario.AddHandler form.FormClose, AddressOf form_Formclosedstack.Add(FormType.Name)
‘ Añadir la opción al menú Ventana del Formulario Principal.Dim lPrincipal As Boolean = FalseIf List.Count = 1 Then
lPrincipal = TrueEnd IfMe.oFormPrin.AñadirMenuItem(form.Text, FormType, lPrincipal)
form.Visible = TrueMonitor.Exit(Me)
End Sub
Public Sub Pop(ByVal FormsToPop As Integer)If stack.Count < FormsToPop ThenThrow New Exception(“No se puede extraer tantos elementos de la pila”)
Else‘ Se elimina de la pila, pero no de la caché.For i As Integer = 0 To (FormsToPop - 1)
stack.RemoveAt(stack.Count - 1)Next
Fuente 3. La clase FormStack (continúa...)Figura 2. Funcionamiento del método Push
de la clase FormStack
Por otra parte, la operación Popque se ejecuta al cerrar el formulario,elimina del top de la pila el nombre deeste formulario y vuelve a mostrar jus-tamente el anterior, desde el que fuellamado.
Para que cuando nos salgamos de unformulario éste realmente no se cierre cap-turamos el evento Closing de dicho for-mulario, por medio del métodoFormBase_Closing de nuestra clase for-mulario FormBase. Dicho método ocultael formulario, y lanza el evento FormClose,que es manejado por Form_FormClosed deesta clase FormStack.
Para una explicación más detalla-da de este sistema, remito al lector aleer el magnífico artículo de ChrisTacke.
Ahora que ya tenemos la ventaja depoder reutilizar los formularios abiertos,optimizando de esta forma su presenta-ción, podemos ofrecer una forma rápiday cómoda de acceder a dichas opciones,evitando al usuario de nuestra aplicaciónnavegar por todas las posibles opcionesdel menú. Se trata al fin y al cabo de cre-ar un menú “Ventana”, como muestra lafigura 3, que recoja todos los formulariosabiertos e incluso que indique el últimoal que hemos accedido.
La implementación se llevará a cabodesde la propia clase FormStack, de talforma que cada vez que queramos abrirun formulario y llamemos por tanto asu método Push, se hará a su vez unallamada al método AñadirMenuItem delformulario de entrada de la aplicación,representado por el objeto oFormPrin.El fuente 4 muestra todo el códigonecesario para realizar este procesodesde el formulario de entrada de laaplicación, y el fuente 5 detalla la cre-ación de una subclase de MenuItem quenos facilitará la manipulación de cadauno de las entradas añadidas al menú“Ventana”. Para poder relacionar elformulario FrmPrincipal con la claseFormStack, en el Load del formulariorealizamos la asignación: goFormStack.
oFormPrin = Me, donde goFormStack esel objeto utilizado para instanciar laclase FormStack.
Optimizando formularios conmuchos controles
Con un framework como el desarro-llado en los apartados anteriores opti-mizamos en gran medida la carga denuestros formularios, pero seguiremosteniendo serios problemas de rendi-miento si no tenemos algunas cuestio-nes en mente, principalmente cuandonos enfrentamos a formularios querequieren de muchos controles.
Normalmente cuando requerimos deun formulario completo con mucha infor-mación que ofrecer al usuario recurrimosal control TabControl, creando diferentesapartados por medio de pestañas. Si dise-ñamos ese formulario con todos los con-troles en cada una de las pestañas, comoseguramente haríamos en una aplicaciónde escritorio, la carga será excesivamentelenta, y terminaremos por impacientar alusuario de nuestra aplicación.
Con Visual Studio 2005 tenemosuna alternativa muy sencilla para sol-ventar esta cuestión. Se trata de los con-
dotN
etM
anía
<<
29
dnm.movilidad<<
If stack.Count > 0 ThenFor Each sf As FormBase In List
If sf.GetType.Name.Equals(stack(stack.Count - 1)) Thensf.Visible = True
End IfNext
End IfEnd If
End Sub
Private Sub form_Formclosed()Pop(1)
End Sub
Public Overrides Function ToString() As StringDim Message As StringBuilder = New StringBuilder()Message.Append(“Hay “ & List.Count.ToString() & “ forms en la caché” & _
ControlChars.CrLf)Message.Append(“Contenido de la pila:”)
For i As Integer = (stack.Count - 1) To 0 Step -1Message.Append(ControlChars.CrLf & stack(i).ToString)
NextReturn Message.ToString
End Function
End Class
(...continuación) Fuente 3. La clase FormStack
Figura 3. Emulandoun Menú Ventana
Podemos de esta forma crear un UserControl por cada una delas pestañas de nuestro formulario, y en tiempo de ejecución
incorporarlo cuando el usuario la active por primera vez
troles de usuario (UserControl) y la gran ventaja quetenemos ahora de diseñarlos de forma totalmentevisual. Podemos de esta forma crear un UserControlpor cada una de las pestañas de nuestro formulario, yen tiempo de ejecución incorporarlo cuando el usua-rio la active por primera vez. Es decir, sólo cuando seanecesaria su visualización.
La figura 4 muestra un ejemplo de UserControl uti-lizada en nuestra aplicación de ejemplo.
El fuente 6 muestra un ejemplo de framework quepodríamos utilizar en el desarrollo de cada uno denuestros controles.
Como se observa en el código debemos tener pre-sente siempre el enlace de datos con los controles de
dotN
etM
anía
<<
30
dnm.movilidad<<
Public Class frmPrincipalPublic Sub AñadirMenuItem(ByVal pNombreForm As String, _
ByVal FormType As Type, _ByVal pPrincipal As Boolean)
‘ MenuItem de la opción de Ventana.Dim mnuVentana As MenuItemDim mnuSeleccion As New MenuItemExtIf pPrincipal Then
mnuVentana = New MenuItemmnuVentana.Text = “Ventana”Me.mainMenu1.MenuItems.Add(mnuVentana)
End If
Dim oMenuItem As MenuItemmnuSeleccion.Text = pNombreFormmnuSeleccion.Checked = TruemnuSeleccion.oType = FormType
AddHandler mnuSeleccion.Click, AddressOf EjecutarOptMenu
oMenuItem = LocalizarOpcion(“Ventana”)If TypeOf oMenuItem Is Object Then
‘ Desactiva el resto de opciones.For Each oMenuVen As MenuItem In oMenuItem.MenuItems
oMenuVen.Checked = FalseNextoMenuItem.MenuItems.Add(mnuSeleccion)
End IfEnd Sub
Public Function LocalizarOpcion(ByVal pTitulo As String) As MenuItemFor Each oMenuItem As MenuItem In Me.mainMenu1.MenuItems
If oMenuItem.Text.IndexOf(pTitulo) <> -1 ThenReturn oMenuItem
End IfNextReturn Nothing
End Function
Private Sub EjecutarOptMenu( ByVal sender As System.Object, _ByVal e As System.EventArgs)
Dim oMenuExt As MenuItemExtoMenuExt = CType(sender, MenuItemExt)
Dim oMenuItem As MenuItemoMenuItem = LocalizarOpcion(“Ventana”)
If TypeOf oMenuItem Is Object Then‘ Desactiva el resto de opciones.For Each oMenuVen As MenuItem In oMenuItem.MenuItems
If oMenuVen.Text.ToUpper = oMenuExt.Text.ToUpper ThenoMenuVen.Checked = True
ElseoMenuVen.Checked = False
End IfNext
‘ Procedimiento del Módulo Main para ejecutar los formularios.EjecutarFormulario(oMenuExt.oType)
End IfEnd Sub
Private Sub frmPrincipal_Load(ByVal sender As System.Object, _ByVal e As System.EventArgs) _Handles MyBase.Load
‘ Referencia de este objeto en la clase FormStack.goFormStack.oFormPrin = Me
End SubEnd Class
Fuente 4. Código del formulario de entrada a nuestra aplicación
' Nueva clase creada para almacenar el Tipo del formu' lario y poder ejecutar la opción desde el menú VentanaPublic Class MenuItemExt
Inherits MenuItemPublic oType As Type
End Class
Fuente 5. Clase MenuItemExt heredada deMenuItemaplicación
Figura 4.Control deUsuario para la
creación de Páginas
Imports SystemImports System.DataImports System.Data.SqlClient
Public Class TabUser‘ Creación del control.Public Sub New(ByVal pdtTabla As DataTable)
‘ Llamada necesaria para el Diseñador de Windows Forms.InitializeComponent()‘ Tabla sobre la que trabajará el Binding.Me.dtTabla = pdtTabla
End Sub
‘ Aquí enlazaríamos nuestros controles a la fuente de datos.Public Sub DataBindingTab()End Sub
‘ Método para habilitar/deshabilitar ciertos controles según‘ se encuentra la situación de nuestro formulario principal.Public Sub HabilitarControles(ByVal pOperacion As Boolean)End Sub
End Class
Fuente 6. Código de nuestro control de usuario
la pestaña, y el hecho de que el estado de los con-troles los debemos adecuar al del propio formulario.
El fuente 7 muestra la forma en que debemosproceder cada vez que se active cada una de las pes-tañas del formulario.
Manejando el evento SelectedIndexChanged pro-cederemos a añadir a la pestaña correspondiente elcontrol de usuario previamente creado. En Me.dtTablacontendremos la DataTable principal de nuestro for-mulario, y con Me.OperacionActual especificamos laoperación que en estos momentos el usuario está rea-lizando: añadir, navegar, actualizar, etc.
Otra posibilidad que tenemos para optimizarla carga de nuestros formularios es la de cambiarla forma en que se cargan los controles dentro delmétodo InitializeComponents. Es un método quedeberíamos manipular sólo cuando hayamos ter-minado por completo el diseño del formulario, yaque debemos tener en cuenta que Visual Studio lorecrea cada vez que hacemos un cambio en el dise-ñador.
Son tres los cambios que vamos a aplicar sobre elInitializeComponents:
• Crearemos los controles siguiendo una jerar-quía “top-down”, de arriba hacia abajo. Sitenemos, por ejemplo, un control panel conmuchos controles, crearemos primero el panely posteriormente añadiremos a él el resto decontroles.
• Asignaremos a cada control la propiedad parent,en vez de añadirlo a la colección controls.
• Reduciremos el número de métodos necesariospara crear los controles. Podemos pasar por ejem-plo de crear un control de esta forma:
Me.PictureBox1.Location = _New System.Drawing.Point(4, 80)
Me.PictureBox1.Size = _New System.Drawing.Size(233, 72)
A hacerlo de esta otra forma, en la que consoli-damos los dos métodos anteriores en uno solo:
Me.PictureBox1.Bounds = NewSystem.Drawing.Rectangle(4, 80, 233, 72)
Esta premisa es totalmente aplicable a nuestropropio código. Reduciendo el número de llamadas amétodos en la carga del formulario mejoraremos sus-tancialmente la presentación de éste.
Con un control panel, un textbox, y un label ensu interior pasaríamos de un InitializeComponentscomo el que muestra el fuente 8, a otro optimi-zado reflejado en el fuente 9 contendremos laDataTable principal de nuestro formulario, y conMe.OperacionActual especificamos la operación queen estos momentos el usuario está realizando: aña-dir, navegar, actualizar, etc.
Optimizando la manipulación local dedatos con SQL Server Mobile
El otro componente de nuestra aplicación, cuyorendimiento debemos cuidar al máximo es la mani-pulación de datos. Cuando llegamos a trabajar con
dotN
etM
anía
<<
31
dnm.movilidad<<
‘ Se añade el contenido de la pestaña en tiempo de ejecución.Private Sub TabControl1_SelectedIndexChanged(_
ByVal sender As Object,_ByVal e As System.EventArgs) _Handles TabControl1.SelectedIndexChanged
If Me.TabControl1.SelectedIndex >= 1Select Case Me.TabControl1.SelectedIndex
Case 1 ‘Página 2. Otros Datos.If Me.TabPage2.Controls.Count = 0 Then
Dim lPagina2 As New TabUser(Me.dtTabla)Me.TabPage2.Controls.Add(lPagina2)lPagina2.DataBindingTab()lPagina2.HabilitarControles(Me.OperacionActual)
End IfCase 2 ‘ Otra Pestaña.
End SelectEnd If
End Sub
Fuente 7. Código de activación de cada pestaña
Private Sub InitializeComponent()Me.mainMenu1 = New System.Windows.Forms.MainMenuMe.Panel1 = New System.Windows.Forms.PanelMe.TextBox1 = New System.Windows.Forms.TextBox
Me.Label1 = New System.Windows.Forms.LabelMe.Panel1.SuspendLayout()Me.SuspendLayout()
‘Panel1Me.Panel1.Controls.Add(Me.Label1)Me.Panel1.Controls.Add(Me.TextBox1)Me.Panel1.Location = New System.Drawing.Point(26, 49)Me.Panel1.Name = “Panel1”Me.Panel1.Size = New System.Drawing.Size(192, 123)‘‘TextBox1Me.TextBox1.Location = New System.Drawing.Point(17, 28)Me.TextBox1.Name = “TextBox1”Me.TextBox1.Size = New System.Drawing.Size(148, 21)Me.TextBox1.TabIndex = 0Me.TextBox1.Text = “TextBox1”
‘Label1Me.Label1.Location = New System.Drawing.Point(17, 10)Me.Label1.Name = “Label1”Me.Label1.Size = New System.Drawing.Size(80, 15)Me.Label1.Text = “Label1”
‘FrmProductosMe.AutoScaleDimensions = New System.Drawing.SizeF(96.0!,96.0!)Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.DpiMe.ClientSize = New System.Drawing.Size(240, 268)Me.Controls.Add(Me.Panel1)Me.Menu = Me.mainMenu1Me.Name = “FrmProductos”Me.Text = “FrmProductos”Me.Panel1.ResumeLayout(False)Me.ResumeLayout(False)
End Sub
Fuente 8. InitializeComponent original
un volumen de información más omenos importante, pretendemos ade-más mantener la integridad y consis-tencia de los datos en base a transac-ciones, y además debe existir algún nexode unión entre el dispositivo móvil y unaaplicación empresarial en un servidorremoto en base a replicación o RDA(Remote Data Access), la solución pasa porusar SQL Server CE. Con la llegada deVisual Studio 2005 y SQL Server 2005se ha reescrito por completo el sistemade almacenamiento de SQL Server CE,de tal forma que en cuestiones acercade su rendimiento Microsoft ha pre-tendido acercar este producto a su her-mano mayor, llegando incluso a rebau-tizarlo como Microsoft SQL ServerMobile. Si además de ello, tenemos encuenta que este gestor de base de datosse integra perfectamente en elExplorador de Servidores de Visual
Studio 2005 y que además está sopor-tado en Smartphones con WindowsMobile 5.0, lo hace el perfecto candi-dato para usarlo en nuestras aplicacio-nes móviles.
He aquí algunos consejos para opti-mizar el tratamiento de nuestros datos:• Cuando sea posible evitemos el uso del
data binding. El enlace automáticode datos con los controles del for-mulario es un mecanismo sencilloy potente, y que por supuesto nosevita la escritura de gran cantidadde código. Pero el gran problemadel data binding es el pobre rendi-miento que ofrece a nuestra apli-cación. Es extremadamente lento,y en ciertas ocasiones conviene evi-tarlo. Por ejemplo, cuando habla-mos de rendimiento, es preferiblecargar manualmente los elemen-tos de un ComboBox o un ListBox arealizar un enlace automático pormedio de sus propiedades DataSource y Displaymember.
• No abusemos de los DataSet para la car-ga de datos. El DataSet es un objetobastante “pesado” y tiene un costebastante significativo en términos derendimiento. Evitemos su uso prin-cipalmente cuando lo único que que-ramos es realizar una consulta paraobtener ciertos datos de nuestrastablas. En estos casos es convenien-te el uso del DataReader, un objetoque nos permite sobre todo una car-ga inicial muy rápida de los datospedidos.
• Cerremos los Datareader y losSqlCeCommand tan pronto como haya-mos terminado de trabajar con ellos.Evitaremos de esta forma el consumode recursos de forma innecesaria.
• Cuando tengamos que incorporardatos en nuestro DataSet proce-
dente de una fuente XML es siem-pre conveniente que éste vengaacompañado de su esquema, y ade-más que diseñemos nuestroDataSet con declaración de tipos(Typed Dataset). Los typed datasetson otra de las grandes novedadesllegadas con Visual Studio 2005,que además de mejorar el rendi-miento cuando trabajamos conXML nos van a permitir elaborarun código más sencillo y conmenos posibilidades de incorpo-rar errores.
• Usemos el nuevo objeto SqlCeResultSet. Este objeto que vie-ne de la mano de SQL ServerMobile, está a mitad de camino delDataReader y el DataSet. Como elDatareader necesita una conexióndedicada y resulta ser un objetobastante “ligero” de usar, pero esque además incorpora todas lasventajas de un DataSet: nos per-mite desplazarnos en cualquierdirección para visualizar los datosy podemos actualizar los datosinsertados o modificados sobre suorigen de datos. Con el frameworkmulti-formulario diseñado enapartados anteriores resulta impo-sible la utilización de este objetocomo estructura de datos princi-pal de todos nuestros formularios,lo impide el hecho de que necesi-temos una conexión dedicada. Sinembargo, podemos llegar a usarloen todos aquellos formularios oprocesos donde eventualmentenecesitemos actualizar datos ypodamos así evitar el uso de unDataset para ello.
En el fuente 10 se muestra unejemplo de las instrucciones que nos
dotN
etM
anía
<<
32
dnm.movilidad<<
Private Sub InitializeComponent()Me.mainMenu1 = New System.Windows.Forms.MainMenuMe.Panel1 = New System.Windows.Forms.PanelMe.TextBox1 = New System.Windows.Forms.TextBoxMe.Label1 = New System.Windows.Forms.LabelMe.Panel1.SuspendLayout()Me.SuspendLayout()
‘Panel1Me.Panel1.Bounds = _
New System.Drawing.Rectangle(26,49,192,123)Me.Panel1.Name = “Panel1”
‘TextBox1Me.TextBox1.Bounds = _
New System.Drawing.Rectangle(17,28,148,21)Me.TextBox1.Name = “TextBox1”Me.TextBox1.TabIndex = 0Me.TextBox1.Text = “TextBox1”Me.TextBox1.Parent = Me.Panel1
‘Label1Me.Label1.Bounds = _
New System.Drawing.Rectangle(17,10,80,15)Me.Label1.Name = “Label1”Me.Label1.Text = “Label1”Me.Label1.Parent = Me.Panel1
‘FrmProductosMe.AutoScaleDimensions = _
New System.Drawing.SizeF(96.0!, 96.0!)Me.AutoScaleMode = _
System.Windows.Forms.AutoScaleMode.DpiMe.ClientSize = New System.Drawing.Size(240,268)Me.Controls.Add(Me.Panel1)Me.Menu = Me.mainMenu1Me.Name = “FrmProductos”Me.Text = “FrmProductos”Me.Panel1.ResumeLayout(False)Me.ResumeLayout(False)
End Sub
Fuente 9. InitializeComponens optimizado.
Usemos el nuevo objeto SqlCeResultSet. Este objeto que viene de la mano de SQL Server Mobile, está a mitad
de camino del DataReader y el DataSet
proporciona SqlCeResultSet para lamanipulación de los datos, tanto paranavegar por los datos, como paraactualizarlos, y cuyo código comple-to podemos encontrar en el formula-rio de ejemplo (FrmSqlCeResultSet)que acompaña a este artículo.
Recomendaciones sobre el usode instrucciones y construccio-nes del lenguaje
He aquí algunos consejos acerca deluso de determinadas instrucciones deCompact Framework:
• Cuando tengamos que concatenarcadenas, usemos la clase StringBuilder. Cada vez que se suman sim-plemente Strings se van creando nue-vas copias en memoria para ir alber-gando la nueva cadena creada, lo cualevidentemente llega a ser muy lento.Con StringBuilder evitamos este pro-blema y por tanto conseguimos unresultado mucho más eficaz.
• Evitemos realizar llamadas directasal Garbage Collector, el recolector debasura de .NET. Es convenientedejar que el propio sistema libere losobjetos cuando proceda.
• Procuremos “cortocircuitar” las sen-tencias lógicas, a través de AndAlso yOrElse, y de esta forma nos saltare-mos la evaluación de expresión quenunca tendrán efecto.
• El uso de genéricos, incorporado alCompact Framework 2.0, es más efi-ciente que la utilización estándar decolecciones, puesto que evita la cargaproveniente del “empaquetado”(boxing) y “desempaquetado” (unbo-xing) de los tipos por valor. Sin embar-go, y como bien detalla el equipo dedesarrollo del .NET CompactFramework en su blog, es importan-te tener presente que la utilización detipos genéricos puede aumentar eltamaño del código proveniente de lacompilación JIT, puesto que distintasinstanciaciones de dicho tipo produ-ce separadas representaciones y portanto un aumento del tamaño de códi-go compilado. Debemos evitar el usode un gran número de métodos/tipospor cada definición de método/tipogenérico.
• El uso de XmlTextReader y XmlTextWriter para el manejo de documen-tos XML, principalmente cuando eltamaño de éstos es grande, es máseficiente en uso de memoria que elde XmlDocument.
• En cuanto a la seriación, con CompactFramework 2.0 tenemos la posibili-dad de usar XmlSerializer, instrucciónque ya anteriormente teníamos dis-ponible con el .NET Framework nor-mal. El uso de la seriación XML noes muy recomendable en términos deuso de memoria, procesador e inclu-so tráfico de red. Es aconsejable eldesarrollo de nuestras propias clases
dotN
etM
anía
<<
33
dnm.movilidad<<
‘ Método para la carga inicial de los datos.Private Sub CargarResultSet()
Dim ceCmd As SqlCeCommand = New SqlCeCommand(_“SELECT * FROM Products ORDER BY ProductID”, ceConn)
ceResultSet = ceCmd.ExecuteResultSet(ResultSetOptions.Updatable Or_ResultSetOptions.Scrollable)
End Sub
‘ Botón primeroPrivate Sub PrimerRegistro(ByVal sender As System.Object, ByVal e As System.EventArgs)_
Handles btoPrimero.ClickIf ceResultSet.ReadFirst() Then
Me.ActualizarValores()End If
End Sub
‘ Botón últimoPrivate Sub UltimoRegistro(ByVal sender As System.Object, ByVal e As System.EventArgs)_
Handles btoUltimo.ClickIf ceResultSet.ReadLast() Then
Me.ActualizarValores()End If
End Sub
‘ Botón anteriorPrivate Sub RegistroAnterior(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btoAnterior.ClickIf ceResultSet.ReadPrevious() Then
Me.ActualizarValores()End If
End Sub
‘ Botón siguientePrivate Sub RegistroSiguiente(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btoSiguiente.ClickIf ceResultSet.Read() Then
Me.ActualizarValores()End If
End Sub
‘ Botón para actualizar los datos de la pantalla.Private Sub ActualizarRegistros(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btoActualizar.ClickceResultSet.Update()
End Sub
‘ Botón para insertar un nuevo registro.Private Sub InsertarRegistro(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btoInsertar.ClickDim ceNewRec As SqlCeUpdatableRecord = ceResultSet.CreateRecord()ceNewRec.SetValue(3, ProductName.Text)ceNewRec.SetValue(8, CType(InStock.Value, Int16))ceNewRec.SetValue(11, False)ceResultSet.Insert(ceNewRec)ceResultSet.Update()
End Sub
‘ Botón para borrar un registro.Private Sub BorrarRegistro(ByVal sender As System.Object, ByVal e As System.EventArgs)_
Handles btoBorrar.ClickceResultSet.Delete()
End Sub
Fuente 10. Uso de SQLCeResultSet
que haciendo uso de BinaryReader yBinaryWriter nos permita la realiza-ción de una serialización binaria.
• Tampoco es muy recomendable el usointensivo de reflection. El uso por ejem-plo de GetTypes(), provocará la cargade todos los tipos del ensamblado.Aunque las estructuras utilizadas paraalbergar dichos tipos no son muygrandes, siempre causará un impactonegativo sobre el uso de la memoria.
• Cuando tengamos que crear múltipleshebras que funcionen de forma total-mente asíncrona y además sean de cor-ta duración, debemos usar ThreadPoool, y no instanciar directamenteThreads independientes. Permitiremosla reutilización de hebras libres y evi-taremos la sobrecarga de crear y des-truirla cada una de ellas de forma inde-pendiente.
¿Cómo medir el rendimiento?Por una parte debemos medir el tiem-
po que nuestro programa emplea en larealización de ciertos procesos cuya dura-ción queramos controlar. Para ello pode-mos emplear Environment.TickCount, pro-visto por el propio Compact Framework,como muestra el siguiente ejemplo:
Si queremos mayor exactitud en lamedida del tiempo podemos emplear lafunción del API: QueryPerformanceFrecuency y QueryPerformanceCounter.Con estas funciones podremos obteneruna exactitud por debajo de los 500 ms.En el artículo “Developing WellPerforming .NET Compact FrameworkApplications” (ver el enlace al final del artí-culo) se implementa una clase que envuel-ve los detalles del uso de estas API y pre-senta al lector una forma sencilla de uti-lización.
Por otra parte .NET Compact Fra-mework nos permite la generación deun informe de estadísticas con aquelloscontadores interesantes de controlar enla ejecución de nuestra aplicación. Lospasos para crear este fichero de estadís-ticas son los siguientes:1. Crear una nueva clave en el registro
del dispositivo: HKEY_LOCAL_MACHI-NE\SOFTWARE\Microsoft\.NetCompact
Framework\PerfMonitor
2. Dentro de dicha clave crear un nue-vo valor de tipo dword, llamadoCounters, y asignarle el valor 1.
3. Cada vez que ejecutemos una apli-cación administrada por .NETCompact Framework se creará unfichero de texto con el nombre: <Myapp>.stat, en el directorio raíz denuestro dispositivo móvil.
Con estos contadores podremos ana-lizar problemas de rendimiento y el impac-to producido por determinados cambiosen el código de nuestra aplicación.
Algunos contadores interesantespara estudiar podrían ser los siguientes:• Número de recolecciones (Garbage
Collections) realizadas de un tipodeterminado durante la ejecucióndel programa.
• Bytes recolectados por tipo durante laejecución del programa.
• Tiempo total empleado en realizar larecolección de un tipo determinado.
• Tiempo empleado en realizar la reco-lección de todos los tipos (Latencia delGarbage Collector).
• Bytes reservados en memoria para losobjetos administrados, el código com-pilado JIT y los datos empleadosdurante el tiempo total de ejecución.
• El tamaño precompilado del códigoIL que ha sido compilado JIT.
• El tamaño postcompilado del códigoIL tras pasar la compilación JIT.
• Contador de métodos que han sidocompilados JIT.
• Número de bytes eliminados de lacaché de código. Mostrará un valordiferente de cero cuando nuestra apli-cación se haya encontrado con exce-siva presión de uso de memoria.
• Número de excepciones controla-das mientras la aplicación se estabaejecutando.
• Número de llamadas virtuales.
ConclusionesComo hemos visto, obtener un buen
rendimiento en una aplicación para dis-positivos móviles requiere de una serie deconocimientos algo avanzados sobre elentorno .NET, y desgraciadamente exis-te poca bibliografía oficial sobre el tema.
En este artículo hemos pretendido daruna serie de pautas básicas para comen-zar este tipo de aplicaciones desde cero,comenzando por el framework inicial has-ta llegar al tratamiento de los datos.
Tal vez, en próximos artículos, poda-mos tratar el rendimiento trabajando condatos remotos y servicios Web.
Por último, es importante mante-ner siempre presente la necesidad demantener un registro de estadísticas derendimiento, así como de realizarmediciones de tiempo en aquellos pro-cesos críticos o sospechosos de unpobre rendimiento.
dotN
etM
anía
<<
34
dnm.movilidad<<
Referencias“Developing Well Performing .Net CompactFramework Applications”, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnet-comp/html/netcfperf.asp.
“Creating a Multiple Form ApplicationFramework for the Microsoft .Net CompactFramework”, http://msdn.microsoft.com/mobility/understanding/articles/default.aspx?pull=/library/en-us/dnnetcomp/html/netcfuiframework.asp.
“Improving Microsoft .Net Compact Framework-based Application Form Load Performance”,http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfimproveformload-perf.asp.
“Blog del .Net Compact Framework”,h t t p : / / b l o g s . m s d n . c o m / n e t c f t e a m /archive/2005/05/04/414820.aspx.
Dim lTmpIni, lTmpFin, lTotalTmp As IntegerlTmpIni = Environment.TickCountMe.Antes_New()lTmpFin = Environment.TickCountlTotalTmp = lTmpFin - lTmpIniMessageBox.Show(“Total Antes_New “ & _
lTotalTmp.ToString + “ ms.”)
dotN
etM
anía
<<
35
Lo que nos traerá Orcas:Novedades en C# 3.0
En el pasado PDC celebrado en Los Angeles, Microsoft desveló por primeravez varias de las características previstas para la siguiente versión de VisualStudio, Orcas. La “joya de la corona” en lo que a los lenguajes de programa-ción respecta es LINQ (Language INtegrated Query).
combinación de extensiones al lenguaje ylibrerías de código manejado que permite expre-sar de manera uniforme las consultas sobre colec-ciones de objetos, bases de datos relacionales ydocumentos XML, ayudando de esta manera a eli-minar el conocido “desajuste de impedancia” (impe-dance mismatch) que provocan las diferencias entrelos modelos de programación que proponen loslenguajes de de propósito general y los lenguajesde acceso a bases de datos relacionales y otros alma-cenes de datos.
Este artículo describe siete nuevas característicasque se incorporarán (posiblemente con ligeras varia-ciones) al lenguaje C# en su próxima versión 3.0:
• Declaración implícita del tipo de variables locales• Inicializadores de objetos y colecciones• Tipos anónimos• Arrays de tipos definidos de forma implícita• Métodos extensores• Expresiones lambda• Árboles de expresiones
Estas nuevas características se integran de mane-ra armoniosa, según mi humilde opinión, con el res-to de las posibilidades que ofrece la versión actual dellenguaje (especialmente las incorporadas en la ver-sión 2.0, como los tipos genéricos, los iteradores o lainferencia de delegados –ver [3]–), y en conjunto sir-ven como base directa para la implementación de laoctava y más importante novedad que incluirá C#3.0: las expresiones de consulta (query expressions), elprincipal reflejo de LINQ en el lenguaje de progra-mación, cuya presentación aplazaremos para una pró-xima entrega.
Recursos disponibles en Internet
Todas las novedades que presentaremos aquí pue-den ser probadas directamente por el lector intere-sado, pues Microsoft ha puesto a disposición delpúblico una versión del futuro compilador de C# 3.0,como parte de la presentación preliminar de la tec-nología LINQ disponible en la URL que se indicaen la bibliografía [1]. Además, podrá hacerlo de unamanera muy cómoda, pues dicha presentación pre-liminar se ofrece en forma de integración dentro deVisual Studio 2005, e incluye plantillas para la crea-ción de diferentes tipos de proyectos relacionadoscon C# 3.0 y LINQ, como muestra la figura 1.
Adicionalmente, desde la página Web antes men-cionada se puede acceder a otros recursos útiles, comola especificación preliminar de C# 3.0, el documen-
Octavio Hernández
dnm.futuro
<< LINQ es una
Octavio Hernándezes colaborador habitual
de dotNetManía,Ingeniero en
Informática de Sistemasy MVP de C#.
Figura 1. Plantillas de proyecto relacionadas con LINQ en Visual Studio 2005
dotN
etM
anía
<<
36
dnm.futuro<<
to original de Don Box y Anders Hejlsberg en elque se define la tecnología LINQ [2], vídeos demos-trativos y una gran cantidad de ejemplos.
Declaración implícita del tipo de varia-bles locales
En C# 3.0 será posible dejar al compilador la tareade determinar el tipo de una variable local inicializadaexplícitamente partiendo del tipo de la expresión de ini-cialización. Por ejemplo, en el fragmento de código quese muestra en el fuente 1 el compilador infiere que lavariable n es de tipo int por el tipo de la constante quese le intenta asignar. Este mecanismo puede utilizarsetambién en otras construcciones del lenguaje, como elbucle foreach o la sentencia using.
Hay que resaltar que esta característica no tiene nadaque ver con la que ofrecen algunos lenguajes dinámicos,en los que una variable puede almacenar valores de dis-tintos tipos a lo largo de su tiempo de vida. En C# 3.0,el compilador simplemente nos libera de la necesidad deespecificar el tipo de una variable inicializada e infiere eltipo de una variable declarada mediante el identificador“especial” var a partir del tipo de la expresión que se leasigna. La verificación estricta de tipos, uno de los pila-res del lenguaje, sigue por supuesto en vigor.
Aunque a priori este nuevo recurso podría utili-zarse para declarar la mayoría de las variables loca-les inicializadas (exceptuando, por ejemplo, aquellassobre las que queramos utilizar el polimorfismo, olas que queramos inicializar con el valor “genérico”null), tal práctica podría considerarse nociva de cara
a la claridad del código fuente. La verdadera poten-cia de esta característica sólo se hace evidente cuan-do se utiliza en combinación con otras (por ejemplo,los tipos anónimos), como ocurre cuando se hace usode las posibilidades que ofrece LINQ.
Inicializadores de objetos y coleccionesLa mayor parte de los ejemplos que se presentan
a lo largo de ésta y nuestras próximas entregas asu-men la definición de la clase Persona que se muestraen el fuente 2.
class Program{
static void Simple(){
// Declaración implícita del tipo de la variablevar n = 2; // equivale a int n = 2;Console.WriteLine(n.GetType().FullName);
// Declaración implícita del tipo de la variable// y los elementos del array var arr = new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };Console.WriteLine(arr.GetType().FullName);
foreach (var i in arr)Console.WriteLine(i);
}}
Fuente 1. Declaración implícita del tipo de variablesy elementos de array
public enum SexoPersona { Mujer, Varón }public class Persona{
// camposprivate string nombre = null;private SexoPersona? sexo = null;private DateTime? fechaNac = null;
// constructorespublic Persona() { }public Persona(string nombre, SexoPersona sexo){
this.nombre = nombre;this.sexo = sexo;
}public Persona(string nombre, SexoPersona sexo, DateTime fechaNac)
: this(nombre, sexo){
this.fechaNac = fechaNac;}
// propiedadespublic string Nombre{
get { return nombre; } set { nombre = value; }}public SexoPersona? Sexo{
get { return sexo; } set { sexo = value; }}public DateTime? FechaNac{
get { return fechaNac; } set { fechaNac = value; }}public int? Edad{
get{
if (fechaNac != null)return (int)(DateTime.Today.Subtract(fechaNac.Value).TotalDays /365.25);
elsereturn null;
}}// métodospublic override string ToString(){
return (nombre != null ? nombre : “ANONIMO”) + (sexo != null ?(sexo.Value == SexoPersona.Mujer ? “ (M)” : “ (V)”) : “”) + (fechaNac != null ? “ (“ + Edad.ToString() + “)” : “”);
}}
Fuente 2. Clase Persona utilizada en los ejemplos
La verdadera potencia de estas nuevas carac-terísticas sólo se hace evidente cuando se utili-zan conjuntamente,como ocurre cuando se haceuso de las posibilidades que ofrece LINQ ][
C# 3.0 añade nuevas construcciones sintácticaspara facilitar la especificación inline de constantes detipos compuestos (estructuras y clases) y de coleccio-nes de éstos. Estas construcciones constituyen un útilmecanismo de conveniencia, y al igual que ocurre conla inferencia de tipos de las variables locales, toda supotencia sólo se hace visible cuando se utilizan en com-binación con otras de las novedades que se describenen este artículo.
Inicializadores de objetos
El método Simple2() que se muestra en el fuente 3comienza con la declaración de una variable de tipoPersona y la asignación a ésta de una constante de la cla-se construida ad hoc. Básicamente, en lugar de la tradi-cional lista de argumentos del constructor ahora se pue-de utilizar también esta variante más “declarativa”, en laque los valores de las propiedades o campos del objetose especifican mediante un inicializador de objeto, con-sistente en una secuencia de elementos del tipo nombre=valor encerrada entre llaves.
Un requisito indispensable para que este meca-nismo funcione en el caso de una clase es que éstaofrezca un constructor sin argumentos, como ocurreen el caso de las clases que no tienen un constructordefinido explícitamente y de aquellas que son sinteti-
zadas artificialmente por el compilador (“tipos anó-nimos”, que presentaremos a continuación).
Inicializadores de colecciones
La extensión de la sintaxis para la inicialización deobjetos se ha ampliado también a las colecciones gené-ricas. El tipo al que se aplica el inicializador de colec-ción debe implementar la interfaz genérica System.Collections.Generic.ICollection<T>, y la inicializaciónse traduce en la construcción de la colección, seguida deuna secuencia de llamadas al método ICollection<T>.Add(T) para añadir cada elemento de la lista.
En el propio fuente 3 se muestra más adelante ladeclaración e inicialización de la variable Hijos, detipo List<Persona>. La declaración ha sido sacada fue-ra del método (lo que nos impide utilizar var) puesvolveremos a referirnos a esta colección desde otrosmétodos del ejemplo.
Tipos anónimosLa expresión tipos anónimos hace referencia a la posi-
bilidad de que el compilador de C# 3.0 sintetice de for-ma automática nuevos tipos de datos a partir de las carac-terísticas que se le indiquen en expresiones de inicializa-ción. Por ejemplo, al compilar la primera sentencia delfragmento de código que se muestra en el fuente 4, elcompilador generará un tipo anónimo (en la versiónactual del compilador, el nombre que se asigna interna-mente a la clase es Sample1.Program+<Projection>f__1)
dotN
etM
anía
<<
37
dnm.futuro<<
static1 void Simple2(){
// inicializador de objetovar p = new Persona {
Nombre = “Amanda”, Sexo = SexoPersona.Mujer,FechaNac = new DateTime(1998, 10, 23)
};// equivale a:// Persona p = new Persona();// p.Nombre = “Amanda”;// p.Sexo = SexoPersona.Mujer;// p.FechaNac = new DateTime(1996, 2, 4);Console.WriteLine(p);
}
// inicializador de colecciónstatic List<Persona> Hijos = new List<Persona> {
new Persona { Nombre = “Diana”, Sexo = SexoPersona.Mujer, FechaNac =
new DateTime(1996, 2, 4) },new Persona { Nombre = “Dennis”, Sexo =
SexoPersona.Varón, FechaNac = new DateTime(1983, 12, 27) },
new Persona { Nombre = “Jennifer”, Sexo = SexoPersona.Mujer, FechaNac =
new DateTime(1982, 8, 12) },new Persona { Nombre = “Claudia”, Sexo =
SexoPersona.Mujer, FechaNac = new DateTime(1989, 7, 26) }
};
Fuente 3. Inicializadores de objetos y colecciones
static void Simple3(){
// tipos anónimosvar revista1 = new { Nombre = “DotNetManía”,EjemplaresPorAño = 12 };Console.WriteLine(revista1.GetType().FullName);var revista2 = new { Nombre = “MSDN Magazine”, EjemplaresPorAño = 12 };Console.WriteLine(revista2.GetType().FullName);
}
Fuente 4. Generación de tipos anónimos
El compilador de C# 3.0 sintetiza de formaautomática nuevos tipos de datos a partir
de las propiedades que se indiquen en expresiones de inicialización
dotado de las propiedades que se indican en su expre-sión de inicialización, Nombre y EjemplaresPorAño.Cuando se ejecute la aplicación, la variable revista1apuntará a un objeto de ese tipo generado de formaautomática por el compilador.
La mejor manera de adentrarse en los detalles deltipo es examinando el ensamblado generado median-te ILDASM (figura 2).
Un detalle muy importante a tener en cuentaaquí es que, como revelan la ejecución del códigode ejemplo y el examen del ensamblado, las varia-bles revista1 y revista2 son de un mismo tipo anó-nimo y no de dos tipos diferentes; C# “combina”las definiciones de tipos siempre que en las expre-siones de inicialización se incluyan las mismas pro-piedades, los tipos de éstas coincidan y estén decla-radas en el mismo orden.
Arrays de tipos definidos de forma implícita
Otra novedad relacionada con las anteriores es laposibilidad de inicializar un array sin indicar explícita-mente el tipo de los elementos, que es inferido por elcompilador a partir de los tipos de las constantes sumi-nistradas. El fuente 5 muestra varios ejemplos de arraysde tipos valor, tipos referencia e incluso de tipos gene-rados automáticamente; en este último caso, se apro-vecha la posibilidad de combinación de tipos anónimosque hemos mencionado anteriormente.
Métodos extensoresLos métodos extensores (extension methods) son un
mecanismo de conveniencia que permite extender oampliar la funcionalidad de una clase sin recurrir a laherencia, técnica en ocasiones imposible (porque la cla-se en cuestión ha sido declarada sealed) o inadecuadadesde el punto de vista de diseño, ni a la delegación ocomposición, que requiere una implementación máslaboriosa y frecuentemente no es mucho más adecua-
da en lo que a diseño se refiere. Para hacer justicia ymostrar que no todo se cuece en Microsoft, debemosseñalar que la idea que subyace a los métodos de exten-sión ha sido tomada de Delphi .NET, donde existe des-de hace tres versiones una característica similar, cono-cida allí como clases auxiliares (helper classes).
Suponga que tenemos a nuestra disposición la cla-se Persona del fuente 2, y que queremos ampliarlacon métodos adicionales –por ejemplo, añadirle unmétodo lógico que permita conocer si la persona cum-ple años en el mes en curso–. Suponga además quepor alguna de las razones antes mencionadas la heren-cia no es una alternativa viable. Usando los nuevosrecursos que nos brinda C# 3.0, la solución consisti-ría extender la clase artificialmente por medio de unaclase auxiliar (que hemos llamado Persona_Helper yse muestra en el fuente 6) dotada del método exten-sor correspondiente.
Tanto el método extensor como la clase que locontiene han de ser estáticos, y lo que realmente indi-ca que se trata de un método extensor es la presen-cia del modificador this delante del primer paráme-tro del método, que debe ser del tipo de la clase quese pretende extender. Una vez definida esta clase ypuesta “en ámbito”, el método extensor podrá seraplicado a instancias de la clase extendida como si de
dotN
etM
anía
<<
38
dnm.futuro<<
static void Simple4(){// arrays de tipos definidos implícitamentevar a = new [] { 2, 3, 5, 7 }; // int []var b = new [] { “x”, “y1”, “z” }; // string []
var contactos = new[] {new {Nombre = “Antonio López”,Telefonos = new[] {“914792573”, “607409115”}
},new {Nombre = “Pedro Posada”,Telefonos = new[] { “981234118” }
}};Console.WriteLine(contactos.GetType().FullName);
}
Fuente 5.Arrays de tipos definidos implícitamente
public static class Persona_Helper{
public static bool CumpleAñosEsteMes(this Persona p){
Console.WriteLine(“Utilización del método extensor”);return p.FechaNac.HasValue && p.FechaNac.Value.Month ==
DateTime.Today.Month && p.FechaNac.Value.Day >= DateTime.Today.Day;}
}
Fuente 6. Clase auxiliar con método extensor
Figura 2. ILDASM muestra la estructura de un tipo anónimo
un método de instancia corriente se tratase. El fuen-te 7 se muestra un fragmento de código en el que seaplica el método extensor definido anteriormente alos elementos de la colección Hijos.
Debe tenerse en cuenta que los métodos extenso-res tienen la menor prioridad a la hora de la resolu-ción de llamadas y son utilizados por el compiladorsólo en el caso de que no exista ningún método ade-cuado en la clase extendida o sus clases base. Si aña-diésemos a la clase Persona un método lógicoCumpleAñosEsteMes(), éste sería el método llamado des-pués de recompilar la aplicación. Para comprobarlo,el lector sólo tiene que quitar los comentarios a laslíneas correspondientes del código de ejemplo, quepuede descargar del sitio Web de la revista, y volver agenerar el ejecutable.
Debo confesar que cuando por primera vez vi estacaracterística en Delphi .NET, la recibí con ciertorecelo –sentimiento del que no me he librado aún deltodo–. La propia especificación preliminar de C# 3.0indica que los métodos extensores sólo deben utili-zarse ocasionalmente y en aquellos casos en los queno sea posible o conveniente utilizar un método deinstancia. Precisamente ante una situación así se encon-traron los diseñadores de LINQ.
Expresiones lambdaLas expresiones lambda, un recurso tradicional en
los lenguajes de Programación Funcional, permitenrepresentar de una manera mucho más concisa quelos métodos anónimos de C# 2.0 los bloques de códi-go que pueden colocarse inline en los lugares en losque el compilador espera encontrar una instancia dedelegado.
La sintaxis de una expresión lambda consta de unalista de parámetros, seguida del símbolo de implica-ción =>, seguido a su vez de una expresión o un blo-que de sentencias. La lista de parámetros se debe ence-rrar entre paréntesis, excepto en el caso de que la can-tidad de parámetros sea 1, caso en que los paréntesisson opcionales. Los tipos de los parámetros puedenser indicados explícitamente, o podemos dejar que elcompilador infiera los tipos tomando en cuenta la uti-lización de los parámetros en la parte derecha de la
expresión. El fuente 8 muestra varios ejemplos deexpresiones lambda.
Volviendo al ejemplo que hemos utilizado comohilo conductor a lo largo del artículo, suponga quedeseamos crear un método que nos permita mostrarlos elementos de la colección Hijos que satisfacen unacondición determinada; la condición se debe pasar almétodo como parámetro. El código del fuente 9 inclu-ye la declaración del tipo de delegado necesario, laimplementación del método y además dos ejemplosprácticos de llamadas a él, utilizando como argumen-
dotN
etM
anía
<<
39
dnm.futuro<<
static void Simple5(){
// métodos extensoresforeach(var p in Hijos)
if (p.CumpleAñosEsteMes())Console.WriteLine( p.Nombre + “ cumple años el día “ +
p.FechaNac.Value.Day);}
Fuente 7. Utilización de un método extensor
// ejemplos de expresiones lambdan => n + 1 // tipo implícito, uso de expresiónn => { return n + 1; }
// tipo implícito, uso de bloque de sentencias(int n) => { return n + 1; }
// tipo explícito, uso de bloque de sentencias(x, y) => Math.sqrt(x * x + y * y)
// dos parámetros, tipos implícitos, uso de expresión() => { Console.WriteLine(“Hola, Universo!”); }
// ningún argumento
Fuente 8. Ejemplos de expresiones lambda
public delegate bool Condicion(Persona p);
public static void MostrarHijos(Condicion condicion){
foreach(var p in Hijos)if (condicion(p))
Console.WriteLine(p);}
static void Simple6(){
// método anónimo (C# 2.0)MostrarHijos( delegate (Persona p) { return p.Edad >= 18; } );// expresión lambdaMostrarHijos( (Persona p) => p.Edad >= 18 );
}
Fuente 9. Uso de una expresión lambda en nuestro ejemplo
Las expresiones lambda permiten representarbloques de código inline de una manera aún
más concisa que los métodos anónimos
to primero un método anónimo (como haríamos hoyen C# 2.0) y luego la expresión lambda equivalente.
De los ejemplos presentados puede deducirse quelas expresiones lambda constituyen un superconjuntode los métodos anónimos, con las siguientes ventajasañadidas:
• Notación más concisa, expresiva y funcional.• Permiten definir los tipos de los parámetros de
forma implícita, mientras que con los métodosanónimos hay que indicarlos explícitamente.
• El cuerpo puede ser una expresión o un bloquede sentencias, siendo ésta última la única opciónposible cuando se utilizan métodos anónimos.
• Las expresiones lambda pueden almacenarse enmemoria como árboles de expresiones, comoveremos en la próxima sección.
Árboles de expresionesUna característica que ha distinguido siempre, des-
de los tiempos del venerable LISP, a la ProgramaciónFuncional es la posibilidad de que fragmentos de códi-go puedan ser tratados a voluntad como datos y vice-versa. Un breve pero intenso artículo de Don Boxen MSDN Magazine [4] resalta la importancia queasignan a esta posibilidad los arquitectos de .NETFramework, y los árboles de expresiones son precisa-mente un paso en esa dirección.
Los árboles de expresiones permiten representarlas expresiones lambda como estructuras de datos. Deesta manera, las expresiones lambda pueden transfor-marse según la necesidad en tipos delegados, para lageneración y posterior ejecución de código, o en árbo-les de expresión, para su posterior manipulación, alma-cenamiento o transmisión. Más concretamente, unaexpresión lambda que pueda convertirse a un tipodelegado D también podrá ser convertida en un obje-to del tipo System.Expressions.Expression<D>, querepresentará la expresión en memoria de una mane-ra transparente y eficiente. Observe que los árbolesde expresiones involucran algo más que recursos pura-mente lingüísticos: requieren el soporte de nuevas cla-ses cuyos espacios de nombres son System.Expressionsy System.Query y que están alojadas en el ensambladoSystem.Query.dll, el mismo en el que se incluye todoel soporte para LINQ.
Las dos primeras sentencias del código que se mues-tra en el fuente 10 presentan las dos posibles transfor-maciones de la expresión lambda que produce el suce-sor de un número entero (el tipo delegado genérico Funcestá definido en System.Query para una mayor comodi-dad). Más adelante, se genera un árbol de expresión parala expresión lambda de nuestro ejemplo que determinala mayoría de edad de una persona, y se imprime en laconsola la cadena que devuelve el método ToString()del árbol, que nos da una ligera idea de cómo se alma-cena internamente la expresión.
Conclusión
En este artículo hemos descrito las nuevas carac-terísticas que incluirá la próxima versión 3.0 del len-guaje de programación C# y que sirven de base parala implementación de la tecnología LINQ. A escla-recer qué es LINQ, qué posibilidades ofrece y cómofunciona internamente dedicaremos nuestra próximaentrega.
dotN
etM
anía
<<
40
dnm.futuro<<
static void Simple7(){
Func<int,int> f = x => x + 1; // códigoExpression<Func<int,int>> e = x => x + 1; // datos
Expression<Func<Persona, bool>> MayorDeEdad = p => p.Edad >= 18;
Console.WriteLine(MayorDeEdad);// imprime ‘|p| GE(p.Edad, 18)’
}
Fuente 10. Ejemplos de árboles de expresiones
Bibliografía
[1] Recursos relacionados con C# 3.0 y LINQ: http://msdn.microsoft.com/vcsharp/future
[2]Box, Don, Hejlsberg, Anders “The LINQ Project -.NET Language Integrated Query”, MicrosoftCorporation, septiembre de 2005.
[3] Hernández, Octavio “Novedades en el estándar de C#”, ,publicado en dotNetManía nº 20, noviembre de 2005.
[4] Box, Don “Scheme is love”, publicado en MSDN Magazine,octubre de 2005.
Los árboles de expresiones permiten representar las expresiones lambda como estructuras de datos para su manipulación,
almacenamiento o transmisión
dotN
etM
anía
<<
41
En el primer artículo de esta serie de artículossobre interoperabilidad (dotNetManía nº 22) vimoscómo usar componentes COM desde aplicacionescreadas con .NET; en este último veremos el casocontrario, es decir, cómo crear componentes en.NET y usarlos desde aplicaciones COM. Debido aque Visual Basic 6.0 es uno de esos entornos de desa-rrollo que “sabe” manejarse con los componentesCOM (o ActiveX), en las pruebas que haremos, usa-remos aplicaciones cliente creadas con VB6, las cua-les se incluyen en el ZIP con el código de ejemplo.
Debido a que Visual Studio 2005 ya es una realidaddesde hace meses, y desde finales de enero lo es tam-bién en la versión en español, usaremos ese entornopara crear nuestros componentes .NET “compati-bles” con COM. Y como es costumbre, el código quemostraremos a lo largo de este artículo, será en C#,pero en el ZIP con el código de ejemplo, también seincluye el equivalente creado con Visual Basic 2005,en el que veremos pequeños cambios con respecto acomo funciona el código de C#, sobre todo en la par-te referente al “lanzamiento” de eventos, ya queVisual Basic los maneja de forma más transparentede cómo lo hace C#.
En cualquier caso vere-mos dos formas de cre-ar los componentes des-de .NET, en la primeraparte nos centraremosen crearlos sin práctica-mente ningún tipo deconfiguración extra pornuestra parte, ya quedejaremos de la mano deVisual Studio todo lonecesario para la crea-ción de los componen-tes; pero como he co-mentado al principio, elpunto fuerte será crearcomponentes “decen-tes”, es decir compo-
Usar componentes .NET desde aplicaciones COM
En este artículo veremos cómo crear componentes en .NET que se puedan usar des-de aplicaciones que utilicen componentes COM.Pero no lo haremos de la forma fácil,sino que veremos cómo hacer que esos componentes funcionen de la misma formaque lo harían con cualquier entorno de desarrollo capaz de generar componentesCOM (o ActiveX),de forma que tengan compatibilidad binaria,para no tener que vol-ver a generar la aplicación cliente si decidimos modificar el componente.
<< Crear componentes de .NET para usar desde aplicaciones COM
dnm.inicio.fundamentos
Guillermo “Guille” Som
dnm.incio.taller
Guillermo “Guille” Somes Microsoft MVP de Visual Basic
desde 1997. Es redactor dedotNetManía,miembro de Ineta
Speakers Bureau Latin America,mentor de Solid Quality LearningIberoamérica y autor del libro
Manual Imprescindible deVisual Basic .NET.
http://www.elguille.info
Cuando trabajamos con componentes COM (ya sean DLL o controles ActiveX),es importantemantener la compatibilidad binaria entre el componente y el cliente que lo utiliza.Al manteneresa compatibilidad binaria nos aseguramos de que cualquier cambio que hagamos en elcomponente COM no requerirá tener que volver a compilar la aplicación que lo utiliza.
Esto es útil en los casos en que hacemos mejoras en el código del componente pero esoscambios no afectan a las interfaces expuestas por el mismo, de forma que la aplicación clienteseguirá usándolo de la misma forma que lo hacía antes de hacer esos cambios. Con lo cual nosevitamos tener que recompilar tanto el componente como la aplicación cliente.
Debemos recordar que COM se basa en interfaces, y es por medio de esas interfacesexpuestas como “controla” la compatibilidad del componente con respecto al cliente que lousa. Si cambia la interfaz (o interfaces) se debe crear una nueva versión del componente parapermitir que los clientes que usaban las interfaces anteriores sigan funcionando como si nadahubiera pasado,y serán los nuevos clientes los que se aprovechen de esos cambios en las interfacesexpuestas en el componente.
Estos detalles los tendremos en cuenta cuando hagamos nuestros componentes en .NET ylos queramos utilizar desde aplicaciones por medio de la interoperabilidad COM.
Componentes COM y compatibilidad binaria
nentes que utilicen la compatibilidadbinaria (ver nota sobre que significa esode compatibilidad binaria), con idea deque le demos un aspecto más “profesio-nal” a nuestros componentes .NET, deforma que, entre otras cosas, los clientesque los usen no tengan que volver a sergenerados cada vez que hagamos cual-quier modificación.
En este aspecto, hay que tener cla-ro que Visual Studio (y por extensión.NET) no es un entorno COM, almenos en el sentido de que no es unentorno de desarrollo pensado para cre-ar componentes COM, por tanto no nosavisará de que hemos roto la compati-bilidad binaria, o lo que es lo mismo, nonos avisará de que las interfaces expues-tas han cambiado con respecto a la últi-ma generación que hicimos del compo-nente. Esto es algo que debemos ges-tionarlo nosotros. Este comentario estádedicado especialmente a aquellos desa-rrolladores que ya han hecho compo-nentes COM con Visual Basic 6.0, yaque el IDE de Visual Basic 6.0 sí nosavisa cuando rompemos la compatibili-dad binaria. De todas formas, ese avisolo tendremos cuando intentemos usarla aplicación cliente que se encargará demostrarnos un aviso “clásico” de que “Elcomponente ActiveX no puede crear elobjeto” tal como vemos en la figura 1,o de que el objeto no acepta esa pro-piedad o método, tal como se muestraen la figura 2.
El primer error (figura 1) lo recibi-remos si el componente no está regis-trado, mientras que el segundo (figura 2)lo recibiremos al acceder a un métodoque ya no está en el componente.
Crear componentes compa-tibles COM de forma “rápi-da” y no recomendable
Como hemos comentado, empeza-remos viendo lo que no tenemos quehacer, o al menos lo que “el autor” norecomienda que hagamos. ¿Por qué?Porque el Visual Studio crea una libre-ría de compatibilidad COM (librería detipos) que solo deberíamos usar parahacer pruebas rápidas, pero nada más.Esa librería de tipos solo expone losobjetos que podemos usar, es decir losnombres de las clases, pero no expone(realmente si los expone, pero como sino estuvieran), los métodos, propieda-des y eventos que definamos. Por tan-to, al usar esos métodos “tenemos quesaber que están”, ya que el Intellisense deVisual Basic 6.0 no nos mostrará esosmétodos, ni tampoco lo hará el exami-nador de objetos, tal como podemos veren la figura 3.
Para crear este tipo de componentedesde Visual Studio (cualquier versión),simplemente haremos lo siguiente:
1. Creamos un nuevo proyecto detipo Class Library (biblioteca declases).
2. Definimos un método público enla clase que se añade.
3. En las propiedades del proyectomarcamos la opción “Registrarpara interoperabilidad COM”.
4. En la información de “Ensamblado”debemos marcar “Crear ensambla-do visible a través de COM” o enAssemblyInfo usamos el atributoComVisible(true).
5. Generaramos el proyecto y se cre-ará tanto el ensamblado de .NETcomo la librería de tipos (.tlb).
6. Creamos una aplicación EXEestándar en VB6.
7. En “Referencias” añadimos unareferencia al componente COMque acabamos de crear con .NET.
8. Utilizamos la clase y el métodoque hemos expuesto desde .NET.
9. Lo ejecutamos y todo funcionarácomo esperábamos.
El código del componente de .NETpuede ser tan simple como el mostradoen el fuente 1.
En la aplicación cliente de VisualBasic 6.0 lo usaremos tal como mostra-mos en el fuente 2.
La única pega es que al intentarindicar el método al que queremosacceder, no nos mostrará los métodosdisponibles, por tanto debemos“saber” que la clase SaludoCS expone
Figura 1. Error al intentar usar uncomponente que no estáregistrado (o no existe)
Figura 2. Error al acceder a unmétodo no existente
Figura 3. El examinador de objetos deVB6 no muestra los miembros del
componente
namespace net2COMCS{
public class SaludoCS{
public string Saludar(){
return "Hola desde .NET (C#)";}
}}
Fuente 1.Clase de C# para usar comocomponente COM
Private Sub cmdSaludoCS_Click()Dim oCS As net2COM_1CS.SaludoCSSet oCS = New net2COM_1CS.SaludoCS
Me.Text1.Text = oCS.Saludar
End Sub
Fuente 2.Código de VB6 para usar la clase del fuente 1.
dotN
etM
anía
<<
42
dnm.inicio.taller<<
<< dnm.inicio.taller
43
<<do
tNet
Man
ía
un método llamado Saludar, porque,como ya hemos mencionado, elIntellisense de VB6 no sabe qué méto-dos expone la clase. Esto es lo que sellama late-binding o lo que es lo mis-mo “rezar y esperar que ese métodoexista”, ya que será en tiempo de eje-cución cuando se compruebe si elmétodo existe o no, que el método exis-te, entonces todo irá bien, que no exis-te y no interceptamos el posible error,obtendremos una pantallita de errorcomo la mostrada en la figura 2.
Crear un componente .NET queexponga los métodos a COM (entiempo de compilación)
Hacer que el componente de .NETexpuesto al mundo de COM muestrelos métodos que la clase expone es fácilde conseguir, ya que solo implica aña-dir un atributo a la clase o al ensambla-do completo:
ClassInterface(
ClassInterfaceType.AutoDual)
Con este atributo, el cliente COMpodrá “ver” los métodos expuestosdesde .NET, es decir, tanto el exami-nador de objetos de VB6 como elIntellisense mostrarán los métodospúblicos de nuestra clase, los cualesincluyen los que nosotros definamosademás de los heredados desde la cla-se Object. En la figura 4 podemos veruna captura del examinador de obje-tos de VB6.
Si después de añadir el atributoindicado volvemos a compilar el com-ponente, veremos que desde VB6 yapodemos ver los miembros expuestospor nuestra clase creada desde .NET,
y que Intellisense mostrará esos miem-bros, en este caso estaremos usando loque se conoce como early-binding o “loque ves es lo que hay”, y por tanto entiempo de compilación se compruebaque el método al que queremos acce-der existe en esa clase, de no ser así, laaplicación no se compilará, mostrandoun error como el que podemos ver enla captura de la figura 5, con lo que nosaseguramos de que no “venderemos”algo que no funciona.
Romper la compatibilidad binaria esfácil
Veamos que fácil es romper la com-patibilidad binaria, y cómo podemos“recuperarnos” de ese error.
Una vez que tenemos creado nues-tro componente de .NET y la librería detipos para que lo podamos usar desde uncliente de COM, no podemos hacermodificaciones a la clase que hemosexpuesto desde el componente. Por ejem-plo, no podemos cambiar el nombre delmétodo (o métodos) ni añadir o quitarninguno de los existentes.
Lo que si podemos hacer es añadirnuevas clases. Esas nuevas clases no afec-tarán a los clientes existentes y los nuevossí podrán usarlas, ya que en realidad lo quehace COM es crear una nueva interfazpara esas clases y seguir usando la que yahabía, por tanto, podemos mantener lacompatibilidad binaria con los clientesanteriores, la única pega es que para poderhacerlo debemos crear nuevas clases, nousar las existentes, pero como veremos enla siguiente parte, este “inconveniente” lopodemos solventar fácilmente.
Lo que sí podremos hacer en losnuevos clientes COM que usen el com-ponente modificado es usar tanto las cla-ses antiguas como las nuevas, pero si esasnuevas clases definen eventos, esos even-tos no los podremos usar desde VisualBasic 6.0.
El código usado para demostrarcómo romper la compatibilidad o cre-ar nuevas clases para mantener esa com-patibilidad binaria es el que podemosver en el fuente 3, en el que está comen-tado el código que rompería la compa-tibilidad binaria.
NOTA
Cuando marcamos la opción “Registrar para interoperabilidad COM” que enVisual C# 2005 está en la ficha “Generar” de las propiedades del proyecto, mientrasque en Visual Basic 2005 esa opción está en la ficha “Compilar”, y al marcarla se mar-ca también la casilla “Crear ensamblado visible a través de COM” y se añade el atri-buto ComVisible(true) en el fichero AssemblyInfo, sin embargo en C# tendremosque indicarlo manualmente. Por tanto debemos asegurarnos de que está activada esaopción, ya que solamente al tener las dos opciones marcadas es cuando se genera lalibrería de tipos que se usará desde el cliente COM.
][Figura 4. El examinador de objetos
de VB6 ahora muestra los miembros del componente
Figura 5. Error en tiempo decompilación al no encontrar el
método que queremos usar
NOTA
Cada vez que compilemos elcomponente desde Visual Studio,debemos tener cerrado el IDE deVisual Basic 6.0, ya que si lo dejamosabierto, no se podrá generar porque“otra aplicación lo está usando”. ][
Y el código que podríamos usar desde VB6 es elque vemos en el fuente 4.
Crear componentes de .NET paraCOM de forma recomendada
Veamos ahora qué es lo que debemos hacer paraque nuestro código de .NET genere librerías de tiposque mantengan la compatibilidad binaria.
Como hemos visto, todo el problema que nos sur-ge para poder mantener la compatibilidad binaria delcomponente COM o, mejor dicho, de la librería detipos, es porque cambiamos las interfaces que expo-nemos. Bueno, nosotros no cambiamos ninguna inter-faz, es el propio Visual Studio el que se encarga decrear esas interfaces o dicho de otra forma: es el VisualStudio el que crea las interfaces que se exponen aCOM.
La forma que tenemos nosotros de “controlar” loque se expondrá al cliente COM es creando las inter-faces que se expondrán, es decir, no dejando de lamano de Visual Studio la creación “automática” delas interfaces, o al menos interviniendo un poco enlas interfaces que se deben exponer a COM.
Cuando usamos el atributoClassInterface(ClassInterfaceType.AutoDual), la uti-lidad regasm (con el parámetro /tlb) genera automá-ticamente una interfaz para nuestro componente; esainterfaz está basada en la clase, es decir, incluyeTODOS los miembros que la clase defina, por tantolo que debemos hacer es indicarle que NO genere unainterfaz predeterminada, esto lo conseguimos usan-do ese atributo indicándole como argumento de lla-mada el valor ClassInterfaceType.None de esta formano generará una interfaz, por tanto debemos indicarnosotros la interfaz que queremos que se exponga aCOM. Esto es tan fácil como definir una interfaz conlos miembros a exportar e implementar esa interfazen nuestra clase.
En el fuente 5 tenemos la versión modificada delejemplo mostrado en el fuente 1 para que use unainterfaz de forma explícita.
Compilamos el ensamblado, (sin olvidar de expo-nerlo a COM), y podemos crear una versión de VB6 que
dotN
etM
anía
<<
44
dnm.inicio.taller<<
namespace net2COM2CS{
public class Saludo2CS{
public string Saludar(){
return “Hola desde .NET (C#) v2”;}
// Si añadimos nuevos métodos a la clase expuesta,// romperemos la compatibilidad binaria, // con lo que tendremos que volver a compilar el cliente COM//public string SaludoNombre(string nombre)//{// return “Hola “ + nombre + “ desde .NET (C#) v2”;//}
}
public class OtraClase{
// Los eventos no se muestran en el cliente COMpublic delegate void UnEventoEventHandler(string msg);public event UnEventoEventHandler UnEvento;
public string SaludoNombre(string nombre){
// Producimos el eventoif(UnEvento != null){
UnEvento(“Se usa el método SaludoNombre”);}
return “Hola “ + nombre + “ desde .NET (C#) v2.1”;}
}}
Fuente 3. El código de C# para crear nuevas clases y métodos en el componente
Private Sub cmdSaludoCS_Click()‘ El código anterior no necesita cambiosDim oCS As net2COM_2CS.Saludo2CSSet oCS = New net2COM_2CS.Saludo2CS
Dim otra As net2COM_2CS.OtraClaseSet otra = New net2COM_2CS.OtraClase
Me.Text1.Text = oCS.Saludar
MsgBox otra.SaludoNombre(“Guille”)
End Sub
Fuente 4. El código del cliente COM (VB6)
using System;using System.Runtime.InteropServices;
// Aplicando el atributo a nivel de ensamblado// no tenemos que aplicarlo en cada clase.[assembly: ClassInterface(ClassInterfaceType.None)]
namespace net2COM3CS{
public interface ISaludo3CS{
string Saludar();}
public class Saludo3CS : ISaludo3CS{
public string Saludar(){
return “Hola desde .NET (C#) v3”;}
}}
Fuente 5. La clase se expondrá con la interfaz que definimos
lo use. El código será similar al del fuen-te 2, salvo que ahora la clase (y el espaciode nombres) se llama de otra forma.
Añadir nuevos métodos y mantenerla compatibilidad binaria
Ahora viene la parte interesante:Añadir nuevos métodos a la clase y man-tener la compatibilidad binaria con losclientes anteriores.
Como hemos comentado, COM sebasa en las interfaces expuestas por loscomponentes, por tanto habrá compati-bilidad entre componentes siempre queno “rompamos” el contrato que hemosestablecido, y como ya sabemos (ver nº 16y 18 de dotNetManía) esos contratos loshacemos por medio de las interfaces, portanto, para mantener la compatibilidadcon el componente que ya hemos creado,y usado desde un cliente COM, debemosmantener la interfaz que el cliente COMespera encontrar, y la nueva funcionali-dad la debemos proporcionar por mediode otra interfaz.
Esa nueva interfaz debe exponer losmiembros anteriores además de los nue-vos, en nuestro ejemplo, vamos a aña-dir un nuevo método a la clase, por tan-to definiremos una nueva interfaz quecontenga los dos métodos, tal comovemos en el fuente 6.
En la misma clase que tenemos defi-niremos el nuevo método, pero tambiénindicaremos que ese método es el quedefine la interfaz, por tanto tambiéndebemos implementarla, sin olvidar deque la otra interfaz debe seguir siendoexpuesta. Aquí debemos usar un peque-ño truco, y ese truco consiste en definirprimero la nueva interfaz, y la antiguala definimos a continuación, tal comovemos en el fuente 7.
El hecho de definir la nueva interfazprimero es para que los nuevos clientesusen esa interfaz de forma predetermina-
da, de forma que puedan acceder a losmiembros expuestos por la misma, losclientes antiguos verán dos interfaces, perocomo no hacemos uso de la nueva, nohabrá ningún tipo de problema. De hechosi miramos los elementos expuestos porel componente en el examinador de obje-tos de Visual Basic 6.0, veremos que ade-más de la clase se muestra también la inter-faz antigua (ver figura 6).
Pero también veremos que solo seexponen los miembros definidos en lainterfaz, si lo comparamos con la figura4, comprobaremos que NO se incluyenlos miembros heredados de la clase Object,si queremos que esos métodos esténexpuestos (y disponibles desde COM),debemos incluirlos en la interfaz, tal comovemos en el código fuente 8.
Ni qué decir tie-ne que si hacemosese cambio despuésde haber compiladoel componente y elcliente COM, rom-peremos la compa-tibilidad binaria,por tanto ese nuevométodo debemosincluirlo en unanueva interfaz (en elZIP con el código
de ejemplo se utiliza este nuevo cam-bio desde VB6 como el proyectonet2COM_3_2VB6).
Utilizar eventos de .NETdesde un cliente COM
Los eventos definidos en los com-ponentes de .NET es otro de los temasque debemos considerar de forma espe-cial para poder exponerlos a COM. Sidefinimos un evento de la forma habi-tual en nuestro componente de .NET,veremos que en el cliente COM solo semuestra la definición del delegado, perono como un evento. De hecho, si que-remos usarlo desde Visual Basic 6.0,comprobaremos que no nos deja.
En VB6, para definir un objeto quecontiene eventos debemos declararlocon la instrucción WithEvents, y al usaresta instrucción, el IDE de VB6 com-probará si la clase que declaramos expo-ne o no eventos, si no los expone, obten-dremos un aviso de error como el mos-trado en la figura 7.
El aviso en realidad se producirá entiempo de ejecución, pero en tiempo dediseño, al “intentar” indicar el tipo, sim-plemente no nos mostrará nuestra clase,porque desde el punto de vista de COMesa clase no produce eventos.
Podemos intentarlo usando el atri-buto ClassInterface pasándole Class
dotN
etM
anía
<<
45
dnm.inicio.taller<<
public interface ISaludo3CS_2{
string Saludar();string SaludoNombre(string nombre);
}
Fuente 6. La nueva interfaz que vamos aexponer en nuestro componente .NET
// La interfaz más reciente debemos indicarla antes de la antiguapublic class Saludo3CS : ISaludo3CS_2, ISaludo3CS{
public string Saludar(){
return "Hola desde .NET (C#) v3 r1";}
public string SaludoNombre(string nombre){
return "Hola " + nombre + " desde .NET (C#) v3.1";}
}
Fuente 7. La clase debe implementar las dos interfaces
Figura 6. El examinador de objetos deVB6 solo muestra los métodos
definidos en la interfaz
public interface ISaludo3CS_2{
string Saludar();string SaludoNombre(string nombre);string ToString();
}
Fuente 8. La interfaz debe exponer todos losmiembros que queremos usar desde COM
Figura 7.Visual Basic 6.0 nos avisacuando no hay eventos en una clase
InterfaceType.AutoDual como argu-mento, que como sabemos creará unainterfaz de forma automática, con lo quemandaremos nuevamente al “garete”todo lo que hemos visto de “buenasprácticas”. Incluso desde el clienteCOM ese evento no se mostrará comotal, sino como dos métodos, tal comopodemos ver en la figura 8.
La solución es crear una interfazque defina los eventos que queremosexponer a COM, pero no solo nos bas-ta definir esa interfaz, sino que tam-bién debemos decirle a COM que loque esa interfaz define son eventos,además de que la clase también debe“firmar” el contrato, pero en esta oca-sión no lo hace implementando lainterfaz, ya que en realidad eso no esnecesario, (al menos desde el punto devista de .NET), sino por medio de unatributo que instruya a regasm que esaclase utilizará los eventos definidos enesa interfaz. ¿Un lío? Seguramente.Pero como veremos tiene su lógica, almenos desde el punto de vista deCOM que todo lo maneja por mediode interfaces.
Antes de ver el código que utiliza-ría esos eventos, veamos cómo pode-mos evitar que se exponga a COM ladefinición del delegado, ya que en rea-lidad no nos hace falta, al menos desdeel cliente COM. Esto mismo tambiénserá aplicable a todos los métodos públi-cos de nuestra clase que no queramosexponer a COM, (solo en el caso de queusemos el atributo ClassInterface conel valor AutoDual, ya que si usamos None,solo se expondrá a COM lo que defi-namos en las interfaces). A lo quevamos, para que el delegado no semuestre en el examinador de objetosdel cliente COM debemos aplicarle elatributo ComVisible(false):
[ComVisible(false)]
public delegate void
UnEventoEventHandler(string msg);
De esta forma le estamos indicandoa la utilidad regasm que no exponga la cla-se o método al que aplicamos ese atribu-to. Es importante que este atributo lo apli-quemos de forma “local” a cada uno delos elementos que NO queramos expo-ner a COM, pero el atributo definido enAssemblyInfo debe tener un parámetroverdadero, sino, no se creará una libreríade tipos de nuestro ensamblado.
Ahora pongamos junto todo lo indi-cado para que nuestro componente de.NET exponga eventos a un clienteCOM.
En el fuente 9 vemos el código de C#y en el fuente 10 tenemos el código deVisual Basic 6.0 que utiliza esos eventos.
Si desde Visual Basic 6.0 mostramosel examinador de objetos, (ver figura 9),comprobaremos que en realidad no hayninguna interfaz, y que el evento se mues-tra como parte de la clase.
Añadir más eventos a la clase y man-tener la compatibilidad binaria
Para ir terminando, veamos cómoañadir nuevos eventos a un componenteya existente, y, por supuesto, sin romperla compatibilidad binaria.
En este caso haremos como antes, esdecir, definir una nueva interfaz paraincluir los eventos que queremos expo-ner. Esa interfaz incluirá tanto los nue-vos eventos como los antiguos que que-ramos que las nuevas versiones sigan
dotN
etM
anía
<<
46
dnm.inicio.taller<<
Figura 8. Los eventos de .NET semuestran en COM como
dos métodos
NOTA
En Visual Basic 2005 podemos definir eventos sin necesidad de asociarloa un delegado, pero .NET creará ese delegado por nosotros y por tanto loexpondrá a COM, por tanto, si no queremos que se muestre el delegado defi-nido automáticamente por el compilador de Visual Basic para .NET, debe-ríamos definir los eventos de la forma “recomendada”, es decir, usando dele-gados. En el código de ejemplo incluido en el ZIP los eventos de Visual Basicestán definidos usando delegados.
][
Figura 9. El examinador de objetos deVB6 muestra el evento como
parte de la clase
...lo expuesto en este artículo es más que suficiente para que podamos crear componentes con .NET
para que puedan ser utilizados desde clientes COM
soportando, es decir, la nueva interfazincluirá los eventos que nos interese quelos “nuevos” clientes COM usen. Estomismo es aplicable a los métodos que que-ramos exponer a COM desde nuestrocomponente, ya que todo lo que esté enla nueva interfaz será lo que utilicen los“nuevos” clientes COM, lo de nuevos estáresaltado para que quede claro que losclientes anteriores seguirán usando lo queel componente exponía cuando se crea-ron las aplicaciones clientes.
Para indicar que ahora en vez de unainterfaz de eventos hay más, seguiremosaplicando el atributo ComSourceInterfacesa la clase, pero en vez de indicar una inter-faz de eventos, indicaremos las que haya-mos definido, poniendo como primerargumento la última que hemos definido,en nuestro ejemplo sería de esta forma:
[ComSourceInterfaces(typeof(net2COM4CS.ISaludo4_2Eventos),typeof(net2COM4CS.ISaludo4Eventos))]
public class Saludo4CS : ISaludo4CS {
Es decir, separamos cada interfaz(usando typeof) con una coma. De estaforma podemos indicar un máximo decuatro interfaces de eventos. Si queremosindicar más de cuatro, debemos usar elconstructor que recibe una cadena comoparámetro. Esa cadena permite una o másinterfaces, en caso de que haya más de una,
dotN
etM
anía
<<
47
dnm.inicio.taller<<
using System;using System.Runtime.InteropServices;
// Aplicando el atributo a nivel de ensamblado// no tenemos que aplicarlo en cada clase.[assembly: ClassInterface(ClassInterfaceType.None)]
namespace net2COM4CS{
// El delegado lo podemos ocultar a COM[ComVisible(false)]public delegate void UnEventoEventHandler (string msg);
// Los eventos no se muestran en el cliente COM// debemos indicarlos expresamente en una interfaz.
// Este atributo solo para exponer eventos[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]public interface ISaludo4Eventos{
void UnEvento(string msg);}
public interface ISaludo4CS{
string Saludar();string SaludoNombre(string nombre);string ToString();
}
// Debemos indicarle la interfaz en la que está definido del evento[ComSourceInterfaces(typeof(net2COM4CS.ISaludo4Eventos))]public class Saludo4CS : ISaludo4CS{
public event UnEventoEventHandler UnEvento;
protected void onUnEvento(string msg){
// Producimos el eventoif(UnEvento != null){
UnEvento(msg);}
}
public string Saludar(){
onUnEvento(“Evento desde el método Saludar”);
return “Hola desde .NET (C#) v4”;}
public string SaludoNombre(string nombre){
onUnEvento(“Evento desde el método SaludoNombre”);
return “Hola “ + nombre + “ desde .NET (C#) v4.1”;}
public override string ToString(){
onUnEvento(“Evento desde el método ToString”);
return “ToString de la clase Saludo4CS”;}
}}
Fuente 9. El código de C# que define una clase que produce eventos
Private WithEvents mCS As net2COM_4CS.Saludo4CS
Private Sub cmdSaludoCS_Click()
List1.Clear
Text1.Text = mCS.Saludar
Text2.Text = mCS.SaludoNombre(txtNombre.Text)
Text3.Text = mCS.ToString
End Sub
Private Sub Form_Load()Set mCS = New net2COM_4CS.Saludo4CS
End Sub
Private Sub mCS_UnEvento(ByVal msg As String)List1.AddItem msg
End Sub
Fuente 10. El código de VB6 que utiliza un componentede .NET que produce eventos
separaremos cada una de ellas con un valornulo, por ejemplo:
[ComSourceInterfaces(“net2COM4CS.ISaludo4_2Eventos\
0net2COM4CS.ISaludo4Eventos”)]
Consideraciones finalesCreo que lo expuesto en este artí-
culo es más que suficiente para quepodamos crear componentes con.NET para que puedan ser utilizadosdesde clientes COM, como es el casode Visual Basic 6.0, y usarlos de la for-ma correcta, sin que el crecimiento denuestro componente interfiera con losclientes que ya están usando las ver-siones anteriores. Ni qué decir tieneque todo lo aquí explicado es para loscasos en que necesitemos ampliar lafuncionalidad del componente y per-mitir que los clientes que ya estánusando los componentes anterioressigan funcionando a las mil maravi-llas. Pero debemos tener en cuentaque hay ciertas características de.NET que COM no sabe manejar,como es el caso de la sobrecarga, yasea de métodos, constructores u ope-radores. Por tanto debemos saber losiguiente:
• Las clases de los componentes de.NET siempre deberían inlcuir unconstructor público sin parámetros.Si no lo definimos, no podremoscrear nuevos objetos de esa clase, ysi esa clase es la única expuesta porel componente, no se generará lalibrería de tipos.
• Cuando existen sobrecargas demétodos, en COM se utilizan
nombres diferentes para cada unade las sobrecargas. El orden en elque se declaren esas sobrecargasen la interfaz indicará el nombreque se usará en COM. El prime-ro no cambiará, pero cada sobre-carga se nombrará con un guiónbajo seguido de un número,empezando con 2. Por ejemplo:Mostrar, Mostrar_2, Mostrar_3, etc.También podemos definir en lainterfaz el nombre que queremosque se exponga a COM y lo pode-mos definir en la clase de .NETcomo queramos, sin embargo enVB es más fácil crear este “enga-ño” ya que las implementacionesde los miembros de una interfazse hace de forma explícita. En losproyectos numerados como prue-ba 5 que se incluyen en el ZIP delcódigo hay ejemplos para vercómo solventar estos casos.
• Si indicamos arrays como pará-metros, éstos deben estar decla-rados por referencia (ref en C#,ByRef en VB).
Cuando creemos nuevas versionesde los componentes de .NET es muyimportante que NO cambiemos laversión del ensamblado, ya que si lohacemos no se mantendrá la compa-tibilidad binaria. Si debemos hacerlo,lo recomendable es mantener la com-patibilidad con la versión del compo-nente COM mediante el atributo:ComCompatibleVersion al que le indi-caremos en el constructor la versióndel ensamblado original, por ejemplo:
[assembly: ComCompatibleVersion(1, 0, 0, 0)]
También es importante indicar ladescripción del ensamblado de .NET,ya que esa descripción será la que se usea la hora de añadir la referencia en laaplicación del cliente COM, tal comopodemos ver en la figura 10.
Conclusiones
La ventaja de crear componentesCOM desde .NET es que en el códigode las clases que expongamos podemosusar todos los tipos soportados por.NET, incluso los tipos y coleccionesgénericas, si bien, como es lógico pen-sar, los tipos de datos expuestos públi-camente deben ser tipos que COMconozca, aunque esto no implica queinternamente no nos aprovechemos delas ventajas de los tipos que el propio.NET define.
El código incluido en el ZIP con-tiene proyectos tanto para VisualBasic 2005 como C# 2005, aunquetodo lo explicado se puede usar tam-bién en las versiones anteriores deVisual Studio, también se incluye elcódigo de ejemplo de las diferentesversiones de Visual Basic 6.0 y laexplicación correspondiente parapoder generar paso a paso las distin-tas versiones de los componentesexpuestos a COM.
Confío en que todo lo explicado seade utilidad para poder actualizar esosproyectos que se resisten a dejar el mun-do COM para convertirlos definitiva-mente al mundo .NET.
dotN
etM
anía
<<
48
dnm.inicio.taller<<
Figura 10. Lo que indiquemos en ladescripción del ensamblado es lo que
se mostrará en las referencias
La ventaja de crear componentes COM desde .NET es que en el código de las clases que expongamos podemos
usar todos los tipos soportados por .NET, incluso los tipos y colecciones genéricas
dotN
etM
anía
<<
49
Web que visito regularmente mues-tran información actualizable desde otros sitios: porejemplo noticias deportivas. No creo que ninguno demis clientes realmente quisiera tal tipo de servicio perosí que pienso que la importación de datos externos des-de otros sitios Web sería una poderosa característicaa considerar.
Hasta donde yo sé, hay dos formas típicas deimplementar algo similar. Una consiste en utilizar unservicio Web para obtener cualquier informacióncontractual expuesta por el sitio. Esto significa, sobretodo, algún tipo de acuerdo entre las dos partes.Cuanta más información valiosa, más tendrás quepagar por ella, probablemente. Desde un punto devista tecnológico, simplemente se accede a la infor-mación de entrada (normalmente, cadenas), y la mues-tras en la forma adecuada. El segundo enfoque, supo-ne suscribirse a algún origen de datos RSS. Es unsitio que expone información publicable y la hace dis-ponible, virtualmente a cualquier cliente, gratis. Eneste caso, abres un socket hacia el destino RSS, obtie-nes la información –una cadena XML– y la incorpo-ras en tus páginas.
En ambos casos, un acuerdo implícito o explí-cito existe entre tu sitio y el del origen de la infor-mación. Pero, para decirlo todo, existe un tercerenfoque: el clásico Screen-scrapping. Aunque nacidahistóricamente en mainframes hace 25 años, la téc-nica recobró actualidad con el advenimiento de laspáginas Web. Consiste en la posibilidad de descar-gar una página completa y analizarla para extraer lainformación válida. Por ejemplo, se puede descar-gar una página de cotizaciones de bolsa, y mostrarsolo aquellas en las que estás interesado. Se anali-zan los contenidos eliminando todo menos los 3 ó4 valores a buscar.
Si el sitio Web de origen no tiene una oferta RSS,ésta sería mi opción predilecta. Screen-scrapping debe-ría considerarse únicamente como último recurso.Para leer orígenes RSS, se utilizan típicamente herra-mientas como RssBandit o SharpReader. ¿Cómopodrías leer uno de estos orígenes en una páginaASP.NET? Lo que muchos sitios Web hacen (inclu-yendo las páginas MSDN) es utilizar un control deusuario compuesto. La clave de este control, conten-dría un código similar al del fuente 1.
La variable text contiene la salida del origen enformato XML. El contenedor ProcessFeed recorrelos elementos XML y construye un texto imprimi-ble en HTML. Si seleccionamos una aproximaciónmás elegante, podríamos devolver un array de obje-tos personalizados a partir de ProcessFeed que sola-mente almacenaran líneas individuales para ser trans-formadas en lenguaje de marcas posteriormente. Elcódigo del fuente 2 muestra cómo construir una lis-ta de enlaces a los últimos “posts”.
Para leer orígenes RSS, se utilizan típicamente herramientas comoRssBandit o SharpReader. ¿Cómo
podrías leer uno de estos orígenes en una página ASP.NET? Lo que
muchos sitios Web hacen es utilizarun control de usuario compuesto
Cuestiones sobre ASP.NET
Dino Esposito
dnm.todotnet.qa
<< Algunos de los sitios
Dino Esposito es mentor de Solid Quality
Learning y autor de “ProgrammingMicrosoft ASP.NET 2.0 CoreReference” y “Programming
ASP.NET 2.0 Applicatinos AdvancedTopics”, ambos de Microsoft
Press.Afincado en Italia,Dino esun ponente habitual en los
eventos de la industria a nivelmundial.Visita su blog en:
http://weblogs.asp.net/despos.Puede enviarle sus consultas aTodotNet.QA@dotnetmania.com
“
”
Este mes responderemos algunas preguntas relacionadas con el desarrollo Web yASP.NET en particular. Las cuestiones abordan temas que van desde la importaciónde datos de fuentes externas y sitios Web,hasta tareas asíncronas y la representaciónde imágenes almacenadas en bases de datos.
dotN
etM
anía
<<
50
dnm.laboratorio.net<<
Este código puede ser fácilmente incorporado enun control de usuario compuesto hecho a partir deuna tabla o rejilla.
He construido varias soluciones utilizando tareasasíncronas, pero reconozco que no he prestado dema-siada atención al término I/O bound (vínculo).¿Significa esto que cualquier operación asíncrona noestrictamente relacionada con entrada/salida es per-niciosa?
Cualquier operación puede ser fácilmente cata-logada en dos formas: vinculada a la CPU o a unproceso de entrada/salida. En el primer caso, eltiempo de compleción está determinado por lascaracterísticas de la propia CPU y la memoria dis-ponible. En el otro, la situación es radicalmentedistinta, y la CPU espera –la mayor parte del tiem-po– a que los dispositivos de entrada/salida termi-nen su trabajo.
Ahora bien, ¿cuál es el objetivo último de un pro-ceso asíncrono? Un empleo típico es cuando necesi-tamos que nuestra interfaz de usuario no se “conge-le” mientras termina algún proceso en background, delarga duración potencial. En este sentido, no hay nin-guna diferencia importante entre los dos tipos de ope-raciones. Esto es correcto en tanto que estemos con-siderando escenarios de “clientes ricos”, como apli-caciones Windows Forms. Para aplicacionesASP.NET las cosas son algo distintas. Si has escritoese código para aplicaciones Windows no debe dehaber problema.
¿Qué operaciones son buenos candidatos a imple-mentarse como páginas Web asíncronas? Para decir-lo en otra forma, ¿qué operaciones requieren, o almenos, sugieren claramente la adopción de páginasasíncronas en una aplicación ASP.NET? Intentemosformalizar brevemente el concepto de proceso asín-crono dentro del contexto de ASP.NET.
La necesidad del proceso asíncrono deriva de un tiempo excesivo en el
tráfico de la información deentrada/salida, respecto del tiempo de proceso.
“”
Cualquier operación puede serfácilmente catalogada en dos for-mas: vinculada a la CPU o a un
proceso de entrada/salida
“”
string ProcessFeed(string feed){StringBuilder sb = new StringBuilder();
XmlDocument doc = new XmlDocument();doc.LoadXml(feed);
XPathNavigator nav = doc.CreateNavigator();XPathNodeIterator iterator;
// Title and descriptioniterator = nav.Select(“/rss/channel/title”);iterator.MoveNext();sb.AppendFormat(“<h3>{0}</h3>”,iterator.Current.Value);iterator = nav.Select(“/rss/channel/description”);iterator.MoveNext();sb.AppendFormat(“<i>{0}</i>”, iterator.Current.Value);
XmlNodeList items=doc.SelectNodes(“/rss/channel/item”);sb.Append(“<ul>”);foreach(XmlNode n in items){
XmlNode title = n.SelectSingleNode(“title”);XmlNode link = n.SelectSingleNode(“link”);XmlNode date = n.SelectSingleNode(“pubDate”);sb.AppendFormat(“<li><a href=\”{0}\”>{1}</a> on {2}</li>”,
link.InnerText, title.InnerText, date.InnerText);}sb.Append(“</ul>”);
return sb.ToString();}
WebRequest req;string rssData = String.Empty;req = WebRequest.Create(RSSFEED);using (WebResponse response = req.GetResponse()){
StreamReader reader;string text = String.Empty;using (reader = new
StreamReader(response.GetResponseStream())){
text = reader.ReadToEnd();}
// Process the RSS datarssData = ProcessFeed(text);
}
Fuente 1
Fuente 2
dotN
etM
anía
<<
51
dnm.laboratorio.net<<
La necesidad del proceso asíncrono deriva de untiempo excesivo en el tráfico de la información deentrada/salida, respecto del tiempo de proceso. Entales situaciones, la CPU está en estado de espera oes infrautilizada la mayor parte del tiempo, esperan-do que algo suceda. Y en particular, en las operacio-nes de entrada/salida en el contexto de ASP.NET, por-que los subprocesos en servicio están bloqueados tam-bién y el pool de servicio de subprocesos es un recur-so finito y crítico.
Se obtienen mejoras en el rendimiento si se uti-lizan modelos asíncronos en operaciones deentrada/salida. En la implementación de .NETFramework, cuando se hace una llamada asíncronano existen subprocesos bloqueados mientras la ope-ración está pendiente.
Ejemplos típicos de operaciones de entrada/sali-da son todas las operaciones que requieren acceso aalgún tipo de recurso remoto o que interaccionancon dispositivos hardware externos. Las operacionessobre bases de datos o servicios Web no locales, sonlas más comunes para considerar la creación de pági-nas asíncronas.
En ASP.NET, las operaciones de larga duraciónde CPU (por ejemplo, algún algoritmo que requieraactuar sobre datos en memoria) son también buenascandidatas a una implementación asíncrona para man-tener en número de subprocesos administrados en unnivel suficientemente alto. En este caso, sin embar-go, todavía está recargada con algo de trabajo, y laganancia de rendimiento es menor que en las opera-ciones de entrada/salida.
En suma, cualquier tarea de larga duración debe-ría de ser llamada de forma asíncrona, tanto enWindows como en ASP.NET. En este último caso,sin embargo, es particularmente importante en losprocesos de entrada/salida. Si uno de estos procesos(por ejemplo, la llamada a un servicio Web), es imple-mentado de forma asíncrona, la CPU del servidor nose ve afectada, y puede procesar con prontitud otraspeticiones. Para operaciones vinculadas a la CPU,también las llamadas asíncronas pueden ofrecer algode mejora en Windows, al ejecutarse en un subpro-ceso diferente. Para aplicaciones ASP.NET, sin embar-go, no debieran esperarse grandes mejoras. Siemprees mejor la llamada asíncrona pero las páginas se mos-trarán lentamente, ya que la CPU tiene que realizarun gran trabajo para generarlas. Una aproximaciónmás eficaz sería separar las operaciones de larga dura-ción a un servidor remoto y transformar la tarea tipoCPU en una del tipo entrada/salida.
En los primeros días de ASP.NET 2.0 –trabajocon ella desde las primeras versiones alpha, en vera-no de 2003– podía referenciar fácilmente imágenesalmacenadas en una base de datos SQL Server usan-do control a medida –el control <asp_
DynamicImage>–. Este control, fue eliminado en pos-
teriores releases y en la versión final. Sin embargo, elproblema que me condujo a esa situación al principiono desaparece. ¿Cómo puedo construir mi propio con-trol de imagen dinámico en ASP.NET 2.0?
En ASP.NET, dispones de dos controles de servi-dor para mostrar imágenes: Image y HtmlImage. Amboscontroles suministran un ligero nivel de abstracciónsobre algunas de las propiedades del elemento <img>de HTML. Ambos controles, en definitiva, solo per-miten referenciar imágenes vía URL, y estableceralgunos atributos de presentación.
Como sugieres, en el mundo real, los gráficos pue-den venir de una gran variedad de orígenes. Por ejem-plo, pueden provenir de un fichero, se pueden leer apartir de un campo de una base de datos, o se puedengenerar dinámicamente en memoria utilizando unaAPI gráfica. Solo en el primer caso –el del fichero endisco– podemos aplicar adecuadamente el elemento<img> y el API de ASP.NET. En todos los otros casos,los programadores deben escribir su propio códigopara conseguirlo. Veamos cómo.
El hecho es que, cualquiera que sea el origen dela imagen a mostrar, sólo puede incluirse en una pági-na a través del elemento <img> y, por consiguiente, víaURL. Toda la lógica empleada para obtener la ima-gen, debe de ser embebida en código accesible a tra-vés de una URL. En ASP.NET, la URL puede apun-tar a un manejador HTTP personalizado. El controlDynamicImage, de hecho, se apoya en el manejadorcacheimageservice.axd, un manejador incrustado queha sido liberado de la plataforma en alguna manera.
En ASP.NET 2.0, comienzas por crear un mane-jador análogo HTTP y diseñarle para aceptar en lacadena de consulta cualquier información que puedaser útil para identificar la imagen y su origen. El vie-jo control DynamicImage encapsulaba mucha de estainformación (cadenas de conexión, consultas, ID) ensus propios parámetros, aislando, por tanto, el mane-jador HTTP subyacente del desarrollador. Este mane-jador ejecutará cualquier código necesario para obte-ner los bytes de la imagen, establecer el tipo MIMEapropiado y devolver los bytes. Para evitar consultasrepetitivas y algunos ciclos de CPU, el manejadorHTTP puede almacenar imágenes en el caché y acce-der a ellas la próxima vez que se necesiten.
To
do
tNet.
qa@
do
tnetm
an
ia.c
om
To
do
tNet.
qa@
do
tnetm
an
ia.c
om
Traducción por Marino Posadas
cualquiera que sea el origen de laimagen a mostrar, sólo puede
incluirse en una página a través del elemento <img> y, por
consiguiente, vía URL
“”
Lorenzo Ponte
Lorenzo Ponte es redactor dedotNetManía. Es Arquitecto de
Sistemas y Aplicaciones .NET.Experto en Datawarehousing yBusiness Intelligence,Marketing
Intelligence,CRM analítico.Actualmente es consultor de la
empresa Matchmind yWebmaster de clikear.com
En este número el laboratorio de dotNetManía analiza tres componentes queahorrarán mucho trabajo al programador a la hora de desarrollar. El primero deellos evita que las direcciones de correo electrónico presentes en sitios Web seanescaneadas por robots, el siguiente ofrece la posibilidad de adaptar elementosgráficos a cualquier plataforma bajo demanda, y para terminar, un componenteque permite automatizar un versionado de ficheros XML.
Ya hemos hablado en el laboratorio de dotNet-Manía sobre la existencia de bots o robots dedicadosa escanear páginas en Internet con el objetivo decopiar direcciones de correo electrónico para luegosaturarlas de correos basura, mas comúnmente lla-mado spam.
Para que esto no ocurra en vuestras aplicacionesASP.NET el laboratorio de esta semana os proponeutilizar este HttpModule. Su función es la de codifi-car las direcciones de correo electrónico presentesen las páginas, evitando así que sean reconociblespara los bots.
Basta con añadir la DLL CodeArchitects.SafeMailLink.dll en el directorio /bin de vuestra aplicación yañadir las siguientes líneas de código en el web.config:
Los indeseados bots pasarán delargo al intentar escanear vuestrosportales.
Ficha técnicaNombre SafeMailLink HttpModule
Versión 1
Fabricante .Net2TheMax Team
Webhttp://www.dotnet2themax.com/ShowContent.aspx?Type=freeware&ID=35efbee1-d8cd-4720-9eb2-83fc9a4033bb
Categoría Seguridad
Precio Gratis
Valoración
<< SafeMailLink HttpModule
<httpModules><add name="SafeMailLinkModule"type = "CodeArchitects.SafeMailLink.SafeMailLinkModule, CodeArchitects.SafeMailLink" />
</httpModules>
Uno de los problemas a los se enfrentan las apli-caciones multiplataforma es el de adaptar los elemen-tos gráficos a todos los entornos donde se van a mos-trar, PC, PDA, Móvil. Para minimizar estos proble-mas el laboratorio de dotNetManía analiza este com-ponente que permite jugar con cualquier tipo de ele-mento gráfico trasformándolo a vuestro antojo y todobajo código .NET.
Este componente proporciona la posibilidad demodificar las propiedades on-line de las imágenes.
Es capaz de cambiarlas el formato, las dimensiones,rotar, crear miniaturas. Todo bajo demanda.
Hecktech.ImageHandler
Ficha técnicaNombre Hecktech.ImageHandlerVersión 1.0Fabricante heckTechWeb http://www.hecktech.com/Products/ImageHandler.aspxCategoría Utilidades
Precio 125.00$
Valoración
<<
dotN
etM
anía
<<
53
El formato de datos XML se esta imponiendocada vez mas en las aplicaciones de hoy en día. Losprincipales beneficios que aporta este tipo de alma-cenamiento son el poder adaptar y comunicar nues-tras aplicaciones con cualquier plataforma, y el aho-rro de coste cuando nos enfrentamos a una migra-ción hacia otros entornos. Los XML suelen con-vertirse en archivos bastante extensos donde sumanejabilidad llega en ocasiones a ser bastante difi-cultosa. Por ello es necesario disponer de herra-mientas diseñadas para facilitar el manejo de estosarchivos.
Microsoft XML Diff and Patch 1.0 es una herra-mienta que nos ayuda a comparar dos archivos XMLcon el fin de identificar si se hay diferencias entreellos. Estos cambios pueden ser tanto a nivel deestructura como a nivel de datos. Está especialmen-te indicado para detectar cambios de versiones yactualizaciones de ficheros.
Permite configurar diferentes tipos de barridoscomparativos. Podemos especificar que no tengaen cuenta algunos aspectos del xml a la hora de com-parar, como los espacios en blanco, los comenta-rios, prefijos. Incluso elementos o atributos dentrodel XML.
A continuación se muestra un ejemplo en el quese comparan dos XML con Microsoft XML Diffand Patch 1.0 y la respuesta de la herramienta.
Diagrama de resultado Microsoft XML Diff andPatch 1.0:
Ficha técnicaNombre Microsoft XML Diff and PatchVersión 1.0Fabricante MicrosoftWeb http://apps.gotdotnet.com/xmltools/xmldiffCategoría XMLPrecio GratisValoración
Microsoft XML Diff and Patch 1.0<<
<?xml version="1.0"?> <Datos><Empleado><Nombre>Lorenzo Ponte</Nombre> <Direccion>Pez</Direccion><Telefono>
<Fijo>91 12345678</Fijo> <Movil>650 44 44 44</Movil> </Telefono>
</Empleado><Empleado><Nombre>Pedro Pozo</Nombre> <Direccion>Gran Via</Direccion> <Telefono>
<Fijo>91 9192121</Fijo> <Movil>650 55 44 44</Movil> </Telefono>
</Empleado></Datos>
XML Versión 1
<?xml version="1.1"?><Datos><Empleado><Nombre>Lorenzo Ponte</Nombre> <Direccion>Pez2</Direccion><Telefono>
<Fijo>91 12345678</Fijo> <Movil>650 44 44 44</Movil> </Telefono>
</Empleado><Empleado><Nombre>Pedro Pozo</Nombre> <Direccion>Gran Via</Direccion> <Telefono>
<Fijo>91 9122121</Fijo> <Movil>650 35 55 55</Movil> </Telefono>
</Empleado></Datos>
XML Versión 1.1
<xd:xmldiff version=”1.0”srcDocHash=”2153503709764626935”options=”None”fragments=”no” >
<xd:node match=”2” ><xd:node match=”1” ><xd:node match=”2” ><xd:change match=”1” >Pez2</xd:change>
</xd:node></xd:node><xd:node match=”2” ><xd:node match=”3” ><xd:node match=”1” ><xd:change match=”1” >91 9122121</xd:change>
</xd:node><xd:node match=”2” ><xd:change match=”1” >650 35 55 55</xd:change>
</xd:node></xd:node>
</xd:node></xd:node>
</xd:xmldiff>
dnm.laboratorio.net
dotN
etM
anía
<<
54
<<
Professional C#.2ª EdiciónSimon Robinson, et. al.
Editorial: Wrox-DanyPressISBN: 8493272027Páginas: 1.171Publicado: Primera edición 2002Idioma: Castellano
Revisamos en este número dos clásicos del desarrollo .NET traducidos y editados enEspaña por DanyPress. En primer lugar, una de las obras más vendidas sobre el lenguajeC#, debidamente traducido y revisado para su segunda edición. Simon Robinson, y unextenso grupo de colaboradores, recorren todos los contenidos fundamentales de la pla-taforma .NET Framework, y lo hacen a la luz de este lenguaje, en el que se demuestrantodos los ejemplos del libro.
Es la típica obra exhaustiva que lo recorre todo, pero que tiene el mérito de hacerlo en for-ma suficientemente detallada como para servir de punto inicial a cualquier problema de desa-rrollo. Uno de los clásicos de la versión 1.1.
Iniciación a VB.NET Bases de DatosBill Forgey,Denise Gosnell,Matthew Reynolds
Editorial: Wrox-DanyPressISBN: 8493272000Páginas: 632Publicado: Primera edición 2002Idioma: Castellano
La segunda obra que seleccionamos dentro de los buenos clásicos de este mes es -sinduda- una de las más agradecidas por los programadores, y -curiosamente- debido a locontrario de su antecesor: la especificidad. Utilizando VB.NET como lenguaje de refe-rencia, analiza con la profundidad necesaria los mil y un intríngulis que nos aparecenen el desarrollo diario respecto al tratamiento de datos. Desde la introducción inicial almodelo relacional, hasta el capítulo final de integración de una solución B2B con XML,nos pasea por las entretelas de ADO.NET y aborda muchos de los problemas diarioscon que nos topamos, sin olvidar lo que, al final, nos da el control de la situación: lo queocurre “entre bastidores”. En suma, una de las buenas obras que el lector encontrará ennuestro idioma dedicadas al tema.
dnm.biblioteca.net<<
dnm.biblioteca.net
dnm.club >>> dnm.club >>> dnm.club >>> dnm.club >>>[ ]
dnm.club >>> dnm.club >>> dnm.club >>> dnm.club >>> dnm.club >
Herramientas de soporte técnico de Windows XP ServicePack 2. Aunque se presentan para usuarios avanzados, esuna de esas cosas que todos deberíamos tener en un “cajónde recursos”. Incluyen una larguísima lista de utilidades(muchas de ventana de comandos). Recomendable su des-carga en http://www.microsoft.com/downloads/details.aspx?dis-playlang=es&FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38 (versión de la página en castellano).
Anunciadas las (¡ocho!) versiones de Windows Vista
Microsoft ha publicado de forma oficial las edicionesdisponibles del próximo sistema operativo heredero deWindows XP, que, según rumores, podría estar disponiblepara primeros de octubre de este año. Son muchas, y pue-den analizarse en la página: http://windowshelp.microsoft.com/Windows/en-US/help/c0680472-bb5f-4a9c-9480-b16ab3eeb8f51033.mspx1. No se trata de una breve descrip-ción, como podrá rápidamente comprobar el lector; se tra-ta de una navegación detallada por todos los aspectos de cadauna de las distintas ediciones que estarán disponibles. Existenediciones para el hogar, para el negocio, y una muy com-pleta, llamada Windows Vista Ultimate, junto a dos ver-siones especiales, llamadas Windows Vista Home Basic
N y Windows Vista Business N, donde la N significa lite-ralmente: “No incluye Windows Media Player”. Y, a pro-pósito de entretenimiento, contendrá dos nuevos juegos deforma predeterminada: Mahjong Titans y Purble Placeun juego educativo de reconocimiento de patrones y for-mas. Pero solo el análisis de las novedades respecto a ver-siones anteriores, llevaría varios números de la revista.
Disponible Microsoft® Visual Studio® 2005 Extensions forWindows Workflow Foundation Beta 2
Desde finales de enero seencuentra disponible en la páginah t t p : / /www.mi c r o s o f t . c om/downloads/details.aspx?FamilyId=A2151993-991D-4F58-A707-5883FF4C1DC2&displaylang=en,la extensión que da título a estanoticia y que permite trabajarcon uno de los subsistemas fundamentales de WindowsVista. Igualmente, en la página
http://www.microsoft.com/downloads/details.aspx?FamilyId=5A0AE4CD-DC79-4B12-8A05-B6195F89FFA2&displaylang=enpodemos descargar Microsoft Visual Studio Code Name“Orcas” Community Technology Preview - DevelopmentTools for WinFX®, y existe todo un conjunto de des-cargas relacionadas.
dotN
etM
anía
<<
58
dnm.desvan<<
Marino Posadas
Hacking Windows XP: Se trata del octavo capítulo deeste libro, donde se nos explica cómo hacer que el tiempode carga de XP se reduzca en cantidades considerables.Puede leerse en la dirección: http://www.extremetech.com/arti-cle2/0,1558,1785996,00.asp?kc=ETRSS02129TX1K0000532
Documentos en la Red Utilidades del mes
no
ticia
s.n
oti
cia
s.n
oti
cia
s
Bart's PE Builder. Herramienta para construir dispositivos“Bootable Windows”, desde una unidad externa o desdeun CD o DVD, para Windows XP o Windows Server2003. Muy útil para administradores de sistemas o -sim-plemente- para aquellos que nos gusta jugar con parti-ciones y cambiar a menudo la configuración del sistema.Disponible en http://www.nu2.nu.
“Preparing for Indigo: Choosing the Right TechnologyToday”: Es un artículo del conocido conferenciante JuvalLowy disponible en http://www.code-magazine.com/Article.aspx?quickid=0503031, como anticipo de tecnologí-as inminentes y con destino a responsables de IT y desa-rrolladores en general.
Utilidades del grupo DonationCoders. Se trata de un sitio de utili-dades, más que de una sola en concreto. Algunas de ellas, muysimples, pero muy útiles. TODO (lista de tareas), Addy (libretade direcciones), y un conjunto de utilidades del sistema. Todoello accesible en la dirección http://xhirl.donationcoders.com/main.php.
Recomendamos esta vez dos sitios dedicados exclusivamenteal lenguaje C#: Public Joe's C# Snippets (http://www.public-joe.f9.co.uk/csharp/snip/snippets.html) que incluye opcionespara varios lenguajes pero ha recopilado algunos de los men-sajes más interesantes de los foros “oficiales”, y la sección“Preguntas Frecuentes” del sitio público de noticias deC# (http://www.yoda.arachsys.com/csharp/faq).
Sitios del mes
1 Al momento del cierre de la edición, esta dirección parece haber sido retirada y hay rumores sobre si los nombres previamente publiciados serán los definitivos.