WPF Prism9 模块化实战学习笔记1(\.NET10\+DryIoc)
WPF Prism9 模块化实战学习笔记1-框架初体验前言本文基于原生WPF项目一步步手动集成Prism9框架完整实现项目搭建、模块化拆分、MVVM架构、Region区域导航、模块解耦开发全程记录实操步骤适合新手入门学习Prism核心原理。开发环境Visual Studio 2026、.NET 10、Prism 9.0.537、DryIoc依赖注入容器一、创建原生WPF项目为了清晰看到每一步Prism改造细节我们不使用Prism模板先创建无任何框架依赖的原生WPF项目。1.1 新建WPF应用打开Visual Studio选择【创建新项目】搜索关键词WPF选择C# WPF 应用程序。 重要区分WPF 应用程序基于 .NET/.NET Core 现代框架本次使用WPF 应用程序(.NET Framework)传统老旧框架不推荐使用1.2 配置项目信息项目名称命名为PrismDemo自定义存储路径取消勾选【将解决方案和项目放在同一目录中】方便后续拆分多模块、多类库。1.3 选择框架版本统一选择.NET 10.0 长期支持版本保证项目版本统一规避后续NuGet依赖冲突。1.4 初始项目结构说明创建完成后是纯净原生WPF工程仅包含App.xaml、MainWindow.xaml。二、搭建模块化架构创建业务模块Prism最核心的特性就是模块化开发可以将大型项目按业务拆分多个独立模块实现代码解耦、按需加载、团队协作开发。2.1 创建解决方案文件夹在解决方案右键 → 添加 → 新建解决方案文件夹命名为Modules用于统一管理所有业务模块类库。2.2 创建WPF模块类库在Modules文件夹下右键新建项目选择WPF类库命名为ModuleA框架版本同样选择.NET10与主项目保持一致。⚠️ 注意事项模块需要承载XAML视图页面必须选择【WPF类库】不能选择普通控制台类库否则无法创建用户控件。三、规范模块结构引入Prism依赖3.1 清理默认文件删除/重命名模块默认生成的Class1.cs后续替换为Prism模块入口类。3.2 安装Prism核心NuGet包右键ModuleA项目 → 管理NuGet程序包浏览安装Prism.Wpf。作用提供Prism MVVM、模块接口、导航注册、事件聚合器等核心API。3.3 规范模块目录分层遵循标准MVVM架构在ModuleA中创建两个核心文件夹Views存放所有页面、用户控件视图层ViewModels存放视图对应业务逻辑逻辑层3.4 创建视图与ViewModel在Views文件夹添加【用户控件WPF】命名为UserControlA.xaml在ViewModels文件夹添加对应实体类命名为UserControlAViewModel.cs四、编写模块核心代码实现Prism模块化4.1 模块入口类实现IModule接口上文3.1重命名默认类为ModuleA.cs实现Prism的IModule接口完成视图导航注册。usingPrism.Ioc;usingPrism.Modularity;usingPrism.Regions;usingModuleA.Views;namespaceModuleA{publicclassModuleA:IModule{privatereadonlyIRegionManager_regionManager;publicModuleA(IRegionManagerregionManager){_regionManagerregionManager;}// 实现接口自动生成的publicvoidOnInitialized(IContainerProvidercontainerProvider){}// 实现接口自动生成的publicvoidRegisterTypes(IContainerRegistrycontainerRegistry){// 将当前用户控件注册为可导航页面containerRegistry.RegisterForNavigationUserControlA();}}}4.2 编写模块视图页面修改UserControlA.xaml编写测试页面布局UserControlx:ClassModuleA.Views.UserControlAxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:localclr-namespace:ModuleA.Viewsmc:Ignorabledd:DesignHeight450d:DesignWidth800GridBackgroundLightPinkTextBlockText这是模块A的内容HorizontalAlignmentCenterVerticalAlignmentCenterFontSize20//Grid/UserControl4.3 编写ViewModel继承BindableBasePrism封装了BindableBase原生实现属性通知替代传统INotifyPropertyChanged简化MVVM开发。usingPrism.Mvvm;namespaceModuleA.ViewModels{publicclassUserControlAViewModel:BindableBase{}} Prism自动绑定规则视图名UserControlA→ 对应ViewModelUserControlAViewModel一定要满足命名约定Prism才会自动绑定DataContext无需手动配置五、改造主项目引用项目ModuleA接入Prism框架在主项目中引用项目ModuleA点击PrismDemo项目–右键–添加–项目引用5.1 主项目安装容器依赖主项目PrismDemo安装NuGet包Prism.DryIocPrism9不再内置容器需手动指定DryIoc该包已内置Prism.Wpf无需重复安装。5.2 改造App.xaml将原生Application替换为PrismApplication引入Prism命名空间prism:PrismApplicationx:ClassPrismDemo.Appxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:localclr-namespace:PrismDemoxmlns:prismclr-namespace:Prism.DryIoc;assemblyPrism.DryIocprism:PrismApplication.Resources/prism:PrismApplication.Resources/prism:PrismApplication5.3 改造App.xaml.cs重写Prism生命周期usingPrism.DryIoc;usingPrism.Ioc;usingPrism.Modularity;usingPrismDemo.Views;usingModuleA;usingSystem.Windows;namespacePrismDemo{publicpartialclassApp:PrismApplication{// 指定程序启动主窗口protectedoverrideWindowCreateShell(){returnContainer.ResolveMainWindow();}// 全局服务、弹窗、共享视图注册protectedoverridevoidRegisterTypes(IContainerRegistrycontainerRegistry){}// 配置需要加载的业务模块实现模块集成protectedoverridevoidConfigureModuleCatalog(IModuleCatalogmoduleCatalog){moduleCatalog.AddModuleModuleA.ModuleA();}}}5.4 主窗口定义Prism导航区域Region修改MainWindow.xaml定义可承载模块页面的导航区域Windowx:ClassPrismDemo.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:PrismDemoxmlns:prismclr-namespace:Prism.Regions;assemblyPrism.Wpfmc:IgnorabledTitleMainWindowHeight450Width800DockPanelStackPanelOrientationHorizontalDockPanel.DockTopButtonContent加载模块ACommand{Binding LoadModuleACommand}Margin5//StackPanel!-- Prism导航区域名称MainRegion用来承载模块内视图 --ContentControlprism:RegionManager.RegionNameMainRegion//DockPanel/Window5.5 主窗口ViewModel实现导航逻辑新建MainWindowViewModel通过IRegionManager实现页面导航usingPrism.Commands;usingPrism.Mvvm;usingPrism.Regions;namespacePrismDemo.ViewModels{publicclassMainWindowViewModel:BindableBase{privatereadonlyIRegionManager_regionManager;publicDelegateCommandLoadModuleACommand{get;}publicMainWindowViewModel(IRegionManagerregionManager){_regionManagerregionManager;LoadModuleACommandnewDelegateCommand((){// 导航到指定区域、指定视图_regionManager.RequestNavigate(MainRegion,UserControlA);});}}}六、完整项目总体结构、完整项目总体结构解决方案 PrismDemo ├── 【解决方案文件夹】Modules │ └── ModuleA (WPF类库 .NET 10) │ ├── Views │ │ └── UserControlA.xaml │ ├── ViewModels │ │ └── UserControlAViewModel.cs │ └── ModuleA.cs │ └── PrismDemo (WPF主启动程序 .NET 10Shell外壳) ├── App.xaml / App.xaml.cs ├── MainWindow.xaml / MainWindow.xaml.cs └── ViewModels └── MainWindowViewModel.cs七、项目职责与运行流程总结7.1 项目分工PrismDemoShell主外壳程序入口、定义导航区域、统一加载所有模块、全局导航控制ModuleA业务模块独立业务单元自主注册视图与主程序完全解耦7.2 程序运行链路程序启动 →App.CreateShell()创建主窗口ConfigureModuleCatalog.AddModuleModuleA()加载业务模块执行ModuleA.RegisterTypes()注册UserControlA为导航视图界面按钮触发命令 →IRegionManager.RequestNavigate(MainRegion, UserControlA)Prism 在MainRegion区域内实例化并显示模块 A 页面八、运行结果运行结果.gif为什么在这里不显示