緩(huan)存篇(pian)~第六回 Microsoft.Practices.EnterpriseLibrary.Caching實現基于方(fang)法(fa)簽名(ming)的(de)數據集緩(huan)存
這(zhe)一(yi)(yi)講中主(zhu)要(yao)(yao)是說(shuo)EnterpriseLibrary企業級(ji)架(jia)(jia)構(gou)里的(de)(de)caching組件,它主(zhu)要(yao)(yao)實現了項目緩(huan)(huan)存(cun)功(gong)能,它支(zhi)持四種持久化(hua)(hua)方式(shi),內(nei)存(cun),文(wen)件,數據庫(ku)和自定(ding)義,對于持久化(hua)(hua)不(bu)是今(jin)天(tian)討論的(de)(de)重要(yao)(yao),今(jin)天(tian)主(zhu)要(yao)(yao)說(shuo),如何使用AOP的(de)(de)思想(xiang)再配合(he)Caching組件來(lai)實現可(ke)更新(xin)的(de)(de),可(ke)插拔的(de)(de),松(song)耦(ou)合(he)的(de)(de),基(ji)于數據集(ji)(結果集(ji))的(de)(de)緩(huan)(huan)存(cun)方案,之所以叫它方案,確實,在(zai)實現上(shang)有一(yi)(yi)定(ding)難度,我自己對于微軟的(de)(de)NLayerApp架(jia)(jia)構(gou)里用到的(de)(de)Attribute注入(ru)方式(shi)也對一(yi)(yi)定(ding)修改,因為(wei)(wei)NLayerApp里的(de)(de)緩(huan)(huan)存(cun)數據集(ji)并(bing)不(bu)支(zhi)持方法參數為(wei)(wei)對象和lambda表達式(shi)的(de)(de)情(qing)況,而我的(de)(de)這(zhe)個方案已經解決了上(shang)面(mian)兩(liang)種情(qing)況,可(ke)以說(shuo),完全支(zhi)持!
我們來看一(yi)下Web.config對Caching的配置(zhi)
緩存配置篇
注冊sections塊
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
配置caching塊
<cachingConfiguration defaultCacheManager="ByteartRetailCacheManager"> <cacheManagers> <add name="ByteartRetailCacheManager" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" expirationPollFrequencyInSeconds="600" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="NullBackingStore" /> <!-- expirationPollFrequencyInSeconds:過期時間(jian)(seconds) maximumElementsInCacheBeforeScavenging:緩沖(chong)中(zhong)的最大元素(su)數(shu)(shu)量 numberToRemoveWhenScavenging:一次(ci)移(yi)除的數(shu)(shu)量 --> </cacheManagers> <backingStores> <add type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="NullBackingStore" /> </backingStores> </cachingConfiguration>
為unity塊添加(jia)要進行緩存的方法(fa)
<register type="NLayer_IoC_Demo.BLL.IUserService,NLayer_IoC_Demo.BLL" mapTo="NLayer_IoC_Demo.BLL.UserService,NLayer_IoC_Demo.BLL" > <!--接口攔截--> <interceptor type="InterfaceInterceptor" /> <!--緩存注入--> <interceptionBehavior type="Project.UnityCaching.CachingBehavior,Project.UnityCaching"/> </register>
緩存實現篇
1 通(tong)過CachingAttribute特(te)性(xing)對(dui)方法進行標識,并(bing)配置緩(huan)存(cun)方式(shi),get,put,remove,一般(ban)在添加(jia),修改操作之后,會對(dui)緩(huan)存(cun)進行remove操作
/// <summary> /// 表示(shi)由此特性(xing)所描述的(de)方法(fa),能夠獲得來自Microsoft.Practices.EnterpriseLibrary.Caching基礎結(jie)構層所提供的(de)緩存功(gong)能。 /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public class CachingAttribute : Attribute { #region Ctor /// <summary> /// 初始化一個(ge)新的<c>CachingAttribute</c>類型。 /// </summary> /// <param name="method">緩存方式。</param> public CachingAttribute(CachingMethod method) { this.Method = method; } /// <summary> /// 初(chu)始化一(yi)個新的<c>CachingAttribute</c>類型。 /// </summary> /// <param name="method">緩存方式。</param> /// <param name="correspondingMethodNames">與當前(qian)緩存方(fang)式相關的方(fang)法名(ming)稱。注:此參(can)數(shu)僅在緩存方(fang)式為Remove時起(qi)作用。</param> public CachingAttribute(CachingMethod method, params string[] correspondingMethodNames) : this(method) { this.CorrespondingMethodNames = correspondingMethodNames; } #endregion #region Public Properties /// <summary> /// 獲取(qu)或設置緩存方式。 /// </summary> public CachingMethod Method { get; set; } /// <summary> /// 獲取(qu)或設置(zhi)一個<see cref="Boolean"/>值(zhi)(zhi),該值(zhi)(zhi)表示當緩(huan)存方式(shi)為Put時(shi),是否強制將值(zhi)(zhi)寫(xie)入緩(huan)存中。 /// </summary> public bool Force { get; set; } /// <summary> /// 獲取或(huo)設置與當(dang)前(qian)緩存(cun)方式(shi)相關的方法(fa)名稱(cheng)。注:此參數僅(jin)在緩存(cun)方式(shi)為(wei)Remove時起作(zuo)用。 /// </summary> public string[] CorrespondingMethodNames { get; set; } #endregion }
2 CachingMethod標識了(le)緩存的方式
/// <summary> /// 表示用(yong)于Caching特(te)性的緩存方式。 /// </summary> public enum CachingMethod { /// <summary> /// 表示需要從緩(huan)存中(zhong)獲(huo)取(qu)對(dui)象(xiang)。如果(guo)緩(huan)存中(zhong)不存在所需的對(dui)象(xiang),系統則會調用(yong)實際的方法獲(huo)取(qu)對(dui)象(xiang), /// 然后將獲得的結果添加到緩存中。 /// </summary> Get, /// <summary> /// 表示(shi)需要將對(dui)象(xiang)存(cun)入緩存(cun)。此(ci)方式(shi)會調用實際方法以獲取對(dui)象(xiang),然后將獲得的結果添加到緩存(cun)中(zhong), /// 并直接返回方法(fa)的調用結果。 /// </summary> Put, /// <summary> /// 表(biao)示需要(yao)將對象從緩存(cun)中移除(chu)。 /// </summary>
3 一個標準(zhun)的緩存(cun)CRUD接口,它默認使(shi)用Microsoft.Practices.EnterpriseLibrary.Caching來(lai)實(shi)現(xian),當前你可以進行利用這個接口來(lai)實(shi)現(xian)多態
/// <summary> /// 表示(shi)實現該接(jie)口(kou)的(de)類型(xing)是能夠為(wei)應用程序提供緩存機(ji)制的(de)類型(xing)。 /// </summary> public interface ICacheProvider { #region Methods /// <summary> /// 向緩存中(zhong)添加一(yi)個對象。 /// </summary> /// <param name="key">緩(huan)存的鍵(jian)值,該(gai)值通(tong)常是(shi)使用(yong)緩(huan)存機制的方(fang)法的名稱。</param> /// <param name="valKey">緩存(cun)值(zhi)(zhi)的(de)鍵(jian)值(zhi)(zhi),該值(zhi)(zhi)通常是由(you)使用緩存(cun)機制的(de)方法的(de)參數值(zhi)(zhi)所產生。</param> /// <param name="value">需要緩存的對象(xiang)。</param> void Add(string key, string valKey, object value); /// <summary> /// 向緩存中更新(xin)一個(ge)對象。 /// </summary> /// <param name="key">緩(huan)存的鍵值(zhi)(zhi),該值(zhi)(zhi)通常(chang)是使用緩(huan)存機制的方法的名稱。</param> /// <param name="valKey">緩存值的鍵值,該(gai)值通常(chang)是由使用緩存機(ji)制的方法的參數值所產生。</param> /// <param name="value">需要緩存的對象。</param> void Put(string key, string valKey, object value); /// <summary> /// 從(cong)緩存中讀取對(dui)象。 /// </summary> /// <param name="key">緩存的鍵值,該值通常是使(shi)用緩存機制的方法的名稱。</param> /// <param name="valKey">緩存值的(de)鍵值,該(gai)值通常是由使用緩存機制的(de)方法的(de)參數值所(suo)產生(sheng)。</param> /// <returns>被緩(huan)存的對象(xiang)。</returns> object Get(string key, string valKey); /// <summary> /// 從緩存中移除對象(xiang)。 /// </summary> /// <param name="key">緩存的鍵值(zhi),該(gai)值(zhi)通常是使用緩存機制的方法的名稱。</param> void Remove(string key); /// <summary> /// 獲取一個<see cref="Boolean"/>值,該值表示擁有(you)指定鍵值的緩(huan)存(cun)是否(fou)存(cun)在。 /// </summary> /// <param name="key">指定的鍵(jian)值(zhi)。</param> /// <returns>如果(guo)緩存存在,則返回true,否則返回false。</returns> bool Exists(string key); /// <summary> /// 獲取一個<see cref="Boolean"/>值,該值表示擁有指定鍵值和緩(huan)存值鍵的緩(huan)存是否(fou)存在。 /// </summary> /// <param name="key">指定的鍵值。</param> /// <param name="valKey">緩存值(zhi)鍵。</param> /// <returns>如果緩(huan)存存在,則(ze)返回true,否則(ze)返回false。</returns> bool Exists(string key, string valKey); #endregion }
4 使用Microsoft.Practices.EnterpriseLibrary.Caching來實現(xian)緩存(cun)的持久化功能
/// <summary> /// 表示基于Microsoft Patterns & Practices - Enterprise Library Caching Application Block的(de)緩存(cun)機制的(de)實現。 /// </summary> public class EntLibCacheProvider : ICacheProvider { #region Private Fields private readonly ICacheManager _cacheManager = CacheFactory.GetCacheManager(); #endregion #region ICacheProvider Members /// <summary> /// 向(xiang)緩存中添加一個對(dui)象。 /// </summary> /// <param name="key">緩存的(de)鍵值,該(gai)值通常是使(shi)用(yong)緩存機制的(de)方(fang)法的(de)名稱。</param> /// <param name="valKey">緩存值(zhi)(zhi)的(de)鍵值(zhi)(zhi),該值(zhi)(zhi)通常是由使用緩存機制的(de)方法(fa)的(de)參數值(zhi)(zhi)所產生。</param> /// <param name="value">需要(yao)緩(huan)存的對象。</param> public void Add(string key, string valKey, object value) { Dictionary<string, object> dict = null; if (_cacheManager.Contains(key)) { dict = (Dictionary<string, object>)_cacheManager[key]; dict[valKey] = value; } else { dict = new Dictionary<string, object>(); dict.Add(valKey, value); } _cacheManager.Add(key, dict); } /// <summary> /// 向緩存(cun)中更新(xin)一個(ge)對象。 /// </summary> /// <param name="key">緩(huan)存的鍵值,該值通常是使用緩(huan)存機(ji)制的方(fang)法(fa)的名稱。</param> /// <param name="valKey">緩(huan)存值(zhi)(zhi)的(de)鍵值(zhi)(zhi),該值(zhi)(zhi)通常是由使(shi)用(yong)緩(huan)存機制的(de)方法的(de)參數值(zhi)(zhi)所產生。</param> /// <param name="value">需要緩(huan)存(cun)的對象。</param> public void Put(string key, string valKey, object value) { Add(key, valKey, value); } /// <summary> /// 從緩存中(zhong)讀(du)取對象。 /// </summary> /// <param name="key">緩(huan)存的鍵值,該值通常是(shi)使用緩(huan)存機(ji)制的方法(fa)的名稱。</param> /// <param name="valKey">緩存值(zhi)的(de)(de)(de)鍵值(zhi),該值(zhi)通(tong)常是由使用緩存機制的(de)(de)(de)方法的(de)(de)(de)參數值(zhi)所產生。</param> /// <returns>被(bei)緩存(cun)的對象(xiang)。</returns> public object Get(string key, string valKey) { if (_cacheManager.Contains(key)) { Dictionary<string, object> dict = (Dictionary<string, object>)_cacheManager[key]; if (dict != null && dict.ContainsKey(valKey)) return dict[valKey]; else return null; } return null; } /// <summary> /// 從緩(huan)存中移(yi)除對(dui)象。 /// </summary> /// <param name="key">緩存(cun)的鍵值,該值通(tong)常是使用緩存(cun)機制的方法的名(ming)稱。</param> public void Remove(string key) { _cacheManager.Remove(key); } /// <summary> /// 獲取一個<see cref="Boolean"/>值,該(gai)值表示(shi)擁有(you)指定鍵值的緩存是否(fou)存在。 /// </summary> /// <param name="key">指定的(de)鍵值。</param> /// <returns>如果緩存存在,則返回(hui)true,否(fou)則返回(hui)false。</returns> public bool Exists(string key) { return _cacheManager.Contains(key); } /// <summary> /// 獲取(qu)一個(ge)<see cref="Boolean"/>值(zhi),該值(zhi)表示擁有指定鍵值(zhi)和緩(huan)存(cun)值(zhi)鍵的緩(huan)存(cun)是否存(cun)在。 /// </summary> /// <param name="key">指定的鍵(jian)值。</param> /// <param name="valKey">緩(huan)存值(zhi)鍵。</param> /// <returns>如果緩存存在,則返回true,否則返回false。</returns> public bool Exists(string key, string valKey) { return _cacheManager.Contains(key) && ((Dictionary<string, object>)_cacheManager[key]).ContainsKey(valKey); } #endregion }
5 一(yi)個(ge)工(gong)廠模(mo)塊,來對緩存的持久(jiu)化方(fang)式進行創建,這個(ge)一(yi)般可以(yi)在(zai)配置(zhi)文件中動態去配置(zhi)的,本類使用簡(jian)單的單例(li)模(mo)式來進行創建,不考(kao)慮多線程(cheng)情況
/// <summary> /// 緩存持久化工(gong)廠類 /// </summary> public sealed class CacheManager : ICacheProvider { #region Private Fields private readonly ICacheProvider _cacheProvider; private static readonly CacheManager _instance = new CacheManager(); #endregion #region Ctor static CacheManager() { } private CacheManager() { _cacheProvider = new EntLibCacheProvider(); } #endregion #region Public Properties /// <summary> /// 獲取<c>CacheManager</c>類型的單件(Singleton)實(shi)例(li)。 /// </summary> public static CacheManager Instance { get { return _instance; } } #endregion #region ICacheProvider Members /// <summary> /// 向(xiang)緩存中添加一個(ge)對象。 /// </summary> /// <param name="key">緩存(cun)的(de)鍵值(zhi),該值(zhi)通常是使用(yong)緩存(cun)機制(zhi)的(de)方(fang)法的(de)名稱。</param> /// <param name="valKey">緩(huan)存值的鍵(jian)值,該值通常是由使用緩(huan)存機制的方法的參(can)數值所產生。</param> /// <param name="value">需要緩(huan)存的對象。</param> public void Add(string key, string valKey, object value) { _cacheProvider.Add(key, valKey, value); } /// <summary> /// 向緩存中更新一(yi)個對象。 /// </summary> /// <param name="key">緩(huan)存的(de)(de)鍵值,該值通(tong)常(chang)是使用緩(huan)存機制的(de)(de)方法的(de)(de)名稱。</param> /// <param name="valKey">緩存(cun)(cun)值(zhi)的鍵值(zhi),該值(zhi)通(tong)常是由使用緩存(cun)(cun)機(ji)制的方法的參數(shu)值(zhi)所產生。</param> /// <param name="value">需(xu)要緩存的對(dui)象。</param> public void Put(string key, string valKey, object value) { _cacheProvider.Put(key, valKey, value); } /// <summary> /// 從(cong)緩存中(zhong)讀(du)取對(dui)象(xiang)。 /// </summary> /// <param name="key">緩(huan)存的(de)鍵值,該值通(tong)常是使用緩(huan)存機制的(de)方法的(de)名稱(cheng)。</param> /// <param name="valKey">緩(huan)(huan)存(cun)(cun)值(zhi)的鍵值(zhi),該值(zhi)通常是由使用緩(huan)(huan)存(cun)(cun)機制的方法的參數值(zhi)所(suo)產生。</param> /// <returns>被緩存的對象。</returns> public object Get(string key, string valKey) { return _cacheProvider.Get(key, valKey); } /// <summary> /// 從緩存中移除對象。 /// </summary> /// <param name="key">緩存(cun)的鍵值(zhi),該值(zhi)通常是使用(yong)緩存(cun)機制的方法的名(ming)稱(cheng)。</param> public void Remove(string key) { _cacheProvider.Remove(key); } /// <summary> /// 獲取一個<see cref="Boolean"/>值,該(gai)值表示擁有(you)指(zhi)定(ding)鍵(jian)值的緩(huan)存是(shi)否存在。 /// </summary> /// <param name="key">指定的鍵值。</param> /// <returns>如果(guo)緩存(cun)存(cun)在,則(ze)返回true,否則(ze)返回false。</returns> public bool Exists(string key) { return _cacheProvider.Exists(key); } /// <summary> /// 獲取一個<see cref="Boolean"/>值(zhi),該值(zhi)表(biao)示擁有指定鍵(jian)值(zhi)和緩存(cun)(cun)值(zhi)鍵(jian)的(de)緩存(cun)(cun)是(shi)否存(cun)(cun)在。 /// </summary> /// <param name="key">指(zhi)定的(de)鍵值。</param> /// <param name="valKey">緩存(cun)值鍵。</param> /// <returns>如果緩存存在,則返回(hui)true,否則返回(hui)false。</returns> public bool Exists(string key, string valKey) { return _cacheProvider.Exists(key, valKey); } #endregion }
7 最(zui)后(hou)貢獻(xian)緩存攔截類(lei),這是核(he)心(xin),是提供AOP功(gong)能的(de)核(he)心(xin),其中自己(ji)添加(jia)了對結構體和(he)(he)lambda表達式和(he)(he)類(lei)的(de)方法參數的(de)支(zhi)持,原(yuan)版(ban)(ban)應該是陳晴陽寫的(de),但它不支(zhi)持結構體和(he)(he)lambda和(he)(he)類(lei),所以,我的(de)版(ban)(ban)本把它完善(shan)了。
/// <summary> /// 表示用于方(fang)法緩存功(gong)能的攔截行為。 /// </summary> public class CachingBehavior : IInterceptionBehavior { #region Private Methods /// <summary> /// 根據指定的<see cref="CachingAttribute"/>以及<see cref="IMethodInvocation"/>實例(li), /// 獲取與某(mou)一特定參數(shu)值相關的鍵名。 /// </summary> /// <param name="cachingAttribute"><see cref="CachingAttribute"/>實例。</param> /// <param name="input"><see cref="IMethodInvocation"/>實例。</param> /// <returns>與(yu)某(mou)一特定參數值(zhi)相(xiang)關的(de)鍵(jian)名。</returns> private string GetValueKey(CachingAttribute cachingAttribute, IMethodInvocation input) { switch (cachingAttribute.Method) { // 如果是Remove,則不(bu)存(cun)(cun)在(zai)特定值鍵名,所(suo)有的以該(gai)方(fang)法名稱(cheng)相關(guan)的緩存(cun)(cun)都需要(yao)清除 case CachingMethod.Remove: return null; // 如果是Get或者Put,則需要產(chan)生一個(ge)針對(dui)特(te)定參數值的(de)鍵名 case CachingMethod.Get: case CachingMethod.Put: if (input.Arguments != null && input.Arguments.Count > 0) { var sb = new StringBuilder(); for (int i = 0; i < input.Arguments.Count; i++) { if (input.Arguments[i].GetType().BaseType == typeof(LambdaExpression))//lambda處理(li) { var exp = input.Arguments[i] as LambdaExpression; var arr = ((System.Runtime.CompilerServices.Closure)(((System.Delegate)(Expression.Lambda(exp).Compile().DynamicInvoke())).Target)).Constants; Type t = arr[0].GetType(); string result = ""; foreach (var member in t.GetFields()) { result += member.Name + "_" + t.GetField(member.Name).GetValue(arr[0]) + "_"; } result = result.Remove(result.Length - 1); sb.Append(result.ToString()); } else if (input.Arguments[i].GetType() != typeof(string)//類和結構體(ti)處(chu)理 && input.Arguments[i].GetType().BaseType.IsClass) { var obj = input.Arguments[i]; Type t = obj.GetType(); string result = ""; foreach (var member in t.GetProperties()) { result += member.Name + "_" + t.GetProperty(member.Name).GetValue(obj) + "_"; } result = result.Remove(result.Length - 1); sb.Append(result.ToString()); } else//簡單值類型處(chu)理 { sb.Append(input.Arguments[i].ToString()); } if (i != input.Arguments.Count - 1) sb.Append("_"); } return sb.ToString(); } else return "NULL"; default: throw new InvalidOperationException("無效的緩存(cun)方(fang)式(shi)。"); } } #endregion #region IInterceptionBehavior Members /// <summary> /// 獲(huo)取當前行為需要攔(lan)截的(de)對象(xiang)類型接口(kou)。 /// </summary> /// <returns>所有需(xu)要(yao)攔截的對(dui)象類型(xing)接口。</returns> public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } /// <summary> /// 通(tong)過實現(xian)此方法來攔截調(diao)用并執(zhi)行所需的(de)攔截行為。 /// </summary> /// <param name="input">調(diao)用攔(lan)截目(mu)標(biao)時(shi)的輸(shu)入信(xin)息。</param> /// <param name="getNext">通過(guo)行(xing)為(wei)鏈來(lai)獲取下一個攔截行(xing)為(wei)的委托。</param> /// <returns>從(cong)攔截目(mu)標獲得的返回信息。</returns> public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { var method = input.MethodBase; var key = method.Name; if (method.IsDefined(typeof(CachingAttribute), false)) { var cachingAttribute = (CachingAttribute)method.GetCustomAttributes(typeof(CachingAttribute), false)[0]; var valKey = GetValueKey(cachingAttribute, input); switch (cachingAttribute.Method) { case CachingMethod.Get: try { if (CacheManager.Instance.Exists(key, valKey)) { var obj = CacheManager.Instance.Get(key, valKey); var arguments = new object[input.Arguments.Count]; input.Arguments.CopyTo(arguments, 0); return new VirtualMethodReturn(input, obj, arguments); } else { var methodReturn = getNext().Invoke(input, getNext); CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue); return methodReturn; } } catch (Exception ex) { return new VirtualMethodReturn(input, ex); } case CachingMethod.Put: try { var methodReturn = getNext().Invoke(input, getNext); if (CacheManager.Instance.Exists(key)) { if (cachingAttribute.Force) { CacheManager.Instance.Remove(key); CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue); } else CacheManager.Instance.Put(key, valKey, methodReturn.ReturnValue); } else CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue); return methodReturn; } catch (Exception ex) { return new VirtualMethodReturn(input, ex); } case CachingMethod.Remove: try { var removeKeys = cachingAttribute.CorrespondingMethodNames; foreach (var removeKey in removeKeys) { if (CacheManager.Instance.Exists(removeKey)) CacheManager.Instance.Remove(removeKey); } var methodReturn = getNext().Invoke(input, getNext); return methodReturn; } catch (Exception ex) { return new VirtualMethodReturn(input, ex); } default: break; } } return getNext().Invoke(input, getNext); } /// <summary> /// 獲取(qu)一個<see cref="Boolean"/>值,該值表(biao)示當前攔截行為被(bei)調用(yong)時,是否真的需要(yao)執行 /// 某些操作(zuo)。 /// </summary> public bool WillExecute { get { return true; } } #endregion }
緩存調用篇
我們的(de)緩存(cun)只能(neng)配(pei)置在(zai)接口的(de)方法(fa)中,這主要考慮到(dao)unity的(de)注(zhu)入(ru)環(huan)節(jie)和面向對(dui)象的(de)多態特性,本例中,緩存(cun)這塊配(pei)置在(zai)了(le)BLL層中,當(dang)然,如果你的(de)架(jia)構允許(xu),也可以(yi)做在(zai)DATA層中,當(dang)然DATA層的(de)緩存(cun)力度可能(neng)太(tai)大,我覺得并不太(tai)合適,但代碼可能(neng)更(geng)精簡,所
以,大家要因情況(kuang)而(er)議(yi),到在哪層都(dou)沒問題。
public interface IUserService { [Caching(CachingMethod.Get)] PagedList<WebManageUsers> GetWebManageUsers(PageParameters pp); [Caching(CachingMethod.Get)] PagedList<WebManageUsers> GetWebManageUsers(Expression<Func<WebManageUsers, bool>> predicate, PageParameters pp); [Caching(CachingMethod.Remove, "GetWebManageUsers")] void InsertManageUsers(NLayer_IoC_Demo.Entity.WebManageUsers entity); }
private readonly IUserService _userService = ServiceLocator.Instance.GetService<IUserService>(); public ActionResult Index(string name, int page = 1) { ViewBag.Message = "緩存篇"; if (string.IsNullOrWhiteSpace(name)) return View(_userService.GetWebManageUsers(new PageParameters(page, 3))); else { Expression<Func<WebManageUsers, bool>> predicate = i => i.LoginName.Contains(name); return View(_userService.GetWebManageUsers(predicate, new PageParameters(page, 3))); } }
緩存配(pei)置(zhi)好(hao)后,可以使(shi)用sql profiler等監控工具去查看數(shu)據庫的訪(fang)問情況!