iT邦幫忙

2022 iThome 鐵人賽

DAY 4
1
自我挑戰組

[Dot Net Core](圖解系列與常用套件)系列 第 4

[Dot Net Core](圖解系列) 4. 實際如何實行DI Resolve Service

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20220904/20144614GHSoU9WVno.jpg

上一節介紹了.Net Core 如何前置準備有關 IOC的物件,可以供程式呼叫 Provider 的方法來 Resolve Service。這節會介紹呼叫後實際上如何Resolve Service。

https://ithelp.ithome.com.tw/upload/images/20220904/20144614euBT7TTg2w.jpg

當選擇的 Provider 為 ServiceProviderEngineScope ,即可呼叫 GetService 來進行Resolve。圖中S1步驟,為一開始的呼叫,接著會往引擎的部位去進行,即 ServiceProviderEngine,也是呼叫GetService的函式,如圖S2步驟,會去找RealizedService的集合。此集合存放註冊的服務對應Resolve的委派函示。如果還未Resolve過,則需呼叫CreateServiceAccessor進一步由CallSiteFactory.GetCallSite來取得對應的CallSite物件。CallSiteFactory.GetCallSite 會先到 CallSiteFactory._cacheCallSite集合中找是否已經有對應的CallSite物件,如果沒有的話需呼叫CallSiteFactory.CreateCallSite函式來新增。

當依照之前註冊好的service資訊建立CallSite物件後,如圖S3步驟,會作一次驗證,也就是模擬一次實際Resolve看看是否有錯誤,如果有錯誤則, throw exception to handle。

接下來執行 DynamicServiceProviderEngine.RealizeService函式,此會回傳一個委派事件讓S1步驟的GetService來叫用。

圖S5步驟即為執行RealizeService函式,其參數為ServiceProviderEngineScope本身。隨 CallSite.kind 的不同,呼叫CallSiteRuntimeResolver 中的路線也不同。

下圖以CallSite.kind為Constructor為例:

https://ithelp.ithome.com.tw/upload/images/20220904/20144614fWPLFQwryv.jpg

S5步驟呼會於CallSiteRuntimeResolver類別中叫用函式,其路徑為:

Resolve > VisitCallSite > VisitRootCache > VisitCache > VisitCallSiteMain > VisitConstructor

如果跑到 VisitConstructor,勢必要找此服務的ConstructorCallSite物件來執行Resolve,產生實體。

附帶一提,如果Constructor 的參數有其它的物件也需要DI,會於呼叫路徑的VisitCallSiteMain中再次遞迴呼叫VisitCallSite,直到所有的參數都完成Resolve。

下圖再以CallSite.kind為Factory為例:

https://ithelp.ithome.com.tw/upload/images/20220904/20144614s9K3XzQS7t.jpg

CallSite.kind 為 Factory,代表當初註冊服務是以委派的函式進行,會希望實作出的服務以自行設計的委派函式產生實體。

S5步驟呼會於CallSiteRuntimeResolver類別中叫用函式,其路徑為:

Resolve > VisitCallSite > VisitRootCache > VisitCache > VisitCallSiteMain > VisitFactory

如果跑到 VisitFactory,勢必要找此服務的FactoryCallSite物件來執行Resolve,也就是用當初註冊到ServiceDescriptor中的委派函式來產生實體。

GetService要看是什麼Provider中的,如果是DynamicServiceProviderEngine 會走IOC。

例如StartUp class 不是走IOC,其建構子中的參數物件需要執行 GetService的Provider是HostServiceProvider。

GetService決定要跑什麼 case 是在 註冊的時候註冊到 ServiceDescriptor 就先收集好的,都在system.type中的資訊內,
最後在 GetService 中 取得 ServiceCallSite 時 經過這些資訊判斷,產生 對應種類的 callSite (ConstantCallSite、FactoryCallSite、ConstructorCallSite)
Type.GetTypeInfo() 可以看見相關資訊包含有沒有constructor、有哪些method、public或private與組件資訊等。

下一節會開始探討 MiddleWare 如何運作。


上一篇
[Dot Net Core](圖解系列) 3. IOC - 牽動框架設計的重要環節 - An important part of system design-an IOC overview
下一篇
[Dot Net Core](圖解系列) 5. MiddleWare –UseEndpoint to Map Controller
系列文
[Dot Net Core](圖解系列與常用套件)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言