应用启动基座 `ApplicationBase`
6. 应用启动基座ApplicationBase位置Source/Extensions/H.Extensions.ApplicationBase/ApplicationBase.csApplicationBase继承 WPF 的Application是整个框架的发动机。它负责设置应用关闭模式。注册应用路径服务。初始化全局异常处理。创建ServiceCollection。调用ConfigureServices。构建 IOC 容器。加载多语言。启动时调用Configure。创建主窗口。加载主题。显示启动页。执行登录。显示主窗口。启动定时任务。退出时记录日志并停止任务。自定义应用通常继承它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 应用启动基座详解一、什么是 ApplicationBaseApplicationBase是 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.ShutdownModeShutdownMode.OnMainWindowClose;// 2. 注册应用路径服务AppPaths.Register(this.CreateAppPathServce());// 3. 初始化全局异常处理this.InitExcetion();// 4. 创建服务容器并构建this.InitServiceCollection();}}第二步服务容器初始化protectedvoidInitServiceCollection(){// 创建服务集合ServiceCollectionscnewServiceCollection();// 调用子类的服务注册方法this.ConfigureServices(sc);// 构建 IOC 容器Ioc.Build(sc);// 在显示页面前加载多语言Ioc.GetServiceILoadGlobalizationOptionsService(false)?.Load(outstringmessage);}第三步启动流程protectedoverridevoidOnStartup(StartupEventArgse){// 1. 应用配置this.Configure();// 2. 单例检查确保只有一个实例运行this.OnSingleton(e);base.OnStartup(e);// 3. 创建主窗口Windowwindowthis.CreateMainWindow(e);// 4. 主窗口加载完成后的回调window.Loaded(s,e){varloadsIoc.GetAssignableFromServicesIMainWindowLoadedLoadable().Distinct();foreach(variteminloads)item.Load(outstringmessage);};// 5. 显示启动页this.OnSplashScreen(e);// 6. 执行登录this.OnLogin();// 7. 加载主窗口状态IocIMainWindowSavableService.Instance?.Load(window);// 8. 显示主窗口this.MainWindow.Show();// 9. 记录启动日志this.ILogger?.Info(系统启动);// 10. 启动定时任务IocIScheduledTaskService.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.AddProjectMyProjectService(xx.UseOpenCurrentOnLoadfalse);// 3. 注册模块services.AddHomeProjectHomeViewPresenter();// 4. 注册标签服务services.AddTagProjectTagService(x{x.Tags.Add(newTag(){Name重要,BackgroundBrushes.Red});x.Tags.Add(newTag(){Name普通,BackgroundBrushes.Gray});});// 5. 注册数据库services.AddDbContextBySettingMyDataContext();services.AddSingletonIRepositoryMyEntity,DbContextRepositoryMyDataContext,MyEntity();}protectedoverridevoidConfigure(IApplicationBuilderapp){// 启用应用配置app.UseApplicationOptions();}protectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}}五、ConfigureServices vs Configure5.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、NoticeH.ApplicationBases.Identify身份认证支持登录、权限验证6.3 使用默认组合publicpartialclassApp:DefaultApplicationBase{// 只需实现 CreateMainWindowprotectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}// 可选额外注册服务protectedoverridevoidConfigureServices(IServiceCollectionservices){base.ConfigureServices(services);// 调用基类注册默认服务// 添加自定义服务services.AddSingletonIMyService,MyService();}}6.4 默认服务注册流程// AddApplicationServices 方法会自动注册services.AddDefaultMessages();// 消息服务services.AddDefaultModuleServices();// 模块服务services.AddDefaultThemeServices();// 主题服务services.AddLog4net();// 日志服务七、异常处理机制7.1 三种异常类型protectedvirtualvoidInitExcetion(){// 1. UI 线程异常DispatcherUnhandledExceptionApp_DispatcherUnhandledException;// 2. 非 UI 线程异常AppDomain.CurrentDomain.UnhandledExceptionCurrentDomain_UnhandledException;// 3. 异步任务异常TaskScheduler.UnobservedTaskExceptionTaskScheduler_UnobservedTaskException;}7.2 异常处理示例protectedvoidApp_DispatcherUnhandledException(objectsender,DispatcherUnhandledExceptionEventArgse){// 显示错误消息this.ShowMessage(e.Exception?.ToString(),系统异常);// 标记异常已处理e.Handledtrue;// 记录日志this.ILogger?.Error(系统异常);this.ILogger?.Error(e.Exception);}八、单例检查机制8.1 实现原理privateMutexmutex;publicvirtualvoidOnSingleton(StartupEventArgse){ProcessthisProcProcess.GetCurrentProcess();boolcreatedNew;// 创建命名互斥锁以进程名作为锁名mutexnewMutex(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.AddDbContextBySettingMyDataContext();services.AddSingletonIMyService,MyService();// 3. 最后注册模块services.AddHomeMyHomePresenter();}9.3 扩展方法命名约定前缀含义示例AddXXX注册服务AddSetting(),AddMessage()UseXXX启用配置UseSettingOptions(),UseStyleOptions()TryAddXXX安全注册不覆盖TryAddSingleton()十、总结ApplicationBase 为 WPF 应用提供了一站式启动解决方案生命周期管理从启动到退出的完整流程服务注册通过 IOC 容器管理所有依赖异常处理全局捕获三种异常类型单例保证确保应用只运行一个实例模块化组合通过 ApplicationBases 快速构建应用通过继承 ApplicationBase开发者可以专注于业务逻辑无需关心底层基础设施的搭建。