How to use Unity Interception to create Attribute Based Cache

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()
{
  .....
}