2011-09-17 3 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* * * * ****

나는 그것을 얻었다. 가장 우아한 방법은 아니고 꽃 봉오리가 작동합니다. 다음과 같이

내 화면 코드는 다음과 같습니다

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

질문에 aspect 코드를 포함시켜 줄 수 있습니까? 네가 성취하려는 것을 이해하지 못한다. 어디에서 GetCachePolicy 메서드를 호출하고 어떤 부분이 적용됩니까? –

답변

6

당신은이 작업을 수행 할 수 있습니다 :

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

또는 그냥이 :

을 다음과 같이

[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 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; 
    } 
'