https://www.bilibili.com/video/BV17arBBgEe5/?vd_source=83527940a14994701f424821abb5dd17

加wx: manyantec了解更多

一、Prism 应用启动核心流程

无论 Prism 7.x、8.x 还是过渡版,BootstrapperShell 的核心启动逻辑本质一致,仅执行载体(如 Bootstrapper 类 / PrismApplication 基类)和语法细节有差异,完整启动顺序如下:

  1. WPF 应用启动:用户运行程序后,WPF 框架触发应用启动流程,跳过普通 WPF 项目的 StartupUri 配置(已删除);
  2. Prism 框架初始化:通过 Bootstrapper 类(7.x/ 过渡版)或 PrismApplication 基类(8.x)启动 Prism 框架核心;
  3. 依赖注入容器创建:Prism 自动创建内置的 DI 容器(7.x 为 Unity,8.x/ 过渡版默认 DryIoc,可切换);
  4. 类型注册执行:调用 RegisterTypes 方法,将应用所需的服务、视图、ViewModel 等注册到 DI 容器中(本示例无自定义注册,方法为空);
  5. Shell 实例创建:调用 CreateShell 方法,从 DI 容器中解析 MainWindow 实例(即 Prism 中的 Shell,应用根容器);
  6. Shell 初始化与显示:调用 InitializeShell 方法,将解析出的 Shell 实例设置为应用主窗口,并执行显示操作;
  7. 应用正常运行:Shell 窗口展示,Prism 应用完成启动,进入正常运行状态。

关键说明:

  • Shell 定位:Prism 中的 Shell 是应用的「根容器窗口」(对应普通 WPF 的 MainWindow),所有子视图、模块最终都会嵌入到 Shell 中;
  • 核心方法职责
    • RegisterTypes:核心是 “制定规则”—— 告诉 DI 容器 “某个抽象接口该用哪个具体实现类”;
    • CreateShell:核心是 “获取实例”—— 从 DI 容器中取出 Shell 实例,容器会自动处理其构造函数依赖;
    • InitializeShell:核心是 “完成初始化”—— 将 Shell 设为应用主窗口并显示,是启动流程的收尾步骤。

二、IoC 与 DI 的核心体现

1. 核心概念(通俗解释)

  • IoC(控制反转):对象的创建权从 “开发者手动 new” 交给 Prism 的 DI 容器管理,比如本示例中 MainWindow 不再通过 new MainWindow() 创建,而是通过 Container.Resolve<MainWindow>() 由容器创建;
  • DI(依赖注入):容器在创建对象时,自动为其注入构造函数中声明的依赖项,比如若 MainWindow 构造函数需要 IRegionManager,容器会自动创建该实例并传入(本示例无自定义依赖,仅体现基础能力)。

2. DI 核心代码(通用逻辑)

csharp

运行

// 1. 注册(可选,本示例无自定义服务):给容器绑定“抽象→实现”的规则
containerRegistry.Register<IMyService, MyServiceImpl>(); 

// 2. 解析(核心):容器创建对象并自动注入依赖
var shell = Container.Resolve<MainWindow>(); 

3. DI 特点

  • 极简场景:仅通过 DI 容器解析 MainWindow,无自定义服务依赖,重点体现 DI 最基础的 “对象创建托管” 能力;
  • 容器抽象化:过渡版、8.x 不再绑定具体容器(如 Unity),而是通过 IContainerRegistry/IContainerProvider 抽象接口操作容器,适配多容器场景。

三、7.x/8.x/ 过渡版 代码差异对比(核心)

维度 Prism 7.x(纯旧版) 过渡版(GitHub 当前代码) Prism 8.x+(纯新版)
核心基类 App 继承 Application,Bootstrapper 继承 UnityBootstrapper App 继承 Application,Bootstrapper 继承 PrismBootstrapper App 继承 PrismApplication(无单独 Bootstrapper)
容器操作接口 IUnityContainer(绑定 Unity 容器) IContainerRegistry/IContainerProvider(抽象接口) IContainerRegistry/IContainerProvider(抽象接口)
RegisterTypes 方法 protected override void RegisterTypes(IUnityContainer container) protected override void RegisterTypes(IContainerRegistry containerRegistry) protected override void RegisterTypes(IContainerRegistry containerRegistry)
启动触发方式 App.OnStartup 中手动调用 new Bootstrapper().Run() App.OnStartup 中手动调用 new Bootstrapper().Run() 基类自动触发(无需手动调用 Run ())
代码文件结构 App.xaml.cs + Bootstrapper.cs 两个核心文件 App.xaml.cs + Bootstrapper.cs 两个核心文件 仅 App.xaml.cs(Bootstrapper 逻辑集成到 App 中)

代码示例对比

1. Prism 7.x(纯旧版)
// Bootstrapper.cs
public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>(); // 基于Unity容器解析
    }
    protected override void RegisterTypes(IUnityContainer container)
    {
        // Unity 专属注册语法
        container.RegisterType<IMyService, MyServiceImpl>();
    }
}

// App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
    new Bootstrapper().Run(); // 手动启动 Bootstrapper
}
2. 过渡版
// Bootstrapper.cs(核心)
namespace BootstrapperShell
{
    // 核心:继承 PrismBootstrapper(7.x→8.x 过渡类,抽象容器)
    class Bootstrapper : PrismBootstrapper
    {
        // 1. 创建 Shell:从抽象容器解析,兼容多容器
        protected override DependencyObject CreateShell()
        {
            return Container.Resolve<MainWindow>(); 
        }

        // 2. 注册类型:抽象注册接口,统一语法
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // 空实现:本示例无自定义服务,如需注册用通用语法
            // containerRegistry.Register<IMyService, MyServiceImpl>();
        }
    }
}

// App.xaml.cs(启动逻辑)
namespace BootstrapperShell
{
    // 仍继承普通 WPF 的 Application,未使用 8.x 的 PrismApplication
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            var bootstrapper = new Bootstrapper();
            bootstrapper.Run(); // 保留 7.x 特性:手动调用 Run()
        }
    }
}
3. Prism 8.x+
// 仅 App.xaml.cs,无单独 Bootstrapper.cs
public partial class App : PrismApplication // 核心:继承 PrismApplication
{
    protected override Window CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<IMyService, MyServiceImpl>();
    }
    // 无需手动调用 Run(),PrismApplication 基类自动执行启动流程
}

四、代码逐行解释

1. Bootstrapper.cs(核心文件)

namespace BootstrapperShell
{
    // 核心:继承 PrismBootstrapper(7.x→8.x 过渡类)
    // 区别于 7.x 的 UnityBootstrapper,抽象容器层,不绑定具体容器实现
    class Bootstrapper : PrismBootstrapper
    {
        /// <summary>
        /// 必须重写:创建应用根容器(Shell)
        /// 返回 DependencyObject 而非 Window:兼容 WPF 所有可视化元素(如 UserControl 作为 Shell)
        /// </summary>
        protected override DependencyObject CreateShell()
        {
            // Container:PrismBootstrapper 内置的 IContainerProvider 类型属性(抽象容器)
            // Resolve<MainWindow>():容器创建 MainWindow 实例,自动注入其构造函数依赖
            return Container.Resolve<MainWindow>();
        }

        /// <summary>
        /// 必须重写:注册服务/视图到 DI 容器
        /// 参数 IContainerRegistry:8.x 抽象注册接口,适配 DryIoc/Unity/Autofac 等所有 Prism 支持的容器
        /// 本示例无自定义服务,因此为空实现
        /// </summary>
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // 扩展示例:如需注册服务,使用通用语法(所有容器都适用)
            // 1. 瞬时注册(每次解析都会创建新实例)
            // containerRegistry.Register<IMyService, MyServiceImpl>();
            // 2. 单例注册(全局仅创建一个实例)
            // containerRegistry.RegisterSingleton<IDataService, DataService>();
            // 3. 导航视图注册(后续导航功能用)
            // containerRegistry.RegisterForNavigation<ViewA>();
        }
    }
}

2. App.xaml.cs(启动入口)

namespace BootstrapperShell
{
    // 过渡版仍继承普通 WPF 的 Application,未使用 8.x 的 PrismApplication
    public partial class App : Application
    {
        /// <summary>
        /// 重写应用启动事件:替代普通 WPF 的 StartupUri 配置
        /// </summary>
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e); // 执行基类默认的启动前置逻辑
            
            // 1. 创建过渡版 Bootstrapper 实例
            var bootstrapper = new Bootstrapper();
            // 2. 手动触发 Prism 初始化流程(7.x 特性,8.x 无需手动调用)
            // Run() 内部会依次执行:创建容器→RegisterTypes→CreateShell→InitializeShell
            bootstrapper.Run();
        }
    }
}

3. MainWindow.xaml/.cs(Shell 容器)

// MainWindow.xaml.cs
namespace BootstrapperShell
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

xml

<!-- MainWindow.xaml -->
<Window x:Class="BootstrapperShell.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Prism Bootstrapper Shell" Height="450" Width="800">
    <!-- Shell 核心定位:仅作为空容器,无业务逻辑 -->
    <!-- 后续学习 Region 后,会在 Shell 中定义区域,动态加载子视图 -->
    <Grid>
        <TextBlock Text="Prism Bootstrapper Shell Example" 
                   HorizontalAlignment="Center" VerticalAlignment="Center"
                   FontSize="20"/>
    </Grid>
</Window>

五、核心总结

  1. 启动逻辑本质:无论 Prism 版本如何,BootstrapperShell 的核心是「用 Prism 接管 WPF 原生启动流程」,通过 DI 容器创建 Shell 窗口,摆脱传统 StartupUri 的绑定,是 Prism 应用的入门基石;
  2. 版本差异核心:7.x 绑定具体容器(如 Unity),8.x 抽象容器并将启动逻辑集成到 PrismApplication,过渡版介于两者之间(抽象容器 + 手动调用 Run ());
  3. DI 核心体现:本示例虽极简,但完整展示了 DI “注册 - 解析” 的核心流程,是后续学习导航、事件聚合、区域管理等 Prism 核心功能的基础;
  4. Shell 设计思想:作为应用根容器,仅承载 UI 布局、无业务逻辑,体现 MVVM“视图仅做容器,逻辑归属于 ViewModel” 的核心思想。
Logo

这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!

更多推荐