using System.Windows; using AutoMapper; using AutoMapper.Internal; using DMS.Application.Interfaces; using DMS.Application.Services; using DMS.Application.Services.Processors; using DMS.Core.Interfaces; using DMS.Core.Interfaces.Repositories; using DMS.Core.Interfaces.Services; using DMS.Infrastructure.Configuration; using DMS.Infrastructure.Configurations; using DMS.Infrastructure.Data; using DMS.Infrastructure.Interfaces; using DMS.Infrastructure.Interfaces.Services; using DMS.Infrastructure.Repositories; using DMS.Infrastructure.Services; using DMS.WPF.Helper; using DMS.WPF.Interfaces; using DMS.WPF.Logging; using DMS.WPF.Services; using DMS.WPF.ViewModels; using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.Views; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NLog; using NLog.Web; using ILogger = Microsoft.Extensions.Logging.ILogger; using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace DMS.WPF; /// /// Interaction logic for App.xaml /// public partial class App : System.Windows.Application { public IServiceProvider Services { get; } public new static App Current => (App)System.Windows.Application.Current; public IHost Host { get; } private readonly ILogger _logger; public App() { Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { ConfigureServices(services); }) .ConfigureLogging(loggingBuilder => { ConfigureLogging(loggingBuilder); }) .Build(); Services = Host.Services; _logger = Host.Services.GetRequiredService>(); } protected override async void OnStartup(StartupEventArgs e) { base.OnStartup(e); ShutdownMode = ShutdownMode.OnLastWindowClose; ThemeHelper.InitializeTheme(); await Host.StartAsync(); try { Host.Services.GetRequiredService(); // 初始化数据处理链 var dataProcessingService = Host.Services.GetRequiredService(); dataProcessingService.AddProcessor(Host.Services.GetRequiredService()); dataProcessingService.AddProcessor(Host.Services.GetRequiredService()); dataProcessingService.AddProcessor(Host.Services.GetRequiredService()); dataProcessingService.AddProcessor(Host.Services.GetRequiredService()); //dataProcessingService.AddProcessor(Host.Services.GetRequiredService()); } catch (Exception exception) { var notificationService = Host.Services.GetRequiredService(); notificationService.ShowError($"加载数据时发生错误,如果是连接字符串不正确,可以在设置界面更改:{exception.Message}", exception); } var splashWindow = Host.Services.GetRequiredService(); splashWindow.Show(); } protected override async void OnExit(ExitEventArgs e) { _logger.LogInformation("应用程序正在关闭,开始清理资源..."); try { // 获取服务管理器 var opcUaServiceManager = Host.Services.GetService(); var s7ServiceManager = Host.Services.GetService(); var mqttServiceManager = Host.Services.GetService(); // 优雅地关闭OPC UA服务 if (opcUaServiceManager != null) { _logger.LogInformation("正在关闭OPC UA服务..."); opcUaServiceManager.Dispose(); _logger.LogInformation("OPC UA服务已关闭"); } // 优雅地关闭S7服务 if (s7ServiceManager != null) { _logger.LogInformation("正在关闭S7服务..."); s7ServiceManager.Dispose(); _logger.LogInformation("S7服务已关闭"); } // 优雅地关闭MQTT服务 if (mqttServiceManager != null) { _logger.LogInformation("正在关闭MQTT服务..."); mqttServiceManager.Dispose(); _logger.LogInformation("MQTT服务已关闭"); } // 停止后台服务 _logger.LogInformation("正在停止后台服务..."); await Host.StopAsync(); _logger.LogInformation("后台服务已停止"); // 释放Host资源 _logger.LogInformation("正在释放Host资源..."); Host.Dispose(); _logger.LogInformation("Host资源已释放"); // 关闭NLog _logger.LogInformation("正在关闭NLog..."); LogManager.Shutdown(); _logger.LogInformation("NLog已关闭"); } catch (Exception ex) { _logger.LogError(ex, "关闭应用程序时发生错误: {ErrorMessage}", ex.Message); } _logger.LogInformation("应用程序已完全关闭"); base.OnExit(e); } private void ConfigureServices(IServiceCollection services) { // 注册NLogLogger作为Microsoft.Extensions.Logging.ILogger的实现 services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // 注册核心服务 services.AddAutoMapper(cfg => { // 最终解决方案:根据异常信息的建议,设置此标记以忽略重复的Profile加载。 // 注意:此属性位于 Internal() 方法下。 cfg.Internal().AllowAdditiveTypeMapCreation = true; cfg.AddProfile(new DMS.Application.Profiles.MappingProfile()); cfg.AddProfile(new DMS.Infrastructure.Profiles.MappingProfile()); cfg.AddProfile(new DMS.WPF.Profiles.MappingProfile()); }); // 注册数据处理服务和处理器 // services.AddHostedService(); //注册OpcUa相关的服务 services.Configure(options => { }); services.AddSingleton(); services.AddHostedService(); // 注册S7相关的服务 services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddHostedService(); services.AddSingleton(); services.AddHostedService(provider => (DataProcessingService)provider.GetRequiredService()); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // 注册Core中的仓库 services.AddSingleton(); services.AddSingleton(_ => { var appSettings = new AppSettings { Database = { Database = "dms_test" } }; return new SqlSugarDbContext(appSettings); }); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); // 注册App服务 services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // 注册MQTT服务管理器 services.AddSingleton(); services.AddSingleton(); services.AddHostedService(); // 注册WPF中的服务 services.AddSingleton(); services.AddSingleton(provider => new DataServices( provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService() ) ); // 注册视图模型 services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddTransient(provider => new VariableTableViewModel( provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService() )); services.AddSingleton(); services.AddSingleton(provider => new MqttsViewModel( provider.GetRequiredService>(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService() ) ); services.AddSingleton(provider => new LogHistoryViewModel( provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService() ) ); services.AddScoped(); // 注册对话框视图模型 services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); // 注册View视图 services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddScoped(); services.AddScoped(); } private void ConfigureLogging(ILoggingBuilder loggingBuilder) { LogManager.Setup().LoadConfigurationFromFile("Configurations/nlog.config"); loggingBuilder.ClearProviders(); loggingBuilder.SetMinimumLevel(LogLevel.Trace); // loggingBuilder.addn; // 添加NLog作为日志提供者 // 捕获未处理的异常并记录 AppDomain.CurrentDomain.UnhandledException += (sender, args) => { var ex = args.ExceptionObject as Exception; if (ex != null) { // 可以使用一个专用的 Logger 来记录未处理异常 LogManager.GetLogger("UnhandledExceptionLogger") .Fatal($"应用程序发生未处理的异常:{ex}"); } }; // 捕获 Dispatcher 线程上的未处理异常 (UI 线程) this.DispatcherUnhandledException += (sender, args) => { LogManager.GetLogger("DispatcherExceptionLogger") .Fatal($"UI 线程发生未处理的异常:{args.Exception}"); // 标记为已处理,防止应用程序崩溃 (生产环境慎用,可能掩盖问题) // args.Handled = true; }; // 如果您使用 Task (异步方法) 并且没有正确 await,可能会导致异常丢失, // 可以通过以下方式捕获 Task 中的异常。 TaskScheduler.UnobservedTaskException += (sender, args) => { LogManager.GetLogger("UnobservedTaskExceptionLogger") .Fatal($"异步任务发生未观察到的异常:{args.Exception}"); // args.SetObserved(); // 标记为已观察,防止进程终止 }; } }