惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
罗磊的独立博客
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Recorded Future
Recorded Future
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
Recent Announcements
Recent Announcements
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
V
Visual Studio Blog
F
Fortinet All Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AI
AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security Affairs
S
SegmentFault 最新的问题
C
Cisco Blogs
博客园 - 聂微东
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
量子位
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Security Latest
Security Latest
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog

博客园 - zhaotianff

解决IIS服务器typecho上传附件后无法访问的问题 Visual Studio编译过程中拷贝文件的一些实用小技巧 Jenkins快速入门教程 .NET是什么?为什么要选择.NET? 如何在WPF中实现类似DevOps的自动化流程 一文带你搞懂医疗器械设计开发全生命周期 Windows如何清除本机记录的git用户名和密码 HL7协议详解 医疗行业 GDT 数据格式详解 一文带你搞懂C# 异步编程(async/await)底层原理 如何在C#中使用Chromium headless(无头模式)浏览器 不同.NET版本中的WPF新增功能 如何在WPF中使用 Fluent 主题 Windows平台下的各种原生UI框架介绍 C#如何Hook托管函数 WinDbg 用户层调试进阶教程 Windows编程的一些基础理论 推荐一款优秀的Windows经典文件管理器项目-WinFile Windows如何阻止应用程序联网 如何在WPF中捕获窗口外的事件 如何查看Windows进程的启动来源 Visual Studio 2026新解决方案格式slnx详解 我的微软MVP申请通过了 WPF MVVM实战系列教程(八、Prism DialogService, 对话框服务) WPF MVVM实战系列教程(七、Prism模块化) WPF 性能优化实战指南 WPF MVVM实战系列教程(六、Prism区域导航) WPF MVVM实战系列教程(五、Prism中的MVVM) WPF MVVM实战系列教程(四、Prism中的依赖注入) 微软 IDE 新纪元:Visual Studio 2026 初体验 Windows 7无法安装VMWare Tools的解决办法 WPF MVVM实战系列教程(二、使用Visual Studio 创建Prism项目) WPF MVVM实战系列教程(一、Prism框架介绍)
WPF MVVM实战系列教程(三、创建Bootstrapper/启动器)
zhaotianff · 2025-11-24 · via 博客园 - zhaotianff

WPF的启动过程

因为在前面的文章中,我还没有介绍到WPF程序的启动过程,所以这里简单介绍一下WPF的启动过程

一个正常的WPF启动流程如下:

 1 public partial class App : Application
 2 {
 3     [STAThread]
 4     public static void Main()
 5     {
 6         App app = new App();
 7         app.InitializeComponent();
 8         app.Run();
 9     }
10 
11     public void InitializeComponent()
12     {
13         this.StartupUri = new Uri("MainWindow.xaml",UriKind.Relative);
14     }
15 }

通过设置Application.StartupUri属性来设置启动的窗口。

上述的代码是手动创建窗口时的逻辑,正常情况下,WPF已经帮我们创建好了App.xaml

并且在App.xaml中指定了StartupUri

1 <Application x:Class="WpfApp23.App"
2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4              xmlns:local="clr-namespace:WpfApp23"
5              StartupUri="MainWindow.xaml">
6     <Application.Resources>
7          
8     </Application.Resources>
9 </Application>

我们可以理解为在App类完成WPF的初始化工作。

后续我会详细介绍Application类,这里仅做简单讲解,有疑问的小伙伴,可以访问下面的链接进行学习:

https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/app-development/application-management-overview

什么是Bootstrapper

在Prism中,我们会引入一个新的概念,Bootstrapper。我们也可以称之为启动器。

目前我们可以不用具体掌握它的全部职责,后面会详细介绍到。

现阶段只要了解,在使用Prism框架后,我们需要调整原来Application类的启动逻辑,以便完成一些Prism的初始化工作。

Bootstrapper的职责如下

初始化容器(Container)

Prism 基于依赖注入(DI)设计,Bootstrapper 首先会创建并配置 DI 容器(默认是 Unity/Autofac 等),这是 Prism 实现松耦合、模块化的核心。
它会自动注册 Prism 框架的核心服务(如IRegionManager、IEventAggregator),也支持你注册自定义服务。


配置模块(Module)
负责发现、加载和初始化应用的模块化组件(Module)。你可以通过 Bootstrapper 指定模块的加载方式(按需加载 / 启动时加载)、模块所在程序集等,实现模块化开发的核心逻辑。

创建并配置 Shell(主窗口)
Shell 是 WPF Prism 应用的主窗口,Bootstrapper 会从 DI 容器中解析 Shell 实例,设置为应用的主窗口,并完成窗口的初始化(如关联 RegionManager、绑定视图模型等)。

自动初始化 Prism 的关键服务
IRegionManager:管理视图区域(Region),实现视图的动态加载 / 切换;
IEventAggregator:实现模块间的无耦合通信;
IDialogService:统一管理对话框;
IModuleManager:管理模块的发现、加载、初始化。

这里的初始化是指创建对应的实例,并注入到DI容器中,这个过程是在内部进行的,不需要我们进行干预。

可以参考下面的代码

Prism-8.1.97\src\Wpf\Prism.Wpf\PrismInitializationExtensions.cs

 1 containerRegistry.RegisterSingleton<IDialogService, DialogService>();
 2 containerRegistry.RegisterSingleton<IModuleInitializer, ModuleInitializer>();
 3 containerRegistry.RegisterSingleton<IModuleManager, ModuleManager>();
 4 containerRegistry.RegisterSingleton<RegionAdapterMappings>();
 5 containerRegistry.RegisterSingleton<IRegionManager, RegionManager>();
 6 containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
 7 containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
 8 containerRegistry.RegisterSingleton<IRegionViewRegistry, RegionViewRegistry>();
 9 containerRegistry.RegisterSingleton<IRegionBehaviorFactory, RegionBehaviorFactory>();
10 containerRegistry.Register<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
11 containerRegistry.Register<IRegionNavigationJournal, RegionNavigationJournal>();
12 containerRegistry.Register<IRegionNavigationService, RegionNavigationService>();
13 containerRegistry.Register<IDialogWindow, DialogWindow>(); 


启动应用
完成所有初始化后,Bootstrapper 会显示 Shell 主窗口,正式启动应用程序。

创建Bootstrapper的两种方式

方式1、代码创建Bootstrapper类

创建步骤如下:

1、创建一个Bootstrapper类

 1    public class Bootstrapper : PrismBootstrapper
 2    {
 3        protected override DependencyObject CreateShell()
 4        {
 5            return Container.Resolve<MainWindow>();
 6        }
 7 
 8        protected override void RegisterTypes(IContainerRegistry containerRegistry)
 9        {
10 
11        }
12    }

可以看到Bootstrapper类的构成:

Bootstrapper里重写了CreateShellRegisterTypes两个函数

CreateShell函数的作用是创建程序外壳(主界面)

RegisterTypes的作用是注册类型到容器中(这个后面会详细介绍)

2、移除App.xaml中的StartupUri

image

3、在App.cs中重写Startup函数,并运行Bootstrapper

 1  public partial class App : Application
 2  {
 3      protected override void OnStartup(StartupEventArgs e)
 4      {
 5          base.OnStartup(e);
 6 
 7          var bootstrapper = new Bootstrapper();
 8          bootstrapper.Run();
 9      }
10  }

方式2、XAML创建PrismApplication类

创建步骤如下:

1、在App.xaml中引入命名空间前缀

1    xmlns:prism="http://prismlibrary.com/"

2、将App.xaml的根节点由Application替换为prism:PrismApplication

 1 <prism:PrismApplication x:Class="Prism_CreateBootstrapper_XAML.App"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:local="clr-namespace:Prism_CreateBootstrapper_XAML"
 5              xmlns:prism="http://prismlibrary.com/">
 7     <Application.Resources>
 8          
 9     </Application.Resources>
10 </prism:PrismApplication>

注意:这里依旧需要移除StartupUri

3、将App类修改为继承自PrismApplication并重写函数

 1 public partial class App : PrismApplication
 2 {
 3     protected override Window CreateShell()
 4     {
 5         return Container.Resolve<MainWindow>();
 6     }
 7 
 8     protected override void RegisterTypes(IContainerRegistry containerRegistry)
 9     {
10 
11     }
12 }

App类中的逻辑和前面创建Bootstrapper类是一样的。

在文章的开头部分我介绍了App类的内部逻辑,这种方式就是借助了原来的流程。

这样我们就拥有了一个Prism的启动器。

这两种方式根据个人需求选择其中一种即可。

下一篇文章中,我将会详细介绍Bootstrapper的职责。

示例代码

https://github.com/zhaotianff/WPF-MVVM-Beginner/tree/main/11_Prism_CreateBootstrapper