文章出處

寫它的原因

之前寫過一個緩存攔截器,主要在方法上添加CachingAspect特性之后,它的返回值就可以被緩存下來,下次訪問時直接從緩存中返回結果,而它有一個前提,就是你的方法需要是一個接口方法,緩存這個CachingAspect卻需要在類里定義,大叔感覺很怪,所以抽時間把它完善一下,讓緩存特性在接口方法里定義。

今天說的是為類里的虛方法添加CachingAspect,這個事實上我們用的比較多,因為并不是所有方法都需要提取到接口的,只有那些可能有多態的情況才需要實現這種功能,所以大叔覺得有必要為類的虛方法添加一個緩存攔截的功能。

攔截的原理

主要是建立一個新的類,然后讓它繼承被攔截的類型,找到聲明為virtual的方法,然后去override它,我們的攔截器使用了emit實現了建立類,建立方法等功能。

  1. -》程序入口
  2. -》 建立代理
  3. -》建立新程序集
  4. -》建立新模塊
  5. -》建立新類
  6. -》繼承被攔截的類
  7. -》重寫virtual方法
  8. -》添加緩存邏輯
  9. -》返回

實例代碼

  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框架!

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()