2010-06-17 75 views
3

我创建了一个通用的包装使用Cache对象:为通用的System.Web.Caching.Cache包装函数

public class Cache<T> where T : class 
{ 
    public Cache Cache {get;set;} 
    public CachedKeys Key {get;set;} 

    public Cache(Cache cache, CachedKeys key){ 
     Cache = cache; 
     Key = key; 
    } 

    public void AddToCache(T obj){ 
     Cache.Add(Key.ToString(), 
      obj, 
      null, 
      DateTime.Now.AddMinutes(5), 
      System.Web.Caching.Cache.NoSlidingExpiration, 
      System.Web.Caching.CacheItemPriority.Normal, 
      null);     
    } 

    public bool TryGetFromCache(out T cachedData) { 
     cachedData = Cache[Key.ToString()] as T; 
     return cachedData != null; 
    } 

    public void RemoveFromCache() { 
     Cache.Remove(Key.ToString()); } 
} 

的CachedKeys枚举只是一个键的列表,可用于高速缓存数据。

麻烦的是,把它称为是相当convul​​uted:

var cache = new Cache<MyObject>(Page.Cache, CachedKeys.MyKey); 
MyObject myObject = null; 

if(!cache.TryGetFromCache(out myObject)){ 
    //get data... 
    cache.AddToCache(data); //add to cache 
    return data; 
} 

return myObject; 

我只保存我的每个高速缓存中的对象的一个​​实例。

因此,有没有什么办法可以创建一个扩展方法来接受要缓存的对象类型并使用(通过Reflection)其Name作为缓存键?

public static Cache<T> GetCache(this Cache cache, Type cacheType){ 
     Cache<cacheType> Cache = new Cache<cacheType>(cache, cacheType.Name); 
    } 

当然,有两个错误的位置:

  • 扩展方法必须在非泛型静态类
  • 类型或命名空间名称“cacheType”被定义找不到

这显然不是正确的方法,但我想我会展示我的工作。有人能指引我朝着正确的方向吗?

+0

此方法线程安全吗? – 2013-04-25 13:46:57

+0

不 - 你可以引入双重检查锁定(即使不能保证)但懒惰填充缓存我建议任何锁定会引入不必要的延迟。你可以在运行定时器的后台线程上填充缓存(如果你对一个正在从线程池中取出的线程执行此操作感到满意)。我倾向于不担心 - 我不认为缓存填充缓存需要线程安全。 – 2013-04-25 14:09:10

回答

5

我结束了使用通用的扩展方法:

public static class CacheExtensions 
{ 
    public static void Remove<T>(this Cache cache) where T : class 
    { 
     cache.Remove(typeof(T).Name); 
    } 

    public static void AddToCache<T>(this Cache cache, object item) where T : class 
    { 
     T outItem = null; 
     if (cache.TryGetItemFromCache<T>(out outItem)) 
      throw new ArgumentException("This item is already in the cache"); 

     cache.Insert(typeof(T).Name, 
       item, 
       null, 
       DateTime.Now.AddMinutes(5), 
       System.Web.Caching.Cache.NoSlidingExpiration, 
       System.Web.Caching.CacheItemPriority.Normal, 
       null); 
    } 

    public static bool TryGetItemFromCache<T>(this Cache cache, out T item) where T : class 
    { 
     item = cache.Get(typeof(T).Name) as T; 
     return item != null; 
    } 
} 

调用,如:

MyObject myObject = null; 
if(!Cache.TryGetItemFromCache(out myObject)){ 
    //get data 
    Cache.AddToCache<MyObject>(data); 
} 

and.. 

Cache.Remove<MyObject>(); 
1

如何:

public static Cache<T> GetCache<T>(this Cache cache) 
{ 
    return new Cache<T>(cache, typeof(T).Name); 
} 

当然,这必须在另一个类中定义。

+0

这基本上就是我在我的'Cache'构造函数中已经有的东西(除了使用'Name'属性作为一个键,这是一个后续思考的东西)。 – 2010-06-17 13:23:17

+0

但它做你想要的,不是吗? – ErikHeemskerk 2010-06-17 13:32:34

+0

是的,我没有想过简单地制作一个泛型类而不是泛型类。我最后简单地添加了通用扩展方法来实现现在的功能。 – 2010-06-17 14:04:50

0

我觉得下面的方法需要改变:

public static bool TryGetItemFromCache<T>(this Cache cache, out T item) where T : class 
    { 
     item = cache.Get(typeof(T).Name) as T; 
     return item != null; 
    } 

如果该项目是不在缓存中,您不想将项目放入缓存中供以后使用或稍后检索。

谢谢,

+0

这将在调用代码中处理。 'Cache'不知道数据来自何处。 – 2010-06-17 14:28:07