我最近開始使用PostSharp,主要是因爲我想實現方法緩存。我發現如何做到這一點幾個例子,但所有這些例子都是基於執行結果應該使用緩存的高速緩存方法,屬性和裝飾方法:在運行時使用PostSharp自定義註冊方法緩存
我會喜歡以一種方式實現緩存,以便能夠根據配置爲運行時間中的每種方法設置一些額外的參數。例如,我想註冊一個具有單獨過期時間的特定方法緩存,但在代碼編譯期間我不知道該值。
我不怎麼做的事情是如何在運行時做到這一點,而不用裝飾方法。
我最近開始使用PostSharp,主要是因爲我想實現方法緩存。我發現如何做到這一點幾個例子,但所有這些例子都是基於執行結果應該使用緩存的高速緩存方法,屬性和裝飾方法:在運行時使用PostSharp自定義註冊方法緩存
我會喜歡以一種方式實現緩存,以便能夠根據配置爲運行時間中的每種方法設置一些額外的參數。例如,我想註冊一個具有單獨過期時間的特定方法緩存,但在代碼編譯期間我不知道該值。
我不怎麼做的事情是如何在運行時做到這一點,而不用裝飾方法。
這應該很簡單,儘管你需要編寫你需要的細節代碼,下面是重要的細節,粘貼我的代碼,所以一些變量是我們的習慣,相應地修改它們。您需要將屬性應用[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; }
}
謝謝你的例子,但它不回答我的問題。您創建了與我在帖子中放置的鏈接類似的示例。我的問題是不同的。我需要在運行時將方法註冊到緩存機制中,而不是用屬性裝飾它們。 –
您計劃在運行時爲給定方法添加緩存方面,但如果相關數據不在緩存中,則在實際方法邏輯執行之前,通過在裝入方法的運行時插入必要的IL以執行必要的IL工作。讓我檢查不確定Post Sharp使用聲明性屬性的工作可以在運行時附加到方法 –
可幫助的幾個鏈接: http://doc.postsharp.net/iaspectprovider http:// stackoverflow。 com/questions/27693438/postsharp-how-to-know-at-runtime-if-a-aspect-was-applied-to-a-method http://stackoverflow.com/questions/2461862/adding -code到最開始-結束方法-在運行時動態地 –
PostSharp可以添加緩存,你的方法的唯一方法是通過在編譯時編織的IL代碼。如果您需要在運行時控制緩存行爲,則可以從截取代碼內檢查當前配置。例如,如果尚未爲此特定方法啓用高速緩存,則可以立即繼續進行原始方法調用。當然,這不會幫助您避免裝飾方法。 – AlexD