La caché de ASP.NET es una maravilla. Permite almacenar en memoria (o en otra ubicación, ya que es extensible) datos costosos de obtener y que no caduquen de inmediato. De esta forma las siguientes veces que debamos utilizarlos en la misma aplicación podremos obtenerlos desde la caché sin necesidad de volver a calcularlos o generarlos. Además la caché de ASP.NET ofrece un montón de características avanzadas que van más allá del simple almacenamiento. Por ejemplo podemos establecer caducidades de la información tanto en un determinado momento en el futuro, si no se utiliza tras un periodo, haciendo que unas informaciones dependan del valor de otras o creando dependencias de ciertos elementos externos (como un archivo, una consulta en la base de datos o una clave del registro).

Esto último es de especial interés, pues nos brinda la posibilidad de hacer cosas bastante complicadas sin apenas código. Por ejemplo, si nuestra aplicación depende de la información almacenada en un archivo en el disco duro, podemos leer sus contenidos, almacenarlos en caché e indicar que queremos que la caché caduque de inmediato en caso de que el archivo sea modificado externamente. Compáralo con el trabajo de conseguir lo mismo totalmente a mano.

Para abarcar toda la funcionalidad de la caché de .NET necesitaríamos un capítulo completo de un libro, y no es el objeto de este post. En MSDN tenemos acceso a toda la documentación al respecto.

El caso es que la versatilidad de la caché de ASP.NET ha hecho que muchos otros programadores quisieran usarla también en aplicaciones de escritorio y de otros ámbitos no atados a la Web. De hecho, en este mismo blog hablábamos hace más de 3 años de cómo conseguirlo. Lo que ocurre es que esto no dejaba de ser un apaño, y resultaba cuando menos extraño tener que añadir una referencia a System.Web.dll en nuestro proyecto. Incluso Microsoft/Avanade dentro de su Enterprise Library ha incluido siempre un módulo de caché para aplicaciones de escritorio con similares funcionalidades.

En .NET 4.0 la cosa se ha simplificado mucho. Se ha cambiado la implementación de la caché para que siga el modelo de proveedores (como en el resto de ASP.NET) para poder definir proveedores de caché propios y extender de diversas maneras la forma de almacenar la información. Y lo que más nos interesa para este post: se ha separado la implementación de la parte Web de la plataforma, para darle independencia y poder usarla en cualquier otro tipo de aplicación.

Ahora toda la funcionalidad de la caché se encuentra dentro del ensamblado System.Runtime.Caching y podemos hacer uso de uso clases desde cualquier tipo de aplicación, aunque hay algún truquillo que ahora mismo voy a contar.

Añadir una referencia a System.Runtime.Caching en una aplicación Windows Forms

Para probar cómo podemos usarla, vamos a crear un nuevo proyecto de Windows Forms en Visual Studio 2010. Lo primero que debemos tras haber creado el proyecto es añadir una referencia a System.Runtime.Caching, que nos habilitará el poder sacarle partido a la funcionalidad de caché.

Pulsamos con el botón derecho en el nodo del proyecto en el Explorador de Soluciones y elegimos la opción “Agregar Referencia”. Dentro de la pestaña .NET buscamos el ensamblado:

¡Eh! Un momento, ¿Qué pasa? No está en la GAC ¡Qué raro!

Es raro, pero no pasa nada. Vamos a buscarlo directamente en el disco duro, dentro de la carpeta de .NET en C:\Windows\Microsoft.NET\Framework\v4.0.30319. Ahí sí que está:

La añadimos, pero de repente observamos que en las referencias del proyecto aparece con una advertencia:

Si nos fijamos más, en la ventana de errores aparece un mensaje indicándonos que esa biblioteca no está preparada para trabajar con este perfil de .NET, y que la quitemos o que cambiemos el perfil.

¿Qué son los perfiles de .NET?

Un perfil de .Net es un subconjunto de la plataforma completa especialmente pensado para un tipo concreto de aplicación. En lugar de contener todas las funcionalidades de la plataforma ofrece sólo las interesantes para el perfil concreto con el que estemos trabajando. De esta forma si la aplicación típica de un determinado ámbito no necesita usar la funcionalidad completa de .NET puede usar sólo una parte y conseguiremos una descarga más pequeña del runtime de la plataforma. Un buen ejemplo son las aplicaciones Windows: ¿para qué vamos a distribuir con ellas todas las DLLs de la plataforma si en realidad no van a usar nada de la parte Web o la de Silverlight?. Esta funcionalidad está relacionada con la capacidad Multi-targeting de Visual Studio y ya apareció con la versión anterior en VS2008.

En Visual Studio 2010, por defecto, las aplicaciones de Windows Forms utilizan uno de estos perfiles, en concreto el denominado .NET Framework 4.0 Client Profile. Éste no incluye System.Runtime.Caching entre los ensamblados que puede utilizar, de ahí la advertencia, ya que luego en tiempo de ejecución en otra máquina puede que no estuviera disponible.

En este excelente post de Jossef Goldberg, del equipo de .Net en Microsoft, se explica la composición exacta de este perfil, qué funcionalidad contiene y cómo se compara con el mismo en .NET 3.5. También puedes ver qué ensamblados contiene el perfil viendo su definición en tu disco duro, en la ruta C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client. Finalmente puedes descargar el instalador de este perfil de la plataforma desde la Web de Microsoft.

Vale, ahora que ya sabemos qué es un perfil ¿cómo evitamos que se produzca la advertencia anterior?

Si vamos a las propiedades del proyecto Windows Forms, dentro de su pestaña “Application” tenemos un apartado para elegir contra qué versión de la plataforma queremos trabajar. Si desplegamos la lista podemos cambiar desde la versión cliente a la versión completa de la plataforma que es la inmediatamente anterior:

Al hacerlo y aceptar se nos avisa de que el proyecto tiene que cerrarse y volver a abrirse para poder realizar los cambios. Una vez hecho si vamos a agregar una referencia a la funcionalidad de Caching veremos que ahora sí está disponible desde la GAC, al ser la plataforma completa:

¡Listo!

Ahora ya podemos sacarle partido a la misma funcionalidad de caching que tendríamos en ASP.NET.

He dejado una pequeña descarga (ZIP, 14KB) con un ejemplo muy simple de uso para que se vea que realmente funciona sin problemas.

Sólo un detalle importante a tener en cuenta: la caché es privada para cada dominio de aplicación, por lo que sólo se puede acceder a la misma desde la propia aplicación que la ha creado. Esto es lógico por seguridad, pero alguien podría pensar que se podría compartir entre aplicaciones distintas o que si ejecutamos dos veces la misma aplicación tendríamos acceso a los mismos datos de caché. No es así y los datos almacenados sólo nos servirán dentro de ventanas o módulos que se ejecuten en la misma aplicación.

Imagino que se podría escribir una implementación propia de una caché que se saltase esos controles de algún modo, pero no es el verdadero objeto generalmente de este tipo de almacenamiento.

¡Espero que te sea útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA