将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。

This commit is contained in:
QI Mingxuan
2026-04-16 17:31:13 +08:00
parent 6ec4c3ddaa
commit 2bd6e566c3
581 changed files with 74600 additions and 222 deletions
+205
View File
@@ -0,0 +1,205 @@
using Prism.Ioc;
using Prism.Modularity;
using Prism.Unity;
using Serilog;
using System;
using System.Resources;
using System.Windows;
using XP.Common.Configs;
using XP.Common.Localization;
using XP.Common.Localization.Interfaces;
using XP.Common.Logging;
using XP.Common.Logging.Implementations;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Plc.Abstractions;
using XP.Hardware.Plc.Core;
using XP.Hardware.Plc.Services;
using XP.Hardware.PLC.Configs;
using XP.Hardware.PLC.Helpers;
using XP.Hardware.PLC.Services;
using XP.Hardware.PLC.Sentry.Views;
using XP.Hardware.PLC.Views;
namespace XP.Hardware.PLC.Sentry
{
/// <summary>
/// PLC Sentry Monitor 应用程序入口 | PLC Sentry Monitor application entry point
/// </summary>
public partial class App : PrismApplication
{
/// <summary>
/// 应用程序日志实例(带模块上下文)| Application logger instance (with module context)
/// </summary>
private ILogger _logger => Log.ForContext("SourceContext", "XP.Hardware.PLC.Sentry");
/// <summary>
/// 创建主窗口 | Create main shell window
/// </summary>
protected override Window CreateShell()
{
return Container.Resolve<SentryMainWindow>();
}
/// <summary>
/// 注册类型到依赖注入容器 | Register types to DI container
/// </summary>
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// === 注册 XP.Common 基础服务 | Register XP.Common base services ===
containerRegistry.RegisterSingleton<ILoggerService, SerilogLoggerService>();
// === 注册 PLC 核心服务(复用 PLCModule 的注册模式)| Register PLC core services (reuse PLCModule registration pattern) ===
// IPlcClient 瞬态注册,每次 Resolve 创建独立实例,避免并发竞争
// IPlcClient registered as transient, each Resolve creates independent instance to avoid contention
containerRegistry.Register<IPlcClient, S7PlcClient>();
// PlcService 单例(依赖:IPlcClient, ILoggerService, XmlSignalParser
// PlcService singleton (deps: IPlcClient, ILoggerService, XmlSignalParser)
containerRegistry.RegisterSingleton<PlcService>();
// IPlcService 接口映射到同一个 PlcService 单例 | IPlcService interface maps to same PlcService singleton
containerRegistry.Register<IPlcService>(c => c.Resolve<PlcService>());
// 配置加载器(瞬态)| Configuration loader (transient)
containerRegistry.Register<PLC.Configs.ConfigLoader>();
// XML 信号解析器(瞬态)| XML signal parser (transient)
containerRegistry.Register<XmlSignalParser>();
// PLC 写入队列单例(依赖:IPlcClient, ILoggerService| PLC write queue singleton
containerRegistry.RegisterSingleton<PlcWriteQueue>();
// 信号数据交互服务单例(依赖:PlcService, PlcWriteQueue, IPlcClient, ILoggerService
// Signal data service singleton
containerRegistry.RegisterSingleton<ISignalDataService, SignalDataService>();
// === 注册 PLC 已有窗口 | Register existing PLC windows ===
containerRegistry.Register<PlcAddrConfigEditorWindow>();
containerRegistry.Register<PLC.ViewModels.PlcAddrConfigEditorViewModel>();
// === 注册 Sentry 视图和 ViewModel | Register Sentry views and ViewModels ===
containerRegistry.Register<SentryMainWindow>();
containerRegistry.Register<Sentry.ViewModels.SentryMainViewModel>();
}
/// <summary>
/// 配置模块目录 | Configure module catalog
/// </summary>
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// 注册通用模块(提供本地化、Dump 等基础服务)| Register common module (provides localization, dump, etc.)
moduleCatalog.AddModule<XP.Common.Module.CommonModule>();
base.ConfigureModuleCatalog(moduleCatalog);
}
/// <summary>
/// 应用程序启动 | Application startup
/// </summary>
protected override void OnStartup(StartupEventArgs e)
{
// 尽早注册非托管异常捕获 | Register unmanaged exception handler early
AppDomain.CurrentDomain.UnhandledException += (s, args) =>
{
var ex = args.ExceptionObject as Exception;
try
{
_logger.Fatal(ex, "检测到未处理异常(IsTerminating={IsTerminating}| Unhandled exception detected (IsTerminating={IsTerminating})", args.IsTerminating);
Log.CloseAndFlush();
// 向用户显示友好的错误提示 | Show friendly error message to user
MessageBox.Show(
$"应用发生严重错误,即将退出。请查看日志获取详细信息。\n\n{ex?.Message}\n\nA critical error occurred. The application will exit. Please check logs for details.",
"致命错误 | Fatal Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
}
catch { /* 最后的防线 | Last resort */ }
};
// 加载并初始化 Serilog | Load and initialize Serilog
SerilogConfig serilogConfig = XP.Common.Helpers.ConfigLoader.LoadSerilogConfig();
SerilogInitializer.Initialize(serilogConfig);
_logger.Information("PLC Sentry Monitor 启动开始 | PLC Sentry Monitor startup started");
base.OnStartup(e);
}
/// <summary>
/// 应用程序初始化完成 | Application initialization completed
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
// 注册模块级多语言资源到 Fallback Chain | Register module-level localization resources to Fallback Chain
try
{
var localizationService = Container.Resolve<ILocalizationService>();
// 注册 PLC 模块的多语言资源(PlcAddrConfigEditorWindow 等窗口依赖)
// Register PLC module localization resources (required by PlcAddrConfigEditorWindow, etc.)
var plcResourceManager = new ResourceManager(
"XP.Hardware.PLC.Resources.Resources",
typeof(XP.Hardware.PLC.PLCModule).Assembly);
localizationService.RegisterResourceSource("XP.Hardware.PLC", plcResourceManager);
// 注册 Sentry 模块的多语言资源 | Register Sentry module localization resources
var resourceManager = new ResourceManager(
"XP.Hardware.PLC.Sentry.Resources.Resources",
typeof(App).Assembly);
localizationService.RegisterResourceSource("XP.Hardware.PLC.Sentry", resourceManager);
// 初始化 LocalizationHelper | Initialize LocalizationHelper
LocalizationHelper.Initialize(localizationService);
}
catch (Exception ex)
{
_logger.Warning(ex, "Sentry 多语言资源注册失败 | Sentry localization resource registration failed");
}
// 注册写入组件到 PlcService | Register write components to PlcService
var plcService = Container.Resolve<PlcService>();
var writeQueue = Container.Resolve<PlcWriteQueue>();
var signalDataService = Container.Resolve<ISignalDataService>() as SignalDataService;
plcService.RegisterWriteComponents(writeQueue, signalDataService?.DirectWriteChannel);
_logger.Information("PLC Sentry Monitor 初始化完成 | PLC Sentry Monitor initialization completed");
}
/// <summary>
/// 应用程序退出 | Application exit
/// </summary>
protected override void OnExit(ExitEventArgs e)
{
_logger.Information("PLC Sentry Monitor 退出 | PLC Sentry Monitor exiting");
Log.CloseAndFlush();
base.OnExit(e);
}
/// <summary>
/// 捕获 UI 线程未处理异常 | Capture UI thread unhandled exceptions
/// </summary>
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
_logger.Fatal(e.Exception, "应用发生未处理异常 | Application encountered unhandled exception");
try
{
// 尝试刷新日志确保异常信息被持久化 | Flush logs to ensure exception info is persisted
Log.CloseAndFlush();
}
catch { /* 日志刷新失败不影响异常处理 | Log flush failure should not affect exception handling */ }
MessageBox.Show(
$"应用发生未处理异常,请查看日志获取详细信息。\n\n{e.Exception.Message}\n\nApplication encountered an unhandled exception. Please check logs for details.",
"错误 | Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
// 标记异常已处理,防止应用崩溃 | Mark exception as handled to prevent app crash
e.Handled = true;
}
}
}