当前位置: 首页 > news >正文

应用启动基座 `ApplicationBase`

6. 应用启动基座ApplicationBase

位置:Source/Extensions/H.Extensions.ApplicationBase/ApplicationBase.cs

ApplicationBase继承 WPF 的Application,是整个框架的发动机。它负责:

  1. 设置应用关闭模式。
  2. 注册应用路径服务。
  3. 初始化全局异常处理。
  4. 创建ServiceCollection
  5. 调用ConfigureServices
  6. 构建 IOC 容器。
  7. 加载多语言。
  8. 启动时调用Configure
  9. 创建主窗口。
  10. 加载主题。
  11. 显示启动页。
  12. 执行登录。
  13. 显示主窗口。
  14. 启动定时任务。
  15. 退出时记录日志并停止任务。

自定义应用通常继承它:

publicpartialclassApp:ApplicationBase{protectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}protectedoverridevoidConfigureServices(IServiceCollectionservices){services.AddAdornerDialogMessage();services.AddSnackMessage();services.AddSetting();}protectedoverridevoidConfigure(IApplicationBuilderapp){app.UseStyleOptions();}}

区别:

ConfigureServices:注册能力,例如 services.AddSetting() Configure:启用配置,例如 app.UseStyleOptions()

ApplicationBases目录下的组合项目:

项目作用
H.ApplicationBases.Default默认应用组合,一键注册消息、模块、主题、日志。
H.ApplicationBases.Modules默认模块集合。
H.ApplicationBases.Themes默认主题集合。
H.ApplicationBases.Messages默认消息集合。
H.ApplicationBases.Identify身份认证应用基座。

ApplicationBase 应用启动基座详解

一、什么是 ApplicationBase

ApplicationBase是 WPF-Control 框架的核心启动类,它继承自 WPF 的Application类,封装了应用程序的完整生命周期管理。

一句话概括:ApplicationBase 是应用的"发动机",负责启动、运行和关闭的全过程。

二、核心架构

2.1 继承关系

System.Windows.Application │ ▼ ApplicationBase (H.Extensions.ApplicationBase) │ ▼ DefaultApplicationBase (H.ApplicationBases.Default) │ ▼ YourApp (自定义应用)

2.2 职责矩阵

阶段职责方法
构造阶段设置关闭模式、注册路径服务、初始化异常处理构造函数
服务注册创建 ServiceCollection、调用 ConfigureServicesInitServiceCollection()
启动阶段配置应用、单例检查、加载主题、启动页、登录OnStartup()
运行阶段显示主窗口、启动定时任务OnStartup()
退出阶段停止定时任务、记录日志OnExit()

三、启动流程详解

3.1 完整流程时序图

用户双击应用 │ ▼ ┌──────────────────────────────────────┐ │ 1. 构造函数执行 │ │ - 设置 ShutdownMode │ │ - 注册 AppPath 服务 │ │ - 初始化异常处理 │ │ - 创建 ServiceCollection │ │ - 调用 ConfigureServices │ │ - 构建 IOC 容器 │ │ - 加载多语言 │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 2. OnStartup 执行 │ │ - 调用 Configure │ │ - 单例检查 (OnSingleton) │ │ - 创建主窗口 │ │ - 加载主题 │ │ - 显示启动页 (OnSplashScreen) │ │ - 执行登录 (OnLogin) │ │ - 显示主窗口 │ │ - 启动定时任务 │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 3. 应用运行中 │ │ - 用户操作控件 │ │ - Command/Presenter/Service响应 │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ 4. OnExit 执行 │ │ - 停止定时任务 │ │ - 记录退出日志 │ └──────────────────────────────────────┘

3.2 核心代码剖析

第一步:构造函数初始化
publicabstractpartialclassApplicationBase:Application,IConfigureableApplication,ILoginableApplication{publicApplicationBase(){// 1. 设置关闭模式:主窗口关闭时退出应用this.ShutdownMode=ShutdownMode.OnMainWindowClose;// 2. 注册应用路径服务AppPaths.Register(this.CreateAppPathServce());// 3. 初始化全局异常处理this.InitExcetion();// 4. 创建服务容器并构建this.InitServiceCollection();}}
第二步:服务容器初始化
protectedvoidInitServiceCollection(){// 创建服务集合ServiceCollectionsc=newServiceCollection();// 调用子类的服务注册方法this.ConfigureServices(sc);// 构建 IOC 容器Ioc.Build(sc);// 在显示页面前加载多语言Ioc.GetService<ILoadGlobalizationOptionsService>(false)?.Load(outstringmessage);}
第三步:启动流程
protectedoverridevoidOnStartup(StartupEventArgse){// 1. 应用配置this.Configure();// 2. 单例检查(确保只有一个实例运行)this.OnSingleton(e);base.OnStartup(e);// 3. 创建主窗口Windowwindow=this.CreateMainWindow(e);// 4. 主窗口加载完成后的回调window.Loaded+=(s,e)=>{varloads=Ioc.GetAssignableFromServices<IMainWindowLoadedLoadable>().Distinct();foreach(variteminloads)item.Load(outstringmessage);};// 5. 显示启动页this.OnSplashScreen(e);// 6. 执行登录this.OnLogin();// 7. 加载主窗口状态Ioc<IMainWindowSavableService>.Instance?.Load(window);// 8. 显示主窗口this.MainWindow.Show();// 9. 记录启动日志this.ILogger?.Info("系统启动");// 10. 启动定时任务Ioc<IScheduledTaskService>.Instance?.Start();}

四、自定义应用实现

4.1 最简应用示例

publicpartialclassApp:ApplicationBase{// 必须重写:创建主窗口protectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}// 可选:注册服务protectedoverridevoidConfigureServices(IServiceCollectionservices){services.AddAdornerDialogMessage();// 注册消息服务services.AddSnackMessage();// 注册 Snack 消息services.AddSetting();// 注册设置服务}// 可选:应用配置protectedoverridevoidConfigure(IApplicationBuilderapp){app.UseStyleOptions();// 启用样式配置}}

4.2 完整应用示例

publicpartialclassApp:ApplicationBase{protectedoverridevoidConfigureServices(IServiceCollectionservices){// 1. 注册应用基础服务services.AddApplicationServices();// 2. 注册项目服务services.AddProject<MyProjectService>(x=>x.UseOpenCurrentOnLoad=false);// 3. 注册模块services.AddHome<ProjectHomeViewPresenter>();// 4. 注册标签服务services.AddTag<ProjectTagService>(x=>{x.Tags.Add(newTag(){Name="重要",Background=Brushes.Red});x.Tags.Add(newTag(){Name="普通",Background=Brushes.Gray});});// 5. 注册数据库services.AddDbContextBySetting<MyDataContext>();services.AddSingleton<IRepository<MyEntity>,DbContextRepository<MyDataContext,MyEntity>>();}protectedoverridevoidConfigure(IApplicationBuilderapp){// 启用应用配置app.UseApplicationOptions();}protectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}}

五、ConfigureServices vs Configure

5.1 核心区别

方法时机作用典型操作
ConfigureServicesIOC 容器构建前注册服务和能力services.AddXXX()
ConfigureIOC 容器构建后启用配置和中间件app.UseXXX()

5.2 通俗理解

ConfigureServices:告诉框架"我有哪些能力" ├─ 注册服务:services.AddSetting() ├─ 注册模块:services.AddHome() └─ 注册数据库:services.AddDbContext() Configure:告诉框架"我要启用哪些能力" ├─ 启用设置:app.UseSettingOptions() ├─ 启用样式:app.UseStyleOptions() └─ 启用主题:app.UseThemeOptions()

5.3 执行顺序

1. ConfigureServices(services) │ ├─→ services.AddSetting() ├─→ services.AddMessage() └─→ services.AddHome() │ ▼ 2. Ioc.Build() ←── 构建容器 │ ▼ 3. Configure(app) │ ├─→ app.UseSettingOptions() ├─→ app.UseMessageOptions() └─→ app.UseHomeOptions()

六、ApplicationBases 组合项目

6.1 项目结构

ApplicationBases/ ├── H.ApplicationBases.Default/ # 默认应用组合 ├── H.ApplicationBases.Modules/ # 默认模块集合 ├── H.ApplicationBases.Themes/ # 默认主题集合 ├── H.ApplicationBases.Messages/ # 默认消息集合 └── H.ApplicationBases.Identify/ # 身份认证基座

6.2 各项目作用

项目作用包含内容
H.ApplicationBases.Default一键注册所有基础服务消息、模块、主题、日志
H.ApplicationBases.Modules默认功能模块首页、设置、帮助、关于
H.ApplicationBases.Themes默认主题样式Light、Dark、系统主题
H.ApplicationBases.Messages默认消息组件Dialog、Snack、Notice
H.ApplicationBases.Identify身份认证支持登录、权限验证

6.3 使用默认组合

publicpartialclassApp:DefaultApplicationBase{// 只需实现 CreateMainWindowprotectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}// 可选:额外注册服务protectedoverridevoidConfigureServices(IServiceCollectionservices){base.ConfigureServices(services);// 调用基类注册默认服务// 添加自定义服务services.AddSingleton<IMyService,MyService>();}}

6.4 默认服务注册流程

// AddApplicationServices 方法会自动注册:services.AddDefaultMessages();// 消息服务services.AddDefaultModuleServices();// 模块服务services.AddDefaultThemeServices();// 主题服务services.AddLog4net();// 日志服务

七、异常处理机制

7.1 三种异常类型

protectedvirtualvoidInitExcetion(){// 1. UI 线程异常DispatcherUnhandledException+=App_DispatcherUnhandledException;// 2. 非 UI 线程异常AppDomain.CurrentDomain.UnhandledException+=CurrentDomain_UnhandledException;// 3. 异步任务异常TaskScheduler.UnobservedTaskException+=TaskScheduler_UnobservedTaskException;}

7.2 异常处理示例

protectedvoidApp_DispatcherUnhandledException(objectsender,DispatcherUnhandledExceptionEventArgse){// 显示错误消息this.ShowMessage(e.Exception?.ToString(),"系统异常");// 标记异常已处理e.Handled=true;// 记录日志this.ILogger?.Error("系统异常");this.ILogger?.Error(e.Exception);}

八、单例检查机制

8.1 实现原理

privateMutexmutex;publicvirtualvoidOnSingleton(StartupEventArgse){ProcessthisProc=Process.GetCurrentProcess();boolcreatedNew;// 创建命名互斥锁(以进程名作为锁名)mutex=newMutex(true,thisProc.ProcessName,outcreatedNew);// 如果锁已存在,说明已有实例在运行if(!createdNew){this.ShowMessage("应用程序已在运行中");this.Shutdown();}}

8.2 使用场景

场景说明
资源独占避免多个实例访问同一硬件/文件
状态一致性确保应用状态不被多个实例修改
内存优化避免重复加载资源

九、最佳实践

9.1 应用组织规范

MyApp/ ├── App.xaml.cs # 继承 ApplicationBase ├── MainWindow.xaml # 主窗口 ├── ViewModels/ # 视图模型 ├── Services/ # 自定义服务 ├── Modules/ # 自定义模块 └── Resources/ # 资源文件

9.2 服务注册顺序

protectedoverridevoidConfigureServices(IServiceCollectionservices){// 1. 先注册基础服务services.AddApplicationServices();// 2. 再注册业务服务services.AddDbContextBySetting<MyDataContext>();services.AddSingleton<IMyService,MyService>();// 3. 最后注册模块services.AddHome<MyHomePresenter>();}

9.3 扩展方法命名约定

前缀含义示例
AddXXX注册服务AddSetting(),AddMessage()
UseXXX启用配置UseSettingOptions(),UseStyleOptions()
TryAddXXX安全注册(不覆盖)TryAddSingleton()

十、总结

ApplicationBase 为 WPF 应用提供了一站式启动解决方案

  1. 生命周期管理:从启动到退出的完整流程
  2. 服务注册:通过 IOC 容器管理所有依赖
  3. 异常处理:全局捕获三种异常类型
  4. 单例保证:确保应用只运行一个实例
  5. 模块化组合:通过 ApplicationBases 快速构建应用

通过继承 ApplicationBase,开发者可以专注于业务逻辑,无需关心底层基础设施的搭建。

http://www.jsqmd.com/news/863166/

相关文章:

  • NVIDIA Profile Inspector深度解析:解锁700+显卡隐藏设置的专业指南
  • 罗技鼠标宏压枪脚本:基于Lua的游戏后坐力控制系统架构
  • 国密SM2-SM4-SM3混合加密与滑块行为指纹实战解析
  • Services 服务体系
  • 试制类项目审价深度解析[18号文]
  • 智慧医疗药品胶囊缺陷检测数据集VOC+YOLO格式219张5类别有增强
  • 3个维度重塑开发体验:GitHub中文化插件的效率革命
  • 免费解锁显卡隐藏性能:NVIDIA Profile Inspector终极优化指南
  • HTTP安全头配置陷阱与三层验证修复指南
  • Unity中获取物体尺寸的三种核心方法与适用场景
  • 【信息科学与工程学】信息科学领域工程——第十一篇 数据库基础040 关系代数操作
  • 动态字体反爬破解:服务端代劳模式实战
  • ViGEmBus虚拟游戏控制器驱动:Windows游戏输入的终极解决方案
  • Office Custom UI Editor完全指南:免费打造你的专属Office工作界面
  • 微信抢红包终极指南:Android自动抢红包工具完整教程
  • 关联规则分析(Apriori算法)
  • Unity中XPBD物理引擎实战:解决PBD卡顿与不稳定性
  • Nginx 配置 HSTS 头强制客户端使用 HTTPS 的具体指令是什么
  • G-Helper:华硕笔记本轻量化硬件控制框架技术解析
  • 螺丝螺栓垫圈缺陷检测生锈划痕数据集VOC+YOLO格式1291张6类别有增强
  • GitHub中文化插件:5分钟让GitHub界面全面汉化的技术实现
  • QMCDecode终极指南:5分钟快速掌握QQ音乐加密格式转换技巧
  • C#零拷贝内存扫描:游戏调试的高性能替代方案
  • 炉石佣兵战记自动化脚本:5分钟告别重复操作,释放你的游戏时间
  • 算力狂飙遇瓶颈,电源破局正当时!
  • FreeMove终极指南:如何安全迁移Windows文件夹而不破坏系统
  • Deep:DeepSeek 版的 Aider / Claude Code,开源 CLI 编程工具新选择
  • Unity中让Dictionary在Inspector可编辑的实用方案
  • 重磅盘点!国内空气能十大品牌权威实力|口碑好、评价高的空气能品牌精选 - 匠言榜单
  • 5月22-24日|鑫云科技诚邀您相约第64届高等教育博览会