2011-09-17 66 views
5

我有一個簡單的使用postsharp實現的Cache屬性。當我設置緩存策略時,我希望能夠像下面那樣設置更新回調。如何在另一個類的CacheItemPolicy上實現UpdateCallback?

private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry) 
    { 
     var policy = new CacheItemPolicy(); 

     switch (type) 
     { 
      case (CacheType.Absolute): 
       policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry); 
       policy.UpdateCallback = new CacheEntryUpdateCallback(UpdateHandler); 
       break; 
      case (CacheType.Sliding): 
       policy.SlidingExpiration = new TimeSpan(0, 0, 0, expiry); 
       break; 
     } 

     return policy; 
    } 

這是好的,如果我只是想做到這一點:

private static void UpdateHandler(CacheEntryUpdateArguments arguments) 
    { 
     throw new NotImplementedException(); 
    } 

不過,我希望能夠在一個委託/方法/方法的名稱和參數傳遞到動態和執行。所以,我希望看到類似的東西(很明顯的語法錯誤):

private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry Func<?,?> method) 
    { 
     var policy = new CacheItemPolicy(); 

     switch (type) 
     { 
      case (CacheType.Absolute): 
       policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry); 
       policy.UpdateCallback = new CacheEntryUpdateCallback(method); 
       break; 
      case (CacheType.Sliding): 
       policy.SlidingExpiration = new TimeSpan(0, 0, 0, expiry); 
       break; 
     } 

     return policy; 
    } 

** * ** * ** * *UPDATE* * * * ****

我得到了它的工作。不是最優雅的方法,它起作用。

我看點代碼如下:

[Serializable] 
public sealed class CacheAttribute : MethodInterceptionAspect 
{ 
    private readonly CacheType m_cacheType; 
    private readonly int m_expiry; 
    private readonly bool m_useCallBack; 
    private KeyBuilder m_keyBuilder; 

    public KeyBuilder KeyBuilder 
    { 

     get { return m_keyBuilder ?? (m_keyBuilder = new KeyBuilder()); } 

    } 

    public CacheAttribute(CacheType cacheType, int expiry, bool useCallBack) 
    { 
     m_cacheType = cacheType; 
     m_expiry = expiry; 
     m_useCallBack = useCallBack; 
    } 

    public CacheAttribute(CacheType cacheType, int expiry) 
    { 
     m_cacheType = cacheType; 
     m_expiry = expiry; 
     m_useCallBack = false; 
    } 


    //Method executed at build time. 

    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo) 
    { 

     KeyBuilder.MethodParameters = method.GetParameters(); 

     KeyBuilder.MethodName = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name); 

    } 

    public override void OnInvoke(MethodInterceptionArgs context) 
    { 
     object value; 


     string key = KeyBuilder.BuildCacheKey(context, context.Arguments); 
     if (!CacheHelper.Get(key, out value)) 
     { 
      // Do lookup based on caller's logic. 
      context.Proceed(); 
      value = context.ReturnValue; 
      var cacheObject = new CacheObject {CacheValue = value, Context = context}; 
      CacheHelper.Add(cacheObject, key, m_cacheType, m_expiry, m_useCallBack); 
     } 

     context.ReturnValue = value; 
    } 
} 

我的回調如下:

private static void UpdateHandler(CacheEntryUpdateArguments arguments) 
    { 
     CacheObject cacheObject = (CacheObject)arguments.Source.Get(arguments.Key); 
     cacheObject.Context.Proceed(); 
     cacheObject.CacheValue = cacheObject.Context.ReturnValue; 

     CacheItem updatedItem = new CacheItem(arguments.Key, cacheObject); 
     arguments.UpdatedCacheItem = updatedItem; 
    } 
+0

你可以包括你的方面代碼的問題?我不明白你想達到什麼目的。從哪裏調用GetCachePolicy方法以及哪個方面適用於哪裏? –

回答

6

你可以這樣做:

private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry, 
            Action<CacheEntryUpdateArguments> method) 
{ 
    ... 
    policy.UpdateCallback = (a) => method(a); 
    ... 
    return policy; 
} 

或者只是這樣的:

private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry, 
              CacheEntryUpdateCallback method) 
{ 
    ... 
    policy.UpdateCallback = method; 
    ... 
    return policy; 
} 
0

我認爲你可以做到這一點

` 
    private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry, Func method) 
    { 
     var policy = new CacheItemPolicy(); 

     switch (type) 
     { 
      case (CacheType.Absolute): 
        Action updateCallBackHandler = null; 
        updateCallBackHandler = delegate(CacheEntryUpdateArguments arguments) 
        {       
         var newData = FetchYourDataWithCustomParameters(); 

         arguments.UpdatedCacheItem = new CacheItem(arguments.Key, newData); 
         arguments.UpdatedCacheItemPolicy = new CacheItemPolicy() 
         { 
          AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry), 
          UpdateCallback = new CacheEntryUpdateCallback(updateCallBackHandler) 
         }; 
        }; 

        policy.UpdateCallback = new CacheEntryUpdateCallback(updateCallBackHandler); 

       break; 
      case (CacheType.Sliding): 
       policy.SlidingExpiration = new TimeSpan(0, 0, 0, expiry); 
       break; 
     } 

     return policy; 
    } 
'
相關問題