1. 程式人生 > >Prism 原始碼解讀1-Bootstrapper和Region的建立

Prism 原始碼解讀1-Bootstrapper和Region的建立

## 介紹 之前也研究過Prism框架但是一直沒有深入理解,現在專案上想把一個Winform的桌面應用程式改造成WPF程式,同時我希望程式是可測試可維護架構良好的,Prism的這些設計理念正好符合我的需求,其主要用於WPF和Xamarin,用於構建鬆耦合,可維護,可測試的應用程式框架,在我看到原始碼後也深受啟發,歡迎大家一起交流探討。 ## 開始 我將從官方的Samples的順序,看介紹中的每個功能是怎麼實現的。 ## 0、PrismApplicationBase 首先介紹一下這個類,這是Startup,這個類中構建了所有的Prism功能和整體的框架。這個類中大多數的方法都是虛方法,可以過載加入自定義的一些功能,Prism也希望我們如此進行設計。 在整個Prism中,UnityContainer無處不再,它就是一個大的容器,儲存著所有類,在需要的時候Resolver出來。 ![1585470691950](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843731-1366169079.png) 有兩個欄位,ContainerExtension就UnityContainer,當然也可以自定義其他的容器,在文章中都預設為UnityContainer容器,關於容器也給一個官方說明 ![](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183943166-301193197.png) ModuleCatalog是定義了載入Module的方式,模組是Prism的一大優勢,給一張官方說明,意圖勝千言 ![](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183955778-1658154778.png) 所有的一切都是從一個類開始PrismApplicationBase,在這個類中載入了Prism的所有功能。 ![1585471475741](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843755-210210455.png) 看一下最重要的一個方法,正是在這個方法中完成了大部分功能,其主要工作就是將基礎架構模組,RequireTypes,RegionAdapterMappings,RegionBehaviors,注入到相應的容器中。 下面幾個方法感受一下 ![1585471851178](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843757-1844773667.png) ![1585471862192](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843759-1242946447.png) ![1585471872010](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843756-1951097860.png) ![1585471899983](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843758-98582669.png) ![1585471908276](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843758-1036488313.png) 在PrismApplicationBase的子類中看一下 ![1585472041462](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843758-390153955.png) 正如我前面所說,重寫某個方法,先呼叫Base.Method,然後再加入自己功能 對於開發者來說必須重寫的就兩個方法 ![1585472248282](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843759-364891009.png) 建立主窗體和RegisterTypes方法,在第二個方法裡可以加入我們所必須的一些基礎構建,ContainerRegistry其實就是註冊的Unity容器 ![1585472365902](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843765-1574104925.png) 下面讓我們愉快的看例子吧。例子都在Prism-Samples-Wpf-master中一共29個, ## 1、BootstrapperShell ![1585472950515](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843768-826881994.png) ![1585472994216](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843769-1602862462.png) 看著就是建立了一個Bootstraper然後Run了一下,通過容器建立了主窗體,Show了一下。 看一下如何實現的,其實文章都是在Bootstrapper中 ![1585473149592](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843777-171289544.png) 看到這兩個類是不是有一種恍然大悟的感覺,原來Bootstrapper是啥?就是將PrismApplicationBase中的方法全部從Application中抽出來,在這重新實現了一下,難道這就是單一職責原則? 來看一下Run,這些方法太熟悉了吧。 ![1585473531825](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843801-57836246.png) 日誌怎麼用,當然是建立然後記錄了,所有的資訊都放到資源裡,建立的方式有很多種,選擇最簡單的一種new, ![1585473705313](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843809-1804681604.png) ## 2、Regions 這個就是簡單的建立一個Region ![1585473969090](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843870-1213234843.png) 一目瞭然啊,就是在ContentControl中用RegionManager的依賴屬性建立的一個Region。 用經典的三個問題來看看RegionManager,你是誰,你從哪裡來,要到哪裡去。 ![1585474161899](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843836-786618718.png) 哦!小夥子你很張狂啊,很強大。看一眼把關了就可以了。 看一眼知道了有一個RegionName依賴屬性,當這個屬性變化的時候呼叫 ![1585474975966](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843876-967415529.png) IsInDesignMode就是判斷是否在VS的設計模式,呼叫 ![1585475107593](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843848-592938697.png) 哦,還是用了延遲載入,還是用容器建立的,Prism裡幾乎所有的類都是通過容器建立的 ![1585475296411](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843891-1669091631.png) Behavior?WPF裡面的行為就是服務啊,就是先把一個依賴屬性存著,需要的時候盤它。去看看 ![1585475415828](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843875-270788873.png) 很標準的服務。 ![1585475467136](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843960-1756625260.png) 使用了弱引用,很棒的設計,想想也是如此, ![1585475585421](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843904-2017682977.png) ![1585475621940](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843964-1592186379.png) 通過Load事件實現延遲載入,嗯,很棒,在介面載入的時候建立Region。 ![1585475679204](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843914-1477101309.png) ![1585475701564](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843968-1481766810.png) 載入觸發一次就好。很喜歡這個單詞WireUp,纏繞,UnWire, ![1585475877997](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843917-1909300604.png) ![1585476017158](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843986-1186011032.png) 通過名字建立,到RegionAdapterMapping中找到RegionAdapter然後通過Adapter的Initialize建立。 ![1585476694306](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843935-1961386005.png) RegionAdapterMapping就是RegionAdapter的集合 ![1585476749370](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843991-2012153352.png) ![1585478744531](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329184659954-349255275.png) ![1585476852940](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183844136-420304392.png) 先建立Region,然後新增行為 ![1585477085692](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843954-1355413187.png) ![1585476992679](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183844180-1989643537.png) 都有哪些行為呢? ![1585477032237](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843972-1682608544.png) 建立Region工作完成啦。 看看官方文件關於Region ![](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329184032553-1557239280.png) ## 3、CustomRegions 想要自定義一個Regin,那肯定要建立一個RegionAdapter,自定義一個StackPanelRegionAdapter ![1585477844435](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183844208-1493010180.png) ![1585477898475](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183843991-1745022676.png) ![1585477950980](https://img2020.cnblogs.com/blog/1078802/202003/1078802-20200329183844507-270770031.png) 通過剛剛的原始碼解讀這些理解起來好像都不困難了。 ## 總結 通過原始碼探索了下Bootstapper,Region的建立及如何自定義一個RegionAdapter,輕輕揭開了Prism一點點面紗。後面還有很多的功能和想法,歡迎大家和我一起探討