Как я могу реализовать UpdateCallback на CacheItemPolicy из другого класса?

У меня есть простой атрибут Cache, реализованный с помощью postsharp. Когда я устанавливаю политику кэширования, я хочу иметь возможность установить обратный вызов обновления, как показано ниже.

 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*********

Я заставил его заработать. Не самый элегантный метод, приятель, он работает.

Код My Aspect выглядит следующим образом:

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

Мой Callback выглядит следующим образом:

  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;
    }
6
задан Lee Cook 17 September 2011 в 21:00
поделиться