viernes, 1 de septiembre de 2006

Recursos incrustados y propiedades extendidas

Los recursos incrustados (embedded resources in inglish) son un mecanismo que nos permite incluir ficheros dentro de un ensamblado. Constituyen una forma limpia y eficaz de distribuir ficheros con una aplicación, cuando no queremos que dichos ficheros pululen por el directorio de la aplicación y puedan por tanto ser chafardeados por los juanquercillos de turno (deberán ser juanquers de cierta categoría si quieren ver algo).

Incluir recursos incrustados desde Visual Studio 2005 es muy sencillo: basta agregar (o crear) los ficheros deseados en el proyecto, abrir la ventana de propiedades de los mismos, y en Acción de generación seleccionar Recurso incrustado. Para recuperar estos ficheros una vez generado el ensamblado, viene al rescate la clase Assembly, en concreto sus métodos GetManifestResourceNames y GetManifestResourceStream.

Veamos un ejemplo. Tomemos un proyecto chorra tal que este:


Supongamos que queremos que todo lo que hay bajo el directorio DatabaseChangeScripts se almacene en el ensamblado como recursos incrustados. No tenemos más que seleccionar todos los ficheros (ya sabes, Shift o Ctrl y clics a discteción), botón derecho, propiedades y:


El siguiente código muestra cómo obtener la lista de todos los recursos incrustados del ensamblado:

Si copias este código en el método Main de Program.cs, al ejecutar el proyecto desde el propio Visual Studio verás lo siguiente en la ventana de resultados:


Fíjate en el interesante detalle de que la jerarquía de carpetas se mantiene en el nombre del recurso. Esto da pie a numerosas e interesantes piruladas, como la que os voy a mostrar ahora. Pero antes, veamos cómo recuperar el contenido de un recurso incrustado una vez conocido su nombre:

En este caso, suponemos que el recurso en cuestión es un fichero de texto, por tanto ponemos su contenido en una cadena.

Pues bien, una estructura como la del ejemplo es la que yo uso para mantener un control de versiones en la base de datos que usan las aplicaciones en las que trabajo. Cada vez que necesito hacer un cambio con respecto a la estructura que tiene la base de datos ya instalada al cliente, creo una nueva carpeta de versión y pongo dentro todas las secuencias de comandos SQL necesarias para la actualización. Al inicio de la aplicación compruebo la versión de la base de datos, y si no es la última, leo las secuencias de comandos incrustadas y las ejecuto, tras lo cual actualizo el número de versión de la base de datos (por supuesto, todo con las pertinentes transacciones de por medio, de forma que nunca queden actualizaciones a medias).

Para guardar el número de versión en la base de datos uso una propiedad extendida. Las propiedades extendidas de SQL Server son atributos globales a nivel de base de datos, no dependen de ninguna tabla ni procedimiento almacenado y constan de un nombre y un valor (en realidad ambién es posible establecer propiedades extendidas para otros objetos, no sólo para las propias bases de datos).

Para crear una propiedad extendida hay que usar el siguiente procedimiento almacenado del sistema (el nombre y el valor son ejemplos):

Para borrar una propiedad extendida existente:

Para modificar el valor de una propiedad extendida:

Finalmente, para consultar el valor de una propiedad extendida:

Si tienes el SQL Server Management Studio, también puedes controlar las propiedades extendidas visualmente, mediante la ventana de propiedades de la base de datos:


Pues hala, dada la tremenda utilidad de los recursos incrustados, incrustaos bien esta parrafada en el cerebro (¿lo pillais? ¿Lo pillais? Bueno, al menos no me pegueis muy fuerte...)