寫它的原因 之前寫過一個緩存攔截器,主要在方法上添加CachingAspect特性之後,它的返回值就可以被緩存下來,下次訪問時直接從緩存中返回結果,而它有一個前提,就是你的方法需要是一個介面方法,緩存這個CachingAspect卻需要在類里定義,大叔感覺很怪,所以抽時間把它完善一下,讓緩存特性在接 ...
寫它的原因
之前寫過一個緩存攔截器,主要在方法上添加CachingAspect特性之後,它的返回值就可以被緩存下來,下次訪問時直接從緩存中返回結果,而它有一個前提,就是你的方法需要是一個介面方法,緩存這個CachingAspect卻需要在類里定義,大叔感覺很怪,所以抽時間把它完善一下,讓緩存特性在介面方法里定義。
今天說的是為類里的虛方法添加CachingAspect,這個事實上我們用的比較多,因為並不是所有方法都需要提取到介面的,只有那些可能有多態的情況才需要實現這種功能,所以大叔覺得有必要為類的虛方法添加一個緩存攔截的功能。
攔截的原理
主要是建立一個新的類,然後讓它繼承被攔截的類型,找到聲明為virtual的方法,然後去override它,我們的攔截器使用了emit實現了建立類,建立方法等功能。
- -》程式入口
- -》 建立代理
- -》建立新程式集
- -》建立新模塊
- -》建立新類
- -》繼承被攔截的類
- -》重寫virtual方法
- -》添加緩存邏輯
- -》返回
實例代碼
public class AOP { [CachingAspect(CachingMethod.Get)] public virtual string Hello() { return DateTime.Now.ToString(); } }
使用它
var aop = ProxyFactory.CreateProxy<AOP>(); Console.WriteLine(aop.Hello()); Thread.Sleep(1000); Console.WriteLine(aop.Hello());
緩存結果存儲到了redis中間件里
修改了LindAspect的代碼段,對代理服務的完善,對類虛方法的支持!
對代理類也進行修改,添加了介面與類的判斷
if (_interfaceType.IsInterface)//介面代理 { _typeBuilder = _moduleBuilder.DefineType(string.Format(TypeNameFormat, _realProxyType.Name), TypeAttributes.Public | TypeAttributes.Sealed); _typeBuilder.AddInterfaceImplementation(_interfaceType); } else//類代理,虛方法可以被重寫 { _typeBuilder = _moduleBuilder.DefineType(string.Format(TypeNameFormat, _realProxyType.Name), TypeAttributes.Public | TypeAttributes.Sealed, _interfaceType); }
下一步,大步將再次進行優化,爭取早日支持介面方法攔截功能,而不是把攔截特性寫在類里。
像下麵的代碼,既然用了介面,就應該把特性寫在介面方法上,您說是吧!
public interface IAOP { [CachingAspect(CachingMethod.Get)] string Hello(); } public class AOP2 : IAOP { public string Hello() { return DateTime.Now.ToString(); } }
感謝閱讀!
請關註大叔新寵LindAgile框架!