深剖:MVVM 分層、共享庫與依賴注入完整拆解)
Fluent XAML Theme Editor 源碼架構(gòu)深剖MVVM 分層、共享庫與依賴注入完整拆解【免費下載鏈接】fluent-xaml-theme-editorThe Fluent Design XAML theme editor.項目地址: https://gitcode.com/gh_mirrors/fl/fluent-xaml-theme-editorFluent XAML Theme Editor是微軟開源的 Fluent 設(shè)計系統(tǒng)主題編輯器UWP 應(yīng)用它能幫你可視化調(diào)整 Light/Dark 主題配色、校驗對比度并一鍵導(dǎo)出可直接用于 UWP 的 XAML ResourceDictionary。本文帶你完整拆解它的源碼架構(gòu)MVVM 三層如何分工、FluentEditorShared 共享庫提供了哪些可復(fù)用組件、依賴注入又是如何落地的。項目全景一個解決方案兩個項目整個解決方案 FluentEditor.sln 只包含兩個工程職責(zé)劃分非常干凈項目職責(zé)入口文件FluentEditor應(yīng)用本體UI 頁面、ViewModel、業(yè)務(wù)模型FluentEditor.csprojFluentEditorShared與業(yè)務(wù)無關(guān)的基礎(chǔ)設(shè)施庫已打包為 NuGet 共享FluentEditorShared.csproj這就是它架構(gòu)上最值得學(xué)的一點先把“框架性”的東西抽成共享庫應(yīng)用項目只寫業(yè)務(wù)。下面逐層拆解。MVVM 分層拆解View 層如何與 ViewModel 解耦View 層ViewBase ViewContainer 的動態(tài)裝配View 層的核心不是普通的 XAML 頁面而是一套動態(tài)視圖裝配機制位于FluentEditorShared/ViewCommon/目錄IView.cs視圖接口只要求實現(xiàn)AttachViewModel/DetachViewModel兩個方法。ViewModel 通過弱類型的object傳入讓裝配邏輯與具體類型徹底解耦。ViewBase.cs泛型基類ViewBaseT把 ViewModel 聲明為強類型依賴屬性——弱類型負責(zé)“裝”強類型負責(zé) XAML 里x:Bind的編譯期綁定兩者兼得。ViewContainer.cs容器控件拿到 ViewModel 后通過ViewFactory委托動態(tài)創(chuàng)建對應(yīng) View并自動完成AttachViewModelViewModel 切換時還會先卸載舊視圖再重建。這種“ViewModel 決定渲染哪個 View”的工廠模式讓導(dǎo)航切換頁面的邏輯完全不需要寫在 XAML 里。ViewModel 層導(dǎo)航與狀態(tài)管理導(dǎo)航的 ViewModel 見 OuterNavViewModel.cs用 ObservableList.cs 承載導(dǎo)航項集合變更可通知 UISelectedNavItem屬性變更時觸發(fā)NavigateToItem事件View 層訂閱后驅(qū)動路由——ViewModel 只描述狀態(tài)不接觸任何控件。功能主頁面 ControlPaletteViewModel.cs 是 MVVM 的典型樣本它不持有數(shù)據(jù)而是訂閱 Model 的ActiveColorChanged、ActivePresetChanged事件把顏色變化轉(zhuǎn)成 UI 可用的SolidColorBrush再把屬性面板上的“保存/加載/導(dǎo)出”按鈕事件轉(zhuǎn)化為對 Model 與導(dǎo)出提供者的調(diào)用。Model 層數(shù)據(jù)與文件的唯一真相源Model 集中在FluentEditor/ControlPalette/Model/目錄核心是 ControlPaletteModel.cs它管理 Light/Dark 兩套色板、預(yù)設(shè)Preset列表及當前激活預(yù)設(shè)Preset.cs 負責(zé)預(yù)設(shè)的 JSON 序列化ControlPaletteExportProvider.cs 負責(zé)把整套主題生成可導(dǎo)出的 XAML 數(shù)據(jù)。FluentEditorShared 共享庫三大可復(fù)用組件共享庫對應(yīng)源碼目錄 FluentEditorShared/沉淀了四類與業(yè)務(wù)無關(guān)的能力其中依賴注入與消息總線最值得細看。依賴注入輕量 DependencyContainerDependencyContainer.cs 實現(xiàn)了一個線程安全的最簡容器以字符串 Id 而非類型作鍵注釋里寫得很直白同一類型可以有多個實例AddDependencyT重復(fù)注冊直接拋異常快速暴露配置錯誤GetDependencyT做運行時類型校驗類型不匹配時給出清晰的報錯信息。它的接口定義在 IDependencyContainer.cs調(diào)用方只依賴接口——這就是“面向接口編程”在依賴注入上的最小實踐。消息總線MessageBus 與弱引用監(jiān)聽MessageBus.cs 實現(xiàn)了一個結(jié)構(gòu)體消息的發(fā)布訂閱總線工程細節(jié)相當講究訂閱者通過WeakReference持有見ListenerAdapter避免總線長期存活導(dǎo)致的內(nèi)存泄漏BroadcastMessage先加鎖拷貝訂閱者列表再解鎖廣播防止監(jiān)聽器在回調(diào)中自相移除引發(fā)的并發(fā)問題支持ActionT委托與IMessageBusListener對象兩種訂閱方式PruneListeners可隨時清理失效的弱引用。這是跨模塊、無直接引用通信的經(jīng)典方案適合在 ViewModel 之間解耦通知。其他基礎(chǔ)設(shè)施編輯器組件FluentEditorShared/Editors/下的 ColorEditor.cs、DoubleEditor.cs、BoolEditor.cs、EnumEditor.cs 是通用屬性編輯器配合 FluentEditorSharedResources.xaml 的主題樣式直接復(fù)用對象池ObjectPool.cs 提供IPoolableObject回收機制減少高頻對象的 GC 壓力顏色算法工具ColorPalette.cs 與 PaletteExtraction.cs 負責(zé)色板生成與對比度計算支撐主題編輯器的核心體驗。組裝全景App 啟動時的依賴裝配所有組件的“總裝車間”是 App.xaml.cs 的SetupDependencies流程一目了然創(chuàng)建StringProvider多語言資源與ControlPaletteExportProvider導(dǎo)出能力實例化ControlPaletteModel加載controlPaletteData.json初始化色板數(shù)據(jù)實例化MainNavModel注入導(dǎo)航所需的 paletteModel 與 exportProvider用導(dǎo)航數(shù)據(jù)構(gòu)造OuterNavViewModel掛到OuterNavPage上完成首屏渲染。依賴全部通過構(gòu)造函數(shù)注入傳遞沒有全局單例、沒有 Service Locator 查找——每個類需要什么都寫在簽名上這就是這套代碼里依賴注入最樸素也最實用的形態(tài)。架構(gòu)亮點清單雙項目分層應(yīng)用項目與共享庫邊界清晰共享能力可獨立打包復(fù)用依賴注入雙軌制全局用構(gòu)造注入細粒度擴展點用IDependencyContainer弱引用消息總線跨模塊通信不產(chǎn)生引用泄漏?View 工廠裝配ViewBaseTViewContainer讓 View 隨 ViewModel 動態(tài)切換XAML 零耦合Model 為唯一真相源ViewModel 只做事件轉(zhuǎn)發(fā)與 UI 適配可測試性天然良好。這套架構(gòu)麻雀雖小五臟俱全對想讀懂 MVVM、依賴注入和共享庫設(shè)計的新手來說是一個非常適合通讀的小型樣本工程。【免費下載鏈接】fluent-xaml-theme-editorThe Fluent Design XAML theme editor.項目地址: https://gitcode.com/gh_mirrors/fl/fluent-xaml-theme-editor創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考