2009-06-24 14 views
29

Contexto: .Net 3.5, C#
me gustaría tener mecanismo de caché en mi aplicación de consola.
En lugar de reinventar la rueda, me gustaría utilizar System.Web.Caching.Cache (y eso es una decisión final, no puedo usar otro marco de almacenamiento en caché, no preguntes por qué). No obstante, parece que System.Web.Caching.Cache se ejecuta solo en un contexto HTTP válido. Mi fragmento muy simple es el siguiente:¿Cómo puedo usar System.Web.Caching.Cache en una aplicación de consola?

using System; 
using System.Web.Caching; 
using System.Web; 

Cache c = new Cache(); 

try 
{ 
    c.Insert("a", 123); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("cannot insert to cache, exception:"); 
    Console.WriteLine(ex); 
} 

y el resultado es:

 
cannot insert to cache, exception: 
System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.Web.Caching.Cache.Insert(String key, Object value) 
    at MyClass.RunSnippet() 

Así que, obviamente, estoy haciendo algo mal aquí. ¿Algunas ideas?


actualización: 1 a la mayoría de las respuestas, para obtener el caché a través de métodos estáticos es el uso correcto, es decir HttpRuntime.Cache y HttpContext.Current.Cache. ¡Gracias a todos!

Respuesta

56

La documentación para el constructor caché dice que es sólo para uso interno. Para obtener su objeto Cache, llame a HttpRuntime.Cache en lugar de crear una instancia a través del constructor.

9

sólo tiene que utilizar el Caching Application Block si no quiere reinventar la rueda. Si aún desea utilizar el caché ASP.NET- see here. Estoy bastante seguro de que esto solo funciona con .NET 2.0 y superiores. Simplemente no era posible utilizar la caché fuera de ASP.NET en .NET 1.

MSDN tiene un bonito gran advertencia en la página de la documentación caché demasiado:

La clase de caché no es previsto para el uso fuera de las aplicaciones ASP.NET. Se diseñó y probó para su uso en ASP.NET para proporcionar el almacenamiento en caché para las aplicaciones Web . En otros tipos de aplicaciones, como la consola aplicaciones o aplicaciones de Windows Forms , almacenamiento en caché de ASP.NET podría no funcionar correctamente.

Para una solución muy liviana, donde no tiene que preocuparse por la caducidad, etc., un objeto de diccionario podría ser suficiente.

+0

"ver aquí" vínculo se rompe –

+0

@ Ron- que es un error Stackoverflow. Aquí hay un TinyUrl para el mismo enlace: http://tinyurl.com/ms35eu – RichardOD

1

Trate

public class AspnetDataCache : IDataCache 
{ 
    private readonly Cache _cache; 

    public AspnetDataCache(Cache cache) 
    { 
     _cache = cache; 
    } 

    public AspnetDataCache() 
     : this(HttpRuntime.Cache) 
    { 

    } 
    public void Put(string key, object obj, TimeSpan expireNext) 
    { 
     if (key == null || obj == null) 
      return; 
     _cache.Insert(key, obj, null, DateTime.Now.Add(expireNext), TimeSpan.Zero); 
    } 

    public object Get(string key) 
    { 
     return _cache.Get(key); 
    } 

1

La clase System.Web.Caching.Cache se basa en tener sus miembros "_cacheInternal" establecido por el objeto HttpRuntime.

Para utilizar las clases System.Web.Caching Habría que crear un objeto HttpRuntime y la configuración de la propiedad HttpRuntime.Cache. De hecho, tienes que emular IIS.

Es mejor que el uso de otros marcos de almacenamiento en caché como:

+1

"La única forma de configurarlo es mediante métodos internos" - no es verdad, _cacheInternal es establecido por el acceso de propiedad estática HttpRuntime.Cache. Sin embargo, me interesaría más información sobre por qué MSDN recomienda que ASP.NET Cache no se use en aplicaciones no web. Tengo un código que lo usa (que data de antes de la existencia de esta advertencia), y * parece * que funciona bien. – Joe

+0

Gracias @Joe - editó mi respuesta – d4nt

4

terminé en esta página preguntando lo mismo. Esto es lo que estoy haciendo (que no me gusta, pero parece que funciona muy bien):

HttpContext context = HttpContext.Current; 
if (context == null) 
{ 
    HttpRequest request = new HttpRequest(string.Empty, "http://tempuri.org", string.Empty); 
    HttpResponse response = new HttpResponse(new StreamWriter(new MemoryStream())); 
    context = new HttpContext(request, response); 
    HttpContext.Current = context; 
} 
this.cache = context.Cache; 
+1

Esto es muy sucio, pero realmente fue útil cuando tenía un prototipo que se integraba con un dll externo que dependía de HttpContext.Current.Cache y solo necesitaba que funcionara. Encontré una versión más corta aquí: http://caioproiete.net/es/fake-mock-httpcontext-without-any-special-mocking-framework/ – bygrace

28

Mientras que el PO se especifica v3.5, la pregunta fue hecha antes v4 fue puesto en libertad. Para ayudar a cualquier persona que encuentre esta pregunta y a vivir con una dependencia de v4, el equipo de la estructura creó una nueva memoria caché de propósito general para este tipo de escenario. Está en el espacio de nombres System.Runtime.Caching: http://msdn.microsoft.com/en-us/library/dd997357%28v=VS.100%29.aspx

La referencia estática a la instancia de caché predeterminada es: MemoryCache.Default

+0

¡Gracias por el consejo! –

+3

¡Muy útil! Estoy cambiando las llamadas en mi aplicación web para usar este nuevo enfoque. Ahora esos métodos se pueden probar en unidades sin necesidad de que se defina HttpContext.Cache. :) – ClearCloud8

Cuestiones relacionadas