日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学完这篇依赖注入,与面试官扯皮就没有问题了。

發(fā)布時間:2023/12/4 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学完这篇依赖注入,与面试官扯皮就没有问题了。 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • IOC: ?Inversion Of Control 控制反轉(zhuǎn)

  • DI: ? Dependency ?Injection 依賴注入

1.控制反轉(zhuǎn) Inversion Of Control 的前世今生

1.1 ?IOC理論產(chǎn)生的背景

討論控制反轉(zhuǎn)之前,先看看軟件系統(tǒng)提出控制反轉(zhuǎn)的前世今生。
一個完整精密的軟件系統(tǒng),組件之間就像齒輪,協(xié)同工作,相互耦合。

  • 一個零件不正常,整個系統(tǒng)就崩潰了。

  • 系統(tǒng)對象之間耦合關(guān)系無法避免,在項目規(guī)模和復(fù)雜度變大的情況下,管理類之間的依賴關(guān)系將會很復(fù)雜。

  • 對象之間耦合度很高的系統(tǒng),架構(gòu)師和開發(fā)人員對于系統(tǒng)的修改,必然會出現(xiàn)牽一發(fā)而動全身的情形。

  • 對象之間耦合性依賴,單元測試很復(fù)雜。

1.2 IOC理論

軟件專家為此提出IOC理論,用來實現(xiàn)對象之間的解耦。
再來看看,控制反轉(zhuǎn)(IOC)到底為什么要起這么個名字?我們來對比一下:

  • 軟件系統(tǒng)在沒有引入IOC容器之前,對象A依賴于對象B,那么對象A在初始化或者運行到某一點的時候,自己必須主動去創(chuàng)建對象B或者使用已經(jīng)創(chuàng)建的對象B。無論是創(chuàng)建還是使用對象B,控制權(quán)都在自己手上。

  • 軟件系統(tǒng)在引入IOC容器之后,這種情形就完全改變了,由于IOC容器的加入,對象A與對象B之間失去了直接聯(lián)系,所以,當(dāng)對象A運行到需要對象B的時候,IOC容器會主動創(chuàng)建一個對象B注入到對象A需要的地方。
    通過前后對比,我們不難看出:
    對象A獲得依賴對象B的過程,由主動變?yōu)榱吮粍有袨?#xff0c;控制權(quán)顛倒過來,這就是“控制反轉(zhuǎn)”的由來。

  • 1.3 控制反轉(zhuǎn) 和 依賴注入

    有些人會把控制反轉(zhuǎn)和依賴注入等同,實際上有本質(zhì)區(qū)別:
    控制反轉(zhuǎn)是一種思想;依賴注入是一種設(shè)計模式。
    依賴注入是實現(xiàn)控制反轉(zhuǎn)的一種方式,但是控制反轉(zhuǎn)還有其他實現(xiàn)方式,例如說ServiceLocator(服務(wù)定位器、依賴查找),所以不能將控制反轉(zhuǎn)和依賴注入等同。

    2 依賴注入 Dependency ?Injection

    依賴注入:容器全權(quán)負責(zé)組件的裝配,它會把符合依賴關(guān)系的對象通過屬性或者構(gòu)造函數(shù)傳遞給需要的對象。

    符合依賴倒置原則,高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象

    2.1 ASP.NET Core依賴注入

    使用方式大體類似:
    ①. 定義依賴實現(xiàn)的接口或者抽象類
    ②. 在服務(wù)容器中注冊組件依賴 :IServiceProvider
    ③. 在構(gòu)造函數(shù)中注入服務(wù), 框架會負責(zé)創(chuàng)建和銷毀實例

    //?編寫組件和服務(wù) public?interface?IMyDependency {string?WriteMessage(string?message); } --- public?class?MyDependency?:?IMyDependency {public?string?WriteMessage(string?message){return?$"MyDependency.WriteMessage?Message:?{message}";} } //?注冊組件和依賴,下面注冊的`IMyDependency`在一個web請求中有效 public?void?ConfigureServices(IServiceCollection?services) {services.AddScoped<IMyDependency,?MyDependency>();services.AddRazorPages(); } --- //?在構(gòu)造函數(shù)注入組件 public?class?HomeController:?AbpController {private?readonly?IMyDependency?_dep;public?HomeController(IMyDependency?dep){_dep?=?dep;}public?IActionResult?Index(){var?content?=??_dep.WriteMessage($"The?Reflection?instance?is?{_dep.GetType().FullName}?");return?Content(content);} }

    在請求某個服務(wù)時,框架會完整解析出這個對象的依賴樹和作用范圍。

    上面的示例代碼形成 req--->HomeController--->IMyDependency依賴樹。

    ?IMyDependency在每個web請求范圍內(nèi)使用同一服務(wù)實例。

    輸出:MyDependency.WriteMessage Message: The Reflection instance is TestDI.MyDependency

    2.2 對象生命周期

    根據(jù)現(xiàn)實需要,前人從使用場景中總結(jié)出三種服務(wù)生命周期。
    ASP.NET Core提供了一個枚舉ServiceLifetime:

    -----------
    Singleton單例服務(wù)容器首次請求會創(chuàng)建,后續(xù)都使用同一實例AddSingleton
    Scoped特定范圍在一個請求(連接)周期內(nèi)使用一個示例AddScoped
    Transient瞬時服務(wù)容器每次請求,都會創(chuàng)建一個實例AddTransient

    對于Scoped Service的理解:在webapp:scoped service 會在請求結(jié)束時被銷毀;
    在EFCore:使用AddDbContext默認注冊的是特定范圍的DbContext,這意味在我們可以在一次sql連接內(nèi),使用同一個DbContext實例進行多次DB操作。

    2.3 依賴注入實現(xiàn)原理

    結(jié)合理論、使用方式 猜測依賴注入的原理:
    實現(xiàn)DI,核心在于依賴注入容器IContainer,該容器具有以下功能
    ①.(容器)保存可用服務(wù)的集合
    // ?要用的特定對象、特定類、接口服務(wù)

    ②.(注冊)提供一種方式將各種部件與他們依賴的服務(wù)綁定到一起;
    // ?Add...函數(shù)或containerBuilder.Register函數(shù)

    ③.(解析點)為應(yīng)用程序提供一種方式來請求已配置的對象:構(gòu)造函數(shù)注入、屬性注入.

    運行時,框架會一層層通過反射構(gòu)造實例,最終得到完整對象。

    3.源碼導(dǎo)航

    利用反射產(chǎn)生對象是依賴注入的核心過程,這也是面試造航母時經(jīng)常問到的。

    .NETSystem.Reflection、System.Type命名空間中的類可以獲取可裝配組件、類、接口的信息,并提供了在運行時創(chuàng)建實例,調(diào)用動態(tài)實例方法、獲取動態(tài)實例的能力。

    當(dāng)我嘗試從github源碼中探究[依賴注入產(chǎn)生對象]的偽代碼時,文件/代碼眾多,迷路了!

    實際上,我們可以在依賴樹的尾部對象的構(gòu)造函數(shù)手動拋出異常,異常的調(diào)用棧就是一個天然的源碼導(dǎo)航。

    于是我在上面示例代碼的request----> HomeController--->MyDependency MyDependency構(gòu)造函數(shù)中添加異常代碼:

    ????public?MyDependency(){throw?new?Exception("exception content!");}

    結(jié)果如下圖:從Github Dependency Injection 庫進入System.Reflection的調(diào)用分界線代碼:

    protected?override?object?VisitConstructor(ConstructorCallSite?constructorCallSite,?RuntimeResolverContext?context) {object[]?parameterValues;if?(constructorCallSite.ParameterCallSites.Length?==?0){parameterValues?=?Array.Empty<object>();}else{parameterValues?=?new?object[constructorCallSite.ParameterCallSites.Length];for?(var?index?=?0;?index?<?parameterValues.Length;?index++){parameterValues[index]?=?VisitCallSite(constructorCallSite.ParameterCallSites[index],?context);}}try{return?constructorCallSite.ConstructorInfo.Invoke(parameterValues);}catch?(Exception?ex)?when?(ex.InnerException?!=?null){ExceptionDispatchInfo.Capture(ex.InnerException).Throw();//?The?above?line?will?always?throw,?but?the?compiler?requires?we?throw?explicitly.throw;} }

    黃色背景行就是.NET反射特性的體現(xiàn):
    對類型信息(構(gòu)造函數(shù)、參數(shù))使用Invoke方法產(chǎn)生對象。

    干貨旁白

  • 控制反轉(zhuǎn)是一種在軟件工程中解耦合的思想,調(diào)用方依賴接口或抽象類,減少了耦合,控制權(quán)交給了服務(wù)容器,由容器維護注冊項,并將具體的實現(xiàn)動態(tài)注入到調(diào)用方。

  • 有些人會把控制反轉(zhuǎn)和依賴注入等同,實際上有本質(zhì)區(qū)別:
    控制反轉(zhuǎn)是一種思想;
    依賴注入是一種設(shè)計模式。
    依賴注入是實現(xiàn)控制反轉(zhuǎn)的一種方式,但是控制反轉(zhuǎn)還有其他實現(xiàn)方式,例如說ServiceLocator,所以不能將控制反轉(zhuǎn)和依賴注入等同。

  • 在運行時,框架會解析依賴樹、依賴圖,通過反射在運行期生成對象。


    • ASP.NET Core 基于聲明的訪問控制到底是什么鬼?

    • 我又踩坑了!如何為HttpClient請求設(shè)置Content-Type標(biāo)頭?

    • 臨近年關(guān),修復(fù)ASP.NET Core因瀏覽器內(nèi)核版本引發(fā)的單點登錄故障

    • 手撕公司SSO登錄原理

    • 實戰(zhàn)解讀ASP.NET Core身份認證

    • ASP.NET Core應(yīng)用注意這一點,CTO會對你刮目相看

    總結(jié)

    以上是生活随笔為你收集整理的学完这篇依赖注入,与面试官扯皮就没有问题了。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。