博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

用匿名函数来更方便的使用缓存

Posted on 2009-06-17 09:00  linFen  阅读(315)  评论(0编辑  收藏  举报

一个数据缓存,一般由数据来源,缓存方案,缓存读取来完成,现在有了匿名函数,可以把获取数据来源变为匿名函数。这样就可以直接声明一个缓存:

protected static CacheManager<Company> companyCache = new CacheManager<Company>(new SmsDatabaseCache<Company>(), (key) =>
             {
                 
return SmsDatabase.Instance.Context.Company.Where(c => c.ShortNumber == (string)key).SingleOrDefault();
             });

SmsDatabaseCache是一个缓存方案,还可以使用SimpleCache,TimeoutCache等实现了ICache接口的类,因为我的ICacheManager从ICache继承,所以还可以实现级连缓存哟,例如:

SmsDatebaseCache是一个依SmsDatabase.Instance.Context的缓存方案,在LinqContextDispose时,会进行清空数据操作。

    public class SmsDatabaseCache<TData> : ICache<TData>
    {
        
private Dictionary<object, TData> cache = new Dictionary<object, TData>();

        
public SmsDatabaseCache()
        {
            SmsDatabase.Instance.PreDisposing 
+= (s, e) =>
                {
                    cache.Clear();
                };
        }

        
public TData Get(object key)
        {
            
return cache[key];
        }

        
public void Set(object key, TData data)
        {
            cache[key] 
= data;
        }
  

    }

实现代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace Evlon.Utils
{
    
public interface ICache<TData>
    {
        TData Get(
object key);
        
void Set(object key, TData data);
    }

    
public interface ICacheManager<TData> : ICache<TData>
    {
        Func
<object, TData> SourceGetter { get; }
    }


    
public class SimpleCache<TData> : ICache<TData>
    {
        
private Dictionary<object, TData> cache = new Dictionary<object, TData>();



        
#region ICacheManager<TData> 成员

        
public TData Get(object key)
        {
            
return cache[key];
        }

        
public void Set(object key, TData data)
        {
            cache[key] 
= data;
        }

        
#endregion
    }


    
public class TimeoutCache<TData> : ICache<TData>
    {
        
public TimeSpan Expire {get;set;}
        
private DateTime timeLastScan = DateTime.Now;
        
private Dictionary<object, KeyValuePair<TData, DateTime>> cache = new Dictionary<object, KeyValuePair<TData, DateTime>>();

        
public TimeoutCache()
        {
            Expire 
= TimeSpan.FromMinutes(5);
        }

        
private void TryClearExpireObject()
        { 
            TimeSpan ts 
= DateTime.Now - timeLastScan;
            
if (ts.TotalSeconds > Expire.TotalSeconds / 2)
            {
                timeLastScan 
= DateTime.Now;
                cache.Where(kv 
=> kv.Value.Value  > DateTime.Now.Subtract(Expire)).ToList().ForEach(kv =>
                    {
                        cache.Remove(kv.Key);
                    });
            }
        }

        
#region ICacheManager<TData> 成员

        
public TData Get(object key)
        {
            TryClearExpireObject();

            
if(!cache.ContainsKey(key))
                
return default(TData);


            KeyValuePair
<TData, DateTime> kv = cache[key];
            
if (kv.Value.Add(Expire) < DateTime.Now)
            {
                cache.Remove(key);
                
return default(TData);
            }
            
return kv.Key;
        }

        
public void Set(object key, TData data)
        {
            cache[key] 
= new KeyValuePair<TData, DateTime>(data, DateTime.Now);
        }

        
#endregion
    }

    
public class CacheManager<TData> : ICacheManager<TData>
    {
        
private ICache<TData> cache = null;

        
public Func<object, TData> SourceGetter { getprivate set; }
        
public CacheManager(ICache<TData> cache, Func<object, TData> sourceGetter)
        {
            
this.cache = cache;
            
this.SourceGetter = sourceGetter;
        }

        
#region ICacheGetter<TData> 成员

        
public TData Get(object key)
        {
            TData data 
= cache.Get(key);
            
if (data != null)
                
return data;

            data 
= this.SourceGetter(key);

            cache.Set(key, data);

            
return data;
        }



        
public void Set(object key, TData data)
        {
            cache.Set(key, data);
        }

        
#endregion
    }



}
技术交流,欢迎转载。转载请注明出处 http://evlon.cnblogs.com QQ:evlion@qq.com