Mam prosty atrybut cache zaimplementowany przy użyciu funkcji postsharp. Kiedy ustawiam politykę pamięci podręcznej, chcę móc ustawić wywołanie zwrotne aktualizacji jak poniżej.Jak mogę wdrożyć UpdateCallback na CacheItemPolicy z innej klasy?
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;
}
To jest w porządku, jeśli tylko chcesz to zrobić:
private static void UpdateHandler(CacheEntryUpdateArguments arguments)
{
throw new NotImplementedException();
}
Jednakże chcę, aby móc przejść na delegata/Metoda/nazwy metody i parametrów do dynamicznie i wykonać to. SO Spodziewam się, aby zobaczyć coś takiego (oczywiście składnia jest źle):
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* * * * ****
Mam to działa. Nie jest to najbardziej elegancka metoda, bud działa.
Mój kod obrazu jest następująca:
[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;
}
}
Moja oddzwaniania jest następujący:
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;
}
Czy możesz dołączyć swój kod aspektowy do pytania? Nie rozumiem, co próbujesz osiągnąć. Skąd się wzięła metoda GetCachePolicy i jaki aspekt jest stosowany? –