AspNetCore 基於AOP實現Polly的使用

来源:https://www.cnblogs.com/szlblog/archive/2018/08/05/9425164.html
-Advertisement-
Play Games

前言 說起AOP,其實我們在做MVC/API 的時候應該沒少接觸,比如說各種的Fitter 就是典型的AOP了。 本來在使用Polly的時候我最初的打算是使用過濾器來實現的,後來發現實現起來相當的困難,利用NetCore的中間以及過濾器去實現一個AOP的獨立應用服務簡直了,我有點無奈,相當的難寫。 ...


前言  

說起AOP,其實我們在做MVC/API 的時候應該沒少接觸,比如說各種的Fitter 就是典型的AOP了。

本來在使用Polly的時候我最初的打算是使用過濾器來實現的,後來發現實現起來相當的困難,利用NetCore的中間以及過濾器去實現一個AOP的獨立應用服務簡直了,我有點無奈,相當的難寫。

後來又使用了,Autofac 做攔截器來實現也是有點小無力。估計還是基礎太薄弱。

目前我瞭解到的實現Polly比較方便的第三方Aop框架的有

(1)AspectCore:是一款 AspNetCore輕量級的Aop解決方案。

(2)Dora.Interception 老A寫的一個Aop解決方案,這個用到解決方案中就需要等到老A升級下一版了。

 

  AspNetCore中的過濾器

在使用Policy 的時候主要點是策略的制定,在保證代碼整潔,並且不破壞當前代碼邏輯的情況下,使用Aop是最合適的解決方案了。

當我們使用過濾器的時候我們會發現,Pollicy 制定了一個錯誤規則,並且在錯誤過濾器中使用、抓取不到任何的錯誤信息,因為錯誤信息被錯誤過濾器抓取了,這個時候不會觸發Pollicy

 

然後嘗試著 用過濾實現一個 當程式發生錯誤的時候,執行另一個方法的功能,類似Policy的重試策略或降級。

下麵代碼:

編寫:一個過濾器類:

 

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Reflection;


namespace InterceptorCoreLibrary
{
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]
    public class CoreExceptionFilter:Attribute, IExceptionFilter,IActionFilter
    {
        /// <summary>
        /// 發生錯誤的時候重新執行的方法
        /// </summary>
        public string FallBackClass { get; set; }
        /// <summary>
        /// 發生錯誤的時候重新執行的方法
        /// </summary>
        public string FallBackMethod { get; set; }

        /// <summary>
        /// 獲取方法的參數
        /// </summary>
        public object[] InvokeParameters { get; set; }

        /// <summary>
        /// 構造函數使用該類時參數為方法
        /// </summary>
        /// <param name="fallBackMethod"></param>
        public CoreExceptionFilter(string fallBackClass, string fallBackMethod) 
        {
            this.FallBackMethod = fallBackMethod;
            this.FallBackClass = fallBackClass;
        }
        /// <summary>
        /// 使用新方法
        /// </summary>
        /// <param name="asm"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private object UseNewMethod(Assembly asm, object[] parameters)
        {
            Object obj = null;
            foreach (Type type in asm.GetExportedTypes())
            {
                if (type.Name == FallBackClass)
                {
                    obj = System.Activator.CreateInstance(type);
                    foreach (var item in type.GetMethods())
                    {
                        if (item.Name == FallBackMethod)
                        {
                            obj = type.GetMethod(FallBackMethod).Invoke(obj, parameters);
                        }
                    }
                }
            }
            return obj;
        }
        /// <summary>
        /// 獲取所有被監控方法的參數
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            object[] parameters = new object[context.ActionArguments.Count];
            int Count = 0;
            foreach (var item in context.ActionArguments)
            {
                parameters[Count] = item.Value;
                Count++;
            }
            InvokeParameters = parameters;
        }

        /// <summary>
        /// 錯誤的時候執行新的方法
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            var objectResult = context.Exception as Exception;
            if (objectResult.Message != null)
            {
                //context.Result = new ObjectResult(UseNewMethod(this.GetType().Assembly, InvokeParameters));
                 context.Result = new ObjectResult(new { Success = true, code = 200, msg = "成功", Data = UseNewMethod(this.GetType().Assembly, InvokeParameters) });
            }
        }
        public void OnActionExecuted(ActionExecutedContext context)
        {
           
        }
    }
}

 

在控制器中使用:

 

 [CoreExceptionFilter(nameof(UserModel), nameof(Delete))]

 

   在執行的時候我拋送一個異常信息

    [CoreExceptionFilter(nameof(UserModel), nameof(Delete))]

        // DELETE api/values/5

        [HttpDelete("{id}")]

        public int Delete(int id)

        {

            throw new Exception();

        }

當方法執行出錯的時候執行另一個方法:

如下:註意參數一致:

using System;
using System.Collections.Generic;
using System.Text;

namespace InterceptorCoreLibrary
{
    public class UserModel
    {
        public int   Delete(int id)
        {
            //記錄日誌
            //重新執行一遍代碼
            return id;
        }
    }
}

執行結果:

 

返回結果:

 

 

這個時候我們能看到過濾器先抓取了錯誤信息,Policy 就抓不到了,但同樣實現了降級的功能。

如果我們不使用Aop的話 直接在控制器中寫

比如:這樣寫一個兩個還行多了的話,代碼就相當的亂了。

 

 // DELETE api/values/5
        [HttpDelete("{id}")]
        public int Delete(int id)
        {
            var PolicyExecute = Policy.Handle<Exception>().Fallback(() =>
              {
                  //程式報錯重新執行一個新的方法
                  UserModel userModel = new UserModel();
                  userModel.Delete(id);
             });
            
            //執行
             PolicyExecute.Execute(() =>            {
                                throw new Exception();
                            }
                           );
        }

以上代碼雖然沒有實現policy ,但是也演示出了大致使用Aop實現 Policy的過程原理。

使用AspectCore 實現Policy

這裡貼出一份楊中科老師 在普及AspNetCore微服務課程中的代碼:支持原創,

完整的代碼這裡貼出過:

http://www.cnblogs.com/qhbm/p/9228238.html

 

使用Dora.Interception 實現Policy

我在Demo中進行了簡單的實現:這裡就不貼出了,因為框架還不是很完善,我問了作者老A,要等到下一版出來後用在項目中才比較穩妥。大家可以關註一下老A博客。

截圖說明一下兩個框架的區別,到時候可根據框架需要酌情使用:

 

  有不足之處 希望大家指出相互學習,

                                     本文原創:轉載請註明出處 謝謝!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、Python編譯器簡介 根據實現Python編譯器語言一般分為以下幾種: 1.1、CPython 標準的Python,解釋型編譯器。 Python:標準的CPython版本,即官方發佈版本。 IPython:基於CPython的一個互動式解釋器,也就是說,IPython只是在交互方式上有所增強, ...
  • Hello Python3 數據類型以及傳參 內置函數 正則表達式 文件操作 異常處理 類和對象 MySQL操作 Socket編程 線程 HTTP請求 JSON 日期時間 感想 解決問題的思路才是關鍵,編程語言只是語法不同而已。 習慣性以分號結尾;哈哈哈!!! ...
  • .net core使用配置文件 在 .net core中,配置文件的讀取是通過IConfiguration來提供的,程式集是 ,對應的有一系列的實現,通過這些實現,可以讀取Json/Xml/ini等類型的配置文件。 在本節示例中,我們使用Json配置文件做演示。 讀取Json配置文件 Json是我們 ...
  • [TOC] C 編程指南 前不久在 Github 上看見了一位大牛創建一個倉庫: "CSharpCodingGuidelines" ,打開之後看了一下 相關描述,感覺應該很不錯,於是就 clone 到本地拜讀一下,這裡列一些自己的筆記,方便日後回顧。 基本原則 Astonishment 原則:你的代 ...
  • 今天我準備記錄一篇關於遍歷的博客,因為覺得它是我們以後工作最常用的一種方法了。比如說在一個模塊里插入小圖標,如京東網頁右側的小圖標<i></i>。 精靈圖中遍歷也是不可或缺的重要用法。 遍歷又是迴圈中最常見的問題。 所謂遍歷,是指有某個範圍的樣本數,需要把樣本中的每個數據取出來一一分析。 比如,輸出 ...
  • 今天試了下mvc自帶的ajax,發現上傳文件時後端action接收不到文件, Request.Files和HttpPostedFileBase都接收不到。。。。。後來搜索了下才知道mvc自帶的Ajax不支持文件上傳,無奈之下只能用其他的方式 第一種方式:通過 jquery的ajaxSubmit 》( ...
  • cSharp_1_概述 名詞描述 C# 是一門語言,語法與javascript、C、C++、java相近,這些語言都是比C語言的語系中發展而來。 .net framework (Framework是框架的意思)asp.net軟體的編譯和運行平臺,電腦必須安裝了這個軟體才可以運行我們編寫的C#應用程 ...
  • 概述 Gaze Input & Tracking - 也就是視覺輸入和跟蹤,是一種和滑鼠/觸摸屏輸入非常不一樣的交互方式,利用人類眼球的識別和眼球方向角度的跟蹤,來判斷人眼的目標和意圖,從而非常方便的完成對設備的控制和操作。這種交互方式,應用場景非常廣泛,比如 AR/VR/MR 中,利用視覺追蹤,來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...