【特別的騷氣】asp.net core運行時注入服務,實現類庫熱插拔


引言

很久之前在群里有看到說asp.net core能不能在運行時注入程序,當時並沒有太在意,剛才在某個群里又看到有人再問,core能不能在運行時注入服務,閑來無事,我就研究了一下,其實也比較簡單,在之前手寫IOC的文章中,我們着重介紹了幾個比較重要的接口,這里我們就需要用到那篇文章說到的接口,不明白的同學,傳送門在此:Asp.net core自定義依賴注入容器,替換自帶容器 - 四處觀察 - 博客園 (cnblogs.com)

IServiceProvider

在這里我們只需要用到這個接口,這個接口有一個GetService的一個方法,我們在創建對象的時候獲取對象構造函數依賴的時候可以直接調用這個方法獲取參數的對象,那我們都知道這個是IOC容器服務提供者,那它內部肯定是有一個字段或者屬性,來存放我們注入或者是系統內部注入的類型的容器,不管是list或者數組,總之肯定是有這么一個東西存在的,所以我在反射的時候發現了在其實現類ServiceProvider中,有一個名為_realizedServices的字段,存放着我們所有注入的服務,看源碼我們發現這個字段是一個ConcurrentDictionary類型的一個對象,其中第一個參數為我們注入的對象的類型,第二個參數實際上是一個創建這個Type的一個Func方法,傳入的那個ServiceProviderEngineScope方法內部也有一個GetService方法,這樣我們傳入這個委托的時候,其方法內部我們可以從容器獲取我們創建對象的參數,前提是你在運行時注入了你所依賴的參數,否則,肯定是會報錯的。

 

       

 

 

 

重頭戲

在上面看完源碼之后,我相信很多同學肯定知道怎么做實現運行時的一個動態注入了,首先我們肯定是需要依賴IServiceProvider接口的實例的,所以我們動態注入的構造函數中肯定需要有這個參數,其次就是我們去GetType,然后GetField,然后在獲取到這個Field的具體的對象,然后我們找到ConcurrentDictionary的GetOrAdd方法或者TryAdd,這里我用的是GetOrAdd方法,然后調用,傳入對應的參數,就可以完成運行時的動態注入了,可以看到,我們在WeatherForecast接口構造函數中注入了我們依賴的Testdss類型的對象,然后我們構造了一個Func直接添加到了_realizedServices字段中,在第二張圖中,我們在構造函數傳入了一個IServiceScopeFactory參數去創建一個Scope然后去獲取我們注入的Testdss的對象,測試了一下,是沒有問題的,同時我在第一次測試的時候是直接傳入了Testdss類型的對象進行測試的,也是沒有問題的,所以不管是Scope類型的獲取或者直接依賴也是沒有問題的。

 

        

 

 

問題

聰明的同學,肯定知道這個其實是存在一個問題的,那就是在默認的注入中,我們對類型的生命周期是可以把控的,可以注入我們需要的單例,或者作用域,在或者是瞬時,但是在這個案例中,我們是沒有對這個運行時注入的Testdss做生命周期處理的,其實這個處理起來也簡單,我們可以自定定義幾個特性,用來標識是單例還是瞬時還是作用域,標記在動態注入的類上,然后在控制動態注入的類中,我們定義容器來存放我們注入的對象,然后在獲取的時候,根據類型創建好對象之后,如果是單例的是怎么的邏輯處理,如果是瞬時的又怎么處理,作用域的又怎么處理就行了,就可以實現運行時注入的生命周期的把控。

結語

好了,今天的分享就到此為止了,我是四川觀察,喜歡研究這等騷操作,喜歡幫助大家解決問題,歡迎大家騷擾,可以在所在的QQ群中查看有沒有叫四川觀察的,那就是我;也可以加QQ群6406277,也可以找到我。

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM