在运行时使用PostSharp自定义方法高速缓存的注册

时间:2015-10-15 09:19:51

标签: c# caching postsharp

我最近开始使用PostSharp,主要是因为我想实现方法缓存。我找到了几个如何做的例子,但是所有这些例子都是基于实现缓存方法属性和装饰方法,结果应该缓存:

我希望以一种方式实现缓存,以便能够根据配置为运行时中的每种方法设置一些额外的参数。例如,我想注册一个具有单独到期时间的特定方法缓存,但在代码编译期间我不知道该值。

我不知道怎么做是在运行时如何做到这一点,而不是修饰方法。

1 个答案:

答案 0 :(得分:1)

这应该很简单,虽然你需要编写你需要的细节,下面是重要的细节,粘贴我的代码,所以一些变量是我们的自定义,相应地修改它们。您需要将[ViewrCache]属性应用于创建底层代码的相关方法,并且它将在运行时相应地修改方法IL

创建从PostSharp.Aspects.MethodInterceptionAspect扩展的自定义缓存属性,如下所示:

 [Serializable]
    public sealed class ViewrCacheAttribute : MethodInterceptionAspect

类变量:

//来自配置文件的缓存过期

private static readonly int CacheTimeOut = Convert.ToInt32(WebConfigurationManager.AppSettings[CacheSettings.CacheTimeOutKey]);

//要从缓存键中忽略的参数

private string[] IgnoreParameters { get; set; }

重写方法OnInvoke(MethodInterceptionArgs args),如下所示:

// My custom implementation that you may want to change
public override void OnInvoke(MethodInterceptionArgs args)
        {
            // Fetch standard Cache
            var cache = MemoryCache.Default;

            // Fetch Cache Key using the Method arguments
            string cacheKey = GetCacheKey(args); // Code pasted below

            var cacheValue = cache.Get(cacheKey);

            if (cacheValue != null)
            {
                args.ReturnValue = cacheValue;

                return;
            }
            ReloadCache(cacheKey, args);
        }

//获取缓存密钥方法

 private string GetCacheKey(MethodInterceptionArgs args)
        {
            //need to exclude paging Parameters from Key

            var builder = new StringBuilder();

            var returnKey = new ViewrCacheKey { CallingMethodFullName = args.Method.ToString() };

            // Loop through the Call arguments / parameters
            foreach (var argument in args.Arguments)
            {
                if (argument != null)
                {
                    if ((IgnoreParameters == null) ||
                        (IgnoreParameters != null && !IgnoreParameters.Contains(argument.ToString())))
                        builder.Append(JsonConvert.SerializeObject(argument));
                }
            }

            returnKey.ControllerHash = builder.ToString();

            return JsonConvert.SerializeObject(returnKey);
        }

//重新加载缓存

private Object ReloadCache(string cacheKey, MethodInterceptionArgs args)
        {
            //call the actual Method
            base.OnInvoke(args);

            //Save result into local cache
            InsertCache(cacheKey, args.ReturnValue);
            return args.ReturnValue;
        }

//插入缓存

 private void InsertCache(string key, object value)
        {
            // Setting Cache Item Policy
            var policy = new CacheItemPolicy
            {
                SlidingExpiration = new TimeSpan(0, 0, CacheTimeOut)
            };

            // sliding Expiration Timeout in Seconds
            ObjectCache cache = MemoryCache.Default;

            // Set the key,value in the cache
            cache.Set(key, value, policy);
        }

// ViewR缓存密钥

public class ViewrCacheKey
    {
        /// <summary>
        /// 
        /// </summary>
        public string CallingMethodFullName { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string ControllerHash { get; set; }
    }