c++ dll 類使用_在.Net Core 中使用鉤子

目錄

  • 前言
  • 什么是鉤子
  • 使用鉤子
  • 3. 掛載多個鉤子
  • 4. 在鉤子中加載額外的程序集
  • 5. 在 Asp.Net Web Api 項目中使用鉤子
  • 結束語
  • 演示代碼下載

前言

????Host startup hook,是2.2中提供的一項新的功能,通過使用主機啟動鉤子,允許開發人員在不修改代碼的情況下,在服務啟動之前注入代碼;通過使用鉤子,可以對已部署好的服務在服務啟動期間自定義托管程序的行為;通過使用鉤子,可以對服務進行跟蹤或者遙測,也可以在服務啟動前對托管環境進行健康檢查;還可以通過鉤子動態加載程序集進行依賴注入等功能。

什么是鉤子

鉤子的作用原理是通過設置環境變量 DOTNET_STARTUP_HOOKS 的值將鉤子程序掛載到托管程序之中,在托管程序啟動的時候,CoreCLR 將按照鉤子列表順序進行檢查,初始化后執行每個鉤子程序,當鉤子列表中的鉤子程序被逐一執行完成后,托管程序將返回到程序主入口 Main 方法,進入一系列的啟動,鉤子程序可以是任何 .Net Core 版本的類庫項目,在項目內必須包含類 StartupHook 這是固定命名,且 StartupHook 必須是一個沒有命名空間的內部類,包含默認的靜態方法 Initialize(),符合此規范即可作為鉤子程序進行托管掛載

使用鉤子

1.首先創建一個控制臺項目 Ron.HooksDemo ,作為托管主機,用于掛載鉤子程序 Ron.Init

Ron.HooksDemo 的代碼非常簡單,僅僅輸出一句話

    class Program    {        static void Main(string[] args)        {            Console.WriteLine("程序已啟動");            Console.ReadKey();        }    }

2. 創建鉤子程序,Ron.Init

2.1 按照鉤子程序的規范,創建一個無命名空間的內部類 StartupHook ,且包含默認靜態方法 Initialize()

internal class StartupHook{    public static void Initialize()    {        Console.WriteLine("程序集:Ron.Init.dll");        Console.WriteLine("正在獲取服務器信息.....");        string[] drives = Environment.GetLogicalDrives();        Console.WriteLine("machineName:{0},OSVersion:{1},version:{2},userName:{3},CurrentDirectory:{4}Core Count:{5}WorkSet:{6}Drives:{7}",            Environment.MachineName,            Environment.OSVersion,            Environment.Version,            Environment.UserName,            Environment.CurrentDirectory,            Environment.ProcessorCount,            Environment.WorkingSet,            string.Join(",", drives));        Console.WriteLine("正在獲取網絡配置.....");        var hostName = Dns.GetHostName();        Console.WriteLine("HostName:{0}", hostName);        var addresses = Dns.GetHostAddresses(hostName);        foreach (var item in addresses)        {            IPAddress ip = item.MapToIPv4();            Console.WriteLine("AddressFamily:{0} Address:{1}", ip.AddressFamily, ip);        }        Console.WriteLine("正在上報啟動信息.....");        Console.WriteLine("=========== Ron.Init.dll 結束 ===========");    }}

上面的代碼即表示一個標準的鉤子程序,在 Initialize() 內部,進行托管主機檢查,獲取網絡配置等行為,最好,還打印一條上報到遙測服務器的信息,這里是模擬上報檢查報告,最后輸出結束信息代碼非常檢查,現在打開 Ron.HooksDemo 項目屬性頁進行鉤子掛載

b3e6e4a8179db98cfd853ff6f9a2ab74.png

上圖添加環境變量 DOTNET_STARTUP_HOOKS ,并設置其值為 C:甥敳獲AdministratorSourceReposRon.HooksDemoRon.InitbinDebugetcoreapp2.2Ron.Init.dll,這是本次示例的鉤子程序絕對路徑注意:該環境變量的值不支持相對路徑,如果嘗試使用相對路徑,托管主機將拋出 ArgumentException 異常

2.2 運行程序,看看是否正確掛載了鉤子程序 Ron.Init

5fbf0606c94c7d29b014e949013c9094.png

上圖紅色部分輸出信息表示鉤子程序掛載成功,藍色部分表示托管主機已啟動,可以看到,托管主機啟動是在掛載鉤子之后運行的一定要注意,鉤子是在托管程序的 Main 方法之前運行的

3. 掛載多個鉤子

3.1 一個托管程序可以掛載多個鉤子

掛載多個鉤子的方法是設置環境變量 DOTNET_STARTUP_HOOKS 的值,多個鉤子按順序執行,其中 Windows 和 Unix 掛載多個鉤子的方式基本相同,這其中,有一點微小的區別

  • Windows 平臺掛載方式
DOTNET_STARTUP_HOOKS = C:Hooks_1.dll;C:Hooks_2.dll
  • Unix 平臺掛載方式
DOTNET_STARTUP_HOOKS =/data/Hooks_1.dll:/data/Hooks_2.dll

以上 DOTNET_STARTUP_HOOKS 變量的值包含兩個鉤子程序,其中 Windows 平臺的值為使用分號(;)進行分隔,Unix 平臺使用冒號(:)進行分隔,這于傳統使用方式一致

3.2 運行掛載了多個鉤子的托管程序

  • 下面把兩個鉤子掛載到 Ron.HooksDemo 項目后,他們分別是:Ron.Init 和 Ron.License

Ron.Init 鉤子輸出的是檢查服務器信息,這個信息在之前已經演示,這里不再重復,下面看 Ron.License 代碼

    public static void Initialize()    {        Console.WriteLine("程序集:Ron.License.dll");        Console.WriteLine("作者:Ron.liang");        Console.WriteLine("博客地址:https://www.cnblogs.com/viter/");        Console.WriteLine("=========== Ron.License.dll 結束 ===========");    }
  • 鉤子程序的 Ron.License 代碼也非常簡單,結構和 Ron.Init 鉤子程序一致,只是簡單的輸出版權信息

3.3 運行 Ron.HooksDemo 程序,看下圖輸出結果

223f4f534b16ea858bf9c9af8466f4e4.png

紅色部分是 Ron.Init 鉤子輸出信息,黃色部分是 Ron.License 輸出信息,藍色部分是托管主機 Ron.HooksDemo 輸出信息可以看到,鉤子上安裝掛載的順序執行的

4. 在鉤子中加載額外的程序集

我們應該這么理解,鉤子程序也是一個普通的應用程序集;所以一個普通的程序集能做到事情,鉤子也一樣可以

4.1 在 Ron.License 加載一個程序集 Ron.Service,Ron.Service 中定義了一個類 UserService,繼承自并實現 IDisposable 接口

    public class UserService : IDisposable    {        public void Dispose()        {            Console.WriteLine("程序集:Ron.Service.dll");            Console.WriteLine("動態加載程序集,執行清理任務已完成");            Console.WriteLine("=========== Ron.Service.dll 結束 ===========");        }    }

4.2 在 Ron.License 的鉤子方法中加載 Ron.Service 程序集,創建 IDisposable 的實現,并調用 Dispose() 方法

internal class StartupHook{    public static void Initialize()    {        Console.WriteLine("程序集:Ron.License.dll");        Console.WriteLine("作者:Ron.liang");        Console.WriteLine("博客地址:https://www.cnblogs.com/viter/");        string path = @"C:甥敳獲AdministratorSourceReposRon.HooksDemoRon.ServicebinDebugetcoreapp2.2Ron.Service.dll";        var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);        dynamic obj = assembly.CreateInstance("Ron.Service.UserService");        obj.Dispose();        Console.WriteLine("=========== Ron.License.dll 結束 ===========");    }}

4.3 運行程序 Ron.HooksDemo

46d3577de8e6f6a7896ab11bcbf09a42.png

從輸出結果看到,Ron.Service 程序集已被成功加載并調用,控制臺紅色輸出信息部分表示加載成功

5. 在 Asp.Net Web Api 項目中使用鉤子

Web Api 項目掛載鉤子的方式和控制臺方式相同,首先我們還是創建一個 Web Api 項目 Ron.HooksDemo.Web接著掛載鉤子

  "DOTNET_STARTUP_HOOKS": "C:甥敳獲AdministratorSourceReposRon.HooksDemoRon.InitbinDebugetcoreapp2.2Ron.Init.dll;C:甥敳獲AdministratorSourceReposRon.HooksDemoRon.LicensebinDebugetcoreapp2.2Ron.License.dll"

5.1 運行 Web Api 項目 Ron.HooksDemo.Web

581ecf772e5e813f088dad891a8648e7.png

紅色輸出部分表示 Web Api 程序的 Main 方法在鉤子列表執行完成之后成功啟動,這表示在 .Net Core 中,掛載鉤子的方式是一致的,其行為也相同

結束語

使用鉤子程序注意事項

鉤子程序不能依賴于托管主機的TPA列表之外的任何程序集,否則會拋出 FileNotFoundException 的異常不要掛載過多的鉤子程序,這可能會出現兼容性問題,如果要使用多個鉤子,必須確保每個鉤子程序的行為都是獨立的,互不干擾的,如果一定要使用,建議修改托管主機的代碼,使用依賴注入的方式而不是鉤子StartupHook 類應該是 internal 類型的,如果是使用 public 進行修飾,還是可以正常加載鉤子程序

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/392635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392635.shtml
英文地址,請注明出處:http://en.pswp.cn/news/392635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3c技能和背包需要改建嗎?_認為您需要儀表板? 您應該改建一個筆記本。

3c技能和背包需要改建嗎?by Mahdi Karabiben通過Mahdi Karabiben 認為您需要儀表板? 您應該改建一個筆記本。 (Think you need a Dashboard? You should build a Notebook instead.) After first establishing themselves as a key component of the standard Bu…

leetcode 147. 對鏈表進行插入排序

對鏈表進行插入排序。 插入排序的動畫演示如上。從第一個元素開始,該鏈表可以被認為已經部分排序(用黑色表示)。 每次迭代時,從輸入數據中移除一個元素(用紅色表示),并原地將其插入到已排好序的…

JSP過濾器Filter配置過濾類型匯總

一、配置方法1 映射過濾應用程序中所有資源<filter> <filter-name>loggerfilter</filter-name> <filter-class>myfilter.LoggerFilter</filter-class></filter><filter-mapping> <filter-name>loggerfilter</filt…

ERP流程入門_從會計分錄理解企業基本流程[轉]

ERP流程入門_從會計分錄理解企業基本流程 本貼寫給尚未在企業工作過的朋友&#xff01;了解企業的基本流程的一個方法是看它的會計分錄,我們現在來看一個完整的企業基本流程&#xff0c;它的會計分錄是如何做的&#xff0c;其中有些帳戶名稱可能不一樣&#xff0c;不過沒關系&a…

薩默爾機器人_助力產業發展 西安市人工智能機器人學會正式成立

8月23日&#xff0c;西安市人工智能機器人學會在西咸新區灃東新城協同創新港正式成立。西安報業全媒體記者 馮煒 攝8月23日&#xff0c;西安市人工智能機器人學會正式成立。學會將通過市場化機制、社會化服務等方式&#xff0c;整合科技創新資源和人才培養資源&#xff0c;促進…

粒度過粗_這些書幫助我度過了第一次成為技術主管的經歷

粒度過粗by Danny Perez丹尼佩雷斯(Danny Perez) 這些書幫助我度過了第一次成為技術主管的經歷 (These books helped me navigate my first time being a tech lead) The tech lead was moving to another team for a long-term assignment, and I took over as the engineeri…

隨便說說:在ASP.NET應用程序中上傳文件

在Web程序中上傳文件是很常見的需求。利用HTTP協議上傳文件的方式非常有限&#xff0c;最常見的莫過于使用<input type"file" />元素進行上傳。這種上傳方式會將內容使用multipart/form-data方案進行編碼&#xff0c;并將內容POST到服務器端。使用multipart/fo…

leetcode 148. 排序鏈表(歸并排序)

給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。 進階&#xff1a; 你可以在 O(n log n) 時間復雜度和常數級空間復雜度下&#xff0c;對鏈表進行排序嗎&#xff1f; 示例 1&#xff1a; 輸入&#xff1a;head [4,2,1,3] 輸出&#xff1a;[1…

理論與哲學就是梳理無限感性經驗和知性知識的工具

理論與哲學就是梳理無限感性經驗和知性知識的工具&#xff0c; 是因為人腦的特性&#xff0c;或者說人腦功能的局限性而被人創造出來的思想工具。 工具服務于實踐&#xff0c;并被實踐所檢驗&#xff08;描述、解釋、預見&#xff09;。 工具一旦創建就有其客觀性&#xff0c;但…

記一次調用API遇到的問題

調用sonar API 接口&#xff0c;地址如下&#xff1a; http://sonar.*****.com/api/measures/search_history?componenttcmp-devops-service&metricssqale_index%2Cduplicated_lines_density%2Cncloc%2Ccoverage%2Cbugs%2Ccode_smells%2Cvulnerabilities&ps1000 url上…

h5滾動隱藏滾動條_這 10 個值得開啟的隱藏功能,讓你的 Chrome 釋放更多潛力

上次分享了讓 Chrome 瀏覽器用得更順手的地址欄命令&#xff0c;跟大家整理和介紹了多個 Chrome 地址欄命令&#xff0c;利用好這些命令工具能夠提升瀏覽器配置效率&#xff0c;讓你的 Chrome 瀏覽器用得更順手。這次介紹的是 Chrome 內置的實驗功能&#xff0c;它被單獨放在了…

redux ngrx_另一個減少Redux(NGRX)應用程序樣板的指南

redux ngrxby Andrey Goncharov通過安德烈貢恰洛夫(Andrey Goncharov) 另一個減少Redux(NGRX)應用程序樣板的指南 (Yet another guide to reduce boilerplate in your Redux (NGRX) app) 我們在這里要覆蓋什么&#xff1f; (What are we gonna cover here?) In this article,…

leetcode 242. 有效的字母異位詞

給定兩個字符串 s 和 t &#xff0c;編寫一個函數來判斷 t 是否是 s 的字母異位詞。 示例 1: 輸入: s “anagram”, t “nagaram” 輸出: true 示例 2: 輸入: s “rat”, t “car” 輸出: false 代碼 class Solution {public boolean isAnagram(String s, String t) {…

技巧:使用User Control做HTML生成

User Control大家肯定不會陌生&#xff0c;在使用ASP.NET的過程中&#xff0c;除了aspx頁面&#xff0c;最常見的就莫過于ascx了。ascx是一個有獨立邏輯的組件&#xff0c;提供了強大的復用特性&#xff0c;合理使用&#xff0c;能夠大大提高開發效率。通過User Control直接生成…

Spring Boot干貨系列:(二)配置文件解析

前言 上一篇介紹了Spring Boot的入門&#xff0c;知道了Spring Boot使用“習慣優于配置”&#xff08;項目中存在大量的配置&#xff0c;此外還內置了一個習慣性的配置&#xff0c;讓你無需手動進行配置&#xff09;的理念讓你的項目快速運行起來。所以&#xff0c;我們要想把S…

mysql常用操作記錄

&#xff08;1&#xff09;判斷表中一個字段是空&#xff0c;可為&#xff1a;字段名 IS NULL&#xff08;2&#xff09;類似oracle的decode作用&#xff1a;IF(字段名>0,字段名,0)&#xff08;3&#xff09;時間格式&#xff08;年-月-日&#xff09;&#xff1a;DATE_FORM…

小愛音響調用php接口_阿里API調用二(PHP)

接口地址拼合成功后&#xff0c;用curl函數post獲取阿里返回的完整數據&#xff0c;將地址傳入getContent()方法中&#xff0c;絕對能獲取用戶數據。public function getContent($url){$ch curl_init();// 初始化curl_setopt($ch,CURLOPT_URL,$apiprourlall);curl_setopt($ch,…

leetcode 452. 用最少數量的箭引爆氣球(貪心算法)

在二維空間中有許多球形的氣球。對于每個氣球&#xff0c;提供的輸入是水平方向上&#xff0c;氣球直徑的開始和結束坐標。由于它是水平的&#xff0c;所以縱坐標并不重要&#xff0c;因此只要知道開始和結束的橫坐標就足夠了。開始坐標總是小于結束坐標。 一支弓箭可以沿著 x…

javascript編程題_如何開始使用JavaScript進行競爭性編程

javascript編程題by Priyabrata Biswas通過Priyabrata Biswas 如何開始使用JavaScript進行競爭性編程 (How to get started with Competitive Programming in JavaScript) If you’re not familiar with competitive programming, basically it is a mind sport with the aim …

hibernate Criteria(條件查詢接口)

Criteria&#xff08;條件查詢接口&#xff09; // 1.簡單查詢 List<Customer> list session.createCriteria(Customer.class).list();// 2.條件查詢: Criteria criteria session.createCriteria(Customer.class); criteria.add(Restrictions.eq("name",&quo…