Pregunta

Estoy implementando un caché en una biblioteca de clases que estoy usando en una aplicación asp.net.

Creé mi objeto de caché como un patrón singleton con un método estático para actualizar el caché que en realidad solo está cargando una variable / propiedad miembro con una colección de datos que necesito en caché (tengo cierta lógica de bloqueo, por supuesto). Me di cuenta de que era una buena forma de hacerlo, ya que solo puedo acceder a mis datos llamando

MyCacheObject.Instance.MyDataCollection

Estoy creando un nuevo objeto de caché para almacenar una gran cantidad de datos particionados por alguna clave. Lo que digo es que estoy creando un nuevo caché, pero este no cargará todos los datos a la vez, sino que almacenará una colección para cada clave accedida.

MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)

Esta vez surgió la pregunta sobre la recolección de basura. Dado que estoy almacenando una gran cantidad de datos, ¿no sería un desperdicio si se hiciera de repente? Ya que es solo un patrón de singleton, no hay nada que garantice que los datos permanecerán en el caché.

Entonces, mi pregunta es: ¿cuál es la mejor práctica para implementar un caché para manejar esta situación? Realmente no me gusta una gran solución compleja para esto, y sé que hay almacenamiento en caché en System.Web, pero eso parece un poco "apagado" ya que esto es solo una biblioteca de clases, ¿o qué piensas?

¿Fue útil?

Solución

En mi opinión, la mejor solución tendría las siguientes características:

  • Utiliza los servicios de almacenamiento en caché disponibles proporcionados por la plataforma tratando de evitar escribir el suyo.

  • No asocia su biblioteca de clases a System.Web, para que las capas sean coherentes.

  • Pero si la biblioteca de clases se está ejecutando dentro de una aplicación ASP.NET, la solución no debería requerir la implementación de otra implementación de almacenamiento en caché (por ejemplo, el Bloque de aplicaciones de almacenamiento en caché de Enterprise Library), que requiere configuración y configuración adicionales.

Entonces, usaría una estrategia de IoC para permitir que la biblioteca de clases use diferentes implementaciones de almacenamiento en caché, en función del entorno en el que se ejecuta.

Supongamos que define su contrato de almacenamiento en caché abstracto como:

public interface ICacheService 
{
    AddItem(...);
}

Podría proporcionar una implementación basada en System.Web:

public AspNetBasedCacheService : ICacheService
{
    AddItem(...)
    {
        // Implementation that uses the HttpContext.Cache object
    }
 }

Y luego haz que esa implementación se 'publique' como singleton. Tenga en cuenta que la diferencia con su enfoque original es que el singleton es solo una referencia a la implementación basada en el servicio de caché ASP.NET, en lugar del 'objeto de caché' completo.

public class ChacheServiceProvider 
{
    public static IChacheService Instance {get; set;}

}

Tendría que inicializar la implementación de chacheo realizando una inicialización diferida o al iniciar la aplicación (en global.asax.cs)

Y cada componente de dominio podría usar el servicio de almacenamiento en caché publicado sin saber que se implementa en función de System.Web.

// inside your class library:
IChacheService chache = CacheServiceProvider.Instance;
cache.AddItem(...);

Estoy de acuerdo en que probablemente no sea la solución más simple, pero estoy tratando de aprovechar la implementación de caché ASP.NET sin sacrificar el desacoplamiento y la flexibilidad del código.

Espero haber entendido bien tu pregunta.

Otros consejos

Los datos no obtendrían basura recolectada mientras el caché aún tenga una referencia a ellos.

Además, nunca uses Singletons.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top