1. 程式人生 > >Prism 原始碼解讀3-Modules載入

Prism 原始碼解讀3-Modules載入

## 介紹 在軟體開發過程中,總想元件式的開發方式,各個元件之間最好互不影響,獨立測試。Prism的Modules很好的滿足了這一點。 ![](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225558301-1721489782.png) 這個架構圖很好了講解了Prism的Modules的概念 Prism支援通過配置檔案,資料夾,手動載入Module的方式,並且對Module的載入進行驗證,包括重複和迴圈依賴驗證 Prism載入模組的順序 ![](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225612587-1306769571.png) 直接看原始碼吧 ## 0、Modules載入 - Modules的載入主要依靠ModuleCatalog來發現模組, - 通過ModuleManager來載入模組並對模組進行驗證以確保模組的載入順序, - ModuleInitializer負責模組的初始化,包括載入模組所必須的類和顯示UI Elements等等。 在Prism.PrismApplicationBase 的Initialize方法中呼叫 ![1585574598775](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538616-888557047.png) 建立目錄 ![1585574672183](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538631-62486994.png) RegisterRequiredTypes方法中向容器注入ModuleManager,ModuleInitializer, ![1585574816406](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538630-837257643.png) 最後呼叫了InitializeModules方法,並在其中呼叫了ModuleManager的Run方法 ![1585574852698](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538632-31279662.png) 看著兩個名字就明白了,第一個是發現模組並驗證模組,第二個是載入模組並初始化。 ![1585574917778](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538632-592136262.png) 看一下ModuleCatalogBase的Initialize方法,果然 ![1585574973443](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538631-1192325281.png) ![1585574987953](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538632-128845162.png) 而驗證就更加有意思了 ![1585575114834](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538633-1899228799.png) 重複性驗證 ![1585571571246](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538654-269099109.png) 通過模組名字ModuleNames來判斷是否被載入過,,如果存在就丟擲異常 載入順序驗證 ![1585572866324](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538654-954393316.png) 同時看一下ModuleBase ![1585575240730](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538663-1116753081.png) 每當items發生變化都會進行驗證 ![1585575308583](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538664-1413530195.png) ![1585575327939](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538665-1992457638.png) 發現驗證完了來看一下ModuleManage的LoadModulesWhenAvailable方法 ![1585575416018](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538682-60870506.png) ![1585575456472](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538684-2061302146.png) ![1585575508444](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538736-1459788632.png) ![1585575521164](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538741-1724278222.png) 看到最終使用了ModuleInitializer來初始化Module。其過程通過Linq實現延遲載入技術。 ![1585575588013](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538749-124345976.png) 在這個方法中發現Module必須實現IModle介面。並在這兒呼叫了RegisterTypes和OnInitialized方法。 模組的載入看完了,下面來看例子吧 ## 1、通過AppSetting載入 先看一下配置檔案 ![1585575781099](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538835-2082653511.png) 在初始化時 ![1585575803440](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538844-577539271.png) 看到重寫了CreateModuleCatalog,前面已經介紹過ModuleCatalog就是控制Module發現和驗證的。 ![1585575869468](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538846-362450134.png) ![1585575909447](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538848-265482678.png) ![1585575962111](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538887-2124780552.png) 可以看到section的名稱必須是modules。 先解析Module依賴邏輯,最後呼叫AddModule方法 ![1585577943221](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538897-1580856103.png) 再ModuleAModule中載入相關的UIElement。 ## 2、通過程式碼載入 通過程式碼載入就更簡單了,直接在ConfigureModuleCatalog方法中呼叫預設的ModuleCatalog載入相關的Module就可以了。 ![1585578152349](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538906-996983112.png) 在ModuleAModule中程式碼不變 這其中的邏輯在0節中已經解釋清楚了,就不在敘述。 ## 3、通過目錄載入 通過目錄載入,如果不看原始碼怎麼設計,需要建立一個ModuleCatalog,在建立的時候將目錄地址傳入。在內部InnerLoad方法中找到對應目錄,然後通過遍歷程式集找到實現IModule介面的類,載入這個類就可以了。 看了下原始碼也正是這麼做的 ![1585578439577](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538909-1978538547.png) ![1585578580233](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538939-1155877340.png) 看了原始碼發現官方考慮了更多的問題,比如建立了AppDoamin來載入程式集以保證隔離和資料安全。甚至還為其建立了一個InnerModuleInfoLoader類來反射程式集 ![1585578854546](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225538941-441699435.png) 這樣的指責分配非常好,我們甚至可以寫一個通過網路來載入Module的ModuleCatalog類。 ## 4、通過手動方式載入 ![1585579279370](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225539051-1205963972.png) 先在ConfigureModuleCatalog中將所有的Module載入進來,並將InitializationMode的方式設定為按需, ![1585579366391](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225539059-1389352781.png) 那麼就可以在需要的時候利用LoadModule方法載入之前載入的Module ![1585579427491](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225539071-622200833.png) ![1585579463038](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200330225539086-1037128174.png) 值得注意的是並沒有提供解除安裝Module的介面。 ## 總結 這一篇介紹了下Modules載入的原理,其實就是 - ModuleCatalog負責發現Module。 - 通過ModuleManager來載入模組並對模組進行驗證以確保模組的載入順序, - ModuleInitializer負責模組的初始化,包括載入模組所必須的類和顯示UI Elements等等。 下一篇開始將介紹MVVM的