我最近开始使用PostSharp,主要是因为我想实现方法缓存。我找到了几个如何做的例子,但是所有这些例子都是基于实现缓存方法属性和装饰方法,结果应该缓存:
我希望以一种方式实现缓存,以便能够根据配置为运行时中的每种方法设置一些额外的参数。例如,我想注册一个具有单独到期时间的特定方法缓存,但在代码编译期间我不知道该值。
我不知道怎么做是在运行时如何做到这一点,而不是修饰方法。
答案 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; }
}