1- Download Unity Interception using NuGet.
2- Create a custom attribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CacheAttribute : Attribute
{
public double AbsoluteExpiration { get; private set; }
public CacheAttribute(double absoluteExpiration)
{
AbsoluteExpiration = absoluteExpiration;
}
}
3- Create Interception Behavior
public class CachingInterceptionBehavior : IInterceptionBehavior
{
private object _LockSync = new object();
public bool WillExecute
{
get
{
return true;
}
}
public CachingInterceptionBehavior() { }
public IEnumerable GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
IMethodReturn result = null;
CacheAttribute cacheAttr = input.Target.GetType().GetMethods().FirstOrDefault(m => m.Name == input.MethodBase.Name)
?.GetCustomAttributes(typeof(CacheAttribute), false).FirstOrDefault() as CacheAttribute;
if (cacheAttr != null)
{
result = GetItem(input.MethodBase.Name, false) as IMethodReturn;
if (result == null)
{
result = InvokeSource(input, getNext);
if (result.Exception == null)
AddItem(input.MethodBase.Name, result, cacheAttr.AbsoluteExpiration);
}
}
if (result == null)
result = InvokeSource(input, getNext);
return result;
}
private IMethodReturn InvokeSource(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
return getNext()(input, getNext);
}
private void AddItem(string key, object value, double seconds)
{
lock (_LockSync)
{
MemoryCache.Default.Add(key, value, DateTimeOffset.Now.AddSeconds(seconds));
}
}
private void RemoveItem(string key)
{
lock (_LockSync)
{
MemoryCache.Default.Remove(key);
}
}
private object GetItem(string key, bool remove)
{
lock (_LockSync)
{
var res = MemoryCache.Default[key];
if (res != null)
{
if (remove == true)
MemoryCache.Default.Remove(key);
}
return res;
}
}
}
4- Register both the Interception extension and the new Cache behavior
Container.AddNewExtension()
.RegisterType(new ContainerControlledLifetimeManager());
5- That’s it. It’s time to start decorating your functions
[Cache(absoluteExpiration: 60)]
public async Task GetValue()
{
.....
}