中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Lind.DDD.LindAspects方(fang)法攔截的介紹

回到目錄

什么是(shi)LindAspects

之前寫了關于Aspects的文章《Lind.DDD.Aspects通過Plugins實現方法的動態攔截~Lind里的AOP,今(jin)天主要(yao)在設計思(si)想上(shang)進行(xing)刨(bao)析(xi)一(yi)下(xia),對緩存攔截器一(yi)直沒有實現,所(suo)以(yi)文章(zhang)了也一(yi)直沒有發出來(lai),讓大家等這么(me)久(jiu)實在不好意思(si)。LindAspects主要(yao)是面(mian)(mian)(mian)向切(qie)(qie)面(mian)(mian)(mian)編(bian)程AOP的(de)(de)一(yi)種實現,就(jiu)像MVC框(kuang)架(jia)里的(de)(de)Filter,Filter會(hui)自己(ji)注入(ru)到了每個Action執行(xing)的(de)(de)各個環節里,而我們可以(yi)直接實現自己(ji)的(de)(de)Filter即(ji)可,例如只(zhi)要(yao)是繼承ActionFilter,那(nei)么(me)你(ni)的(de)(de)Filter在Action執行(xing)時(shi)就(jiu)可以(yi)被動態執行(xing),這種設計就(jiu)相當(dang)于把(ba)整個Action橫切(qie)(qie)開來(lai),注入(ru)我們需要(yao)的(de)(de)代碼,這大概念就(jiu)是面(mian)(mian)(mian)向切(qie)(qie)面(mian)(mian)(mian)(方面(mian)(mian)(mian))編(bian)程的(de)(de)真諦吧!

LindAspects原理是什么

主要通過Emit實現對方法的重寫,這個方法不向Unity.Interception非要是虛方法,咱們的Emit本質上是建立一個新的類型,然后建立一個新的方法,這個方法里再去執行當前被攔(lan)截(jie)的方法(fa)的主體,然后(hou)通過主體方法實現的AspectAttribute來控制(zhi)是(shi)在主體執行(xing)前注(zhu)入還是(shi)在主體執行(xing)之后(hou)注(zhu)入!

配合LindPlugins實現對象的生產

方法(fa)的對(dui)象(xiang)如何生產(chan)(chan)一直是個(ge)問題,傳統方法(fa)是通過IoC去創建(jian)對(dui)象(xiang),而(er)你使(shi)用(yong)new去生產(chan)(chan)對(dui)象(xiang)一定是不行的,因為你的攔截器無法(fa)注入到實例上,在Lind環境里(li),一切(qie)組件都應該是“插件(LindPlugins)”,它們的注冊和(he)生產(chan)(chan)也是統一的,都是通過LindPlugins來實現,當前再往底(di)層看,Plugins本身也是通過autofac這個(ge)ioc容器實現的,呵呵。

兩種生產攔截對象的對比

Aspects本身的工廠生產

    [TestMethod]
        public void TestMethod1()
        {
            ITest test = ProxyFactory.CreateProxy(typeof(ITest), typeof(LoggerAspectAttribute)) as ITest;
            test.Do();
        }

LindPlugins的容器生產

     [TestMethod]
        public void AspectCachingGet()
        {
            var old = PluginManager.Resolve<IAopHelloTest2>();
            var result = old.GetData("zz", 1);
            Console.WriteLine(result);
        }

LindAspects設計圖

CachingAspectAttribute在介紹(shao)

數據緩存這個東西經常被我們提到,現在很多產品都是異步緩存,就是先生成緩存數據,然后在方法里直接從緩存取即可,而今天大叔說的CachingAspectAttribute是指(zhi)在方法中進行(xing)攔(lan)截(jie),緩存(cun)添(tian)加(jia)與讀取的(de)(de)動作完成由特(te)性(xing)攔(lan)截(jie)器去做,這樣做的(de)(de)好處是把業務邏輯與緩存(cun)邏輯分開,解耦你的(de)(de)代(dai)碼(ma)!

     /// <summary>
        /// 有返回(hui)值的方法攔(lan)截動作
        /// </summary>
        /// <param name="context"></param>
        public override object FuncInvoke(InvokeContext context, MethodInfo methodInfo)
        {
            var paramList = InitParams(context, methodInfo);
            var obj = Activator.CreateInstance(methodInfo.ReflectedType);
            switch (cachingMethod)
            {
                case CachingMethod.Get:
                    #region 讀緩存
                    //redis鍵名,在(zai)put和get時使用
                    var key = prefix + context.Method.MethodName;
                    //hashset鍵名,參數組合
                    var param = string.Join("_", context.Parameters.Select(i => i.Para));
                    if (!RedisClient.RedisManager.Instance.GetDatabase().KeyExists(key))
                    {
                        var objValue = methodInfo.Invoke(obj, paramList.ToArray());
                        RedisClient.RedisManager.Instance.GetDatabase().HashSet(key, param, Lind.DDD.Utils.SerializeMemoryHelper.SerializeToJson(objValue));
                        return objValue;
                    }
                    var entity = RedisClient.RedisManager.Instance.GetDatabase().HashGet(key, param);
                    return Lind.DDD.Utils.SerializeMemoryHelper.DeserializeFromJson<object>(entity.ToString());
                    #endregion
                case CachingMethod.Remove:
                case CachingMethod.Put:
                    #region 緩存失效
                    var putvalue = methodInfo.Invoke(obj, paramList.ToArray());
                    RemoveCache(methodInfo);
                    return putvalue;
                    #endregion
                default:
                    throw new InvalidOperationException("無(wu)效(xiao)的緩(huan)存方(fang)式。");
            }
        }

本緩存特性(xing)主(zhu)要使用(yong)redis實現持久化,在(zai)key的(de)設計上(shang)(shang)使用(yong)了前綴(zhui)在(zai)方(fang)(fang)法名(ming)及方(fang)(fang)法參數的(de)規則,存儲結構如hashset,在(zai)緩存失效上(shang)(shang)使用(yong)了方(fang)(fang)法的(de)動態觸發,我(wo)們可以看(kan)到,代碼(ma)中定義了緩存的(de)方(fang)(fang)式,讀(du),加,移除等,我(wo)們可以在(zai)具體方(fang)(fang)法上(shang)(shang)控制緩存的(de)類(lei)型,下面是(shi)具體方(fang)(fang)法的(de)特性(xing)注入,代碼(ma)如下:

  public class AopHello : IAopHelloTest2
    {
        #region IHello 成員
        [CachingAspect(CachingMethod.Get)]
        public List<DtoUser> GetData(string title, int age)
        {
            //讀取數(shu)據的業務代碼
            return new Test_Code_FirstEntities().WebManageUsers.Select(i => new DtoUser
            {
                Id = i.ID,
                Name = i.LoginName
            }).ToList();

        }

        [CachingAspect(CachingMethod.Remove, "GetData")]
        public void AddData(string title)
        {
             //添加數(shu)據的業(ye)務代碼...
        }

        #endregion
    }

從代(dai)(dai)碼(ma)中(zhong)可以(yi)看(kan)到,業(ye)務(wu)代(dai)(dai)碼(ma)如負責自己(ji)的業(ye)務(wu),緩(huan)存(cun)注入(ru)只是一個特(te)性(xing)標記!這才是大叔希望(wang)看(kan)到的緩(huan)存(cun)注入(ru)點!

感謝各位的閱讀,希(xi)望文章(zhang)給大(da)家一些啟發!

回到目錄

 

posted @ 2016-12-20 16:33  張占嶺  閱讀(1126)  評論(1)    收藏  舉報