From bb650e26827a3ddd1142261c4413daa13a4ff919 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Thu, 4 Sep 2025 17:29:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86NlogHelper=EF=BC=8C=E5=92=8CNotificati?= =?UTF-8?q?onHelper=EF=BC=8C=E6=94=B9=E4=B8=BA=E6=9C=8D=E5=8A=A1=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E6=B3=A8=E5=85=A5=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Processors/CheckValueChangedProcessor.cs | 1 - .../Processors/DataProcessingService.cs | 15 +- .../Services/Processors/HistoryProcessor.cs | 1 - .../Processors/UpdateDbVariableProcessor.cs | 12 +- DMS.Core/Helper/NlogHelper.cs | 232 ------------------ .../Repositories/BaseRepository.cs | 29 +-- .../Repositories/DeviceRepository.cs | 9 +- .../Repositories/InitializeRepository.cs | 8 +- .../Repositories/MenuRepository.cs | 15 +- .../Repositories/MqttServerRepository.cs | 9 +- .../Repositories/RepositoryManager.cs | 72 ++++-- .../Repositories/UserRepository.cs | 9 +- .../Repositories/VariableHistoryRepository.cs | 9 +- .../VariableMqttAliasRepository.cs | 9 +- .../Repositories/VariableRepository.cs | 15 +- .../Repositories/VariableTableRepository.cs | 11 +- DMS.WPF/App.xaml.cs | 14 +- DMS.WPF/Services/DataServices.cs | 4 +- DMS.WPF/Services/NavigationService.cs | 6 +- .../NotificationService.cs} | 86 ++++--- DMS.WPF/ViewModels/DeviceDetailViewModel.cs | 28 ++- DMS.WPF/ViewModels/DevicesViewModel.cs | 29 +-- .../Dialogs/ImportExcelDialogViewModel.cs | 8 +- .../Dialogs/ImportOpcUaDialogViewModel.cs | 42 ++-- .../Dialogs/VariableDialogViewModel.cs | 1 - DMS.WPF/ViewModels/MainViewModel.cs | 11 +- .../ViewModels/MqttServerDetailViewModel.cs | 10 +- DMS.WPF/ViewModels/MqttsViewModel.cs | 1 - DMS.WPF/ViewModels/SettingViewModel.cs | 1 - DMS.WPF/ViewModels/SplashViewModel.cs | 4 +- DMS.WPF/ViewModels/VariableTableViewModel.cs | 56 +++-- DMS.WPF/Views/Dialogs/DeviceDialog.xaml.cs | 6 +- .../Views/Dialogs/ImportOpcUaDialog.xaml.cs | 8 +- DMS.WPF/Views/MainView.xaml.cs | 4 +- DMS.WPF/Views/VariableTableView.xaml.cs | 6 +- 35 files changed, 307 insertions(+), 474 deletions(-) delete mode 100644 DMS.Core/Helper/NlogHelper.cs rename DMS.WPF/{Helper/NotificationHelper.cs => Services/NotificationService.cs} (66%) diff --git a/DMS.Application/Services/Processors/CheckValueChangedProcessor.cs b/DMS.Application/Services/Processors/CheckValueChangedProcessor.cs index 7eb8111..c93c0e6 100644 --- a/DMS.Application/Services/Processors/CheckValueChangedProcessor.cs +++ b/DMS.Application/Services/Processors/CheckValueChangedProcessor.cs @@ -1,4 +1,3 @@ -using DMS.Core.Helper; using DMS.Core.Models; using DMS.Application.Interfaces; using DMS.Application.Models; diff --git a/DMS.Application/Services/Processors/DataProcessingService.cs b/DMS.Application/Services/Processors/DataProcessingService.cs index 7039ec4..8ad84f4 100644 --- a/DMS.Application/Services/Processors/DataProcessingService.cs +++ b/DMS.Application/Services/Processors/DataProcessingService.cs @@ -2,7 +2,6 @@ using System.Threading.Channels; using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Application.Models; -using DMS.Core.Helper; using DMS.Core.Interfaces; using DMS.Core.Models; using Microsoft.Extensions.Hosting; @@ -21,16 +20,20 @@ public class DataProcessingService : BackgroundService, IDataProcessingService // 存储数据处理器的链表 private readonly List _processors; + + // 日志记录器 + private readonly ILogger _logger; /// /// 构造函数,注入日志记录器。 /// /// 日志记录器实例。 - public DataProcessingService() + public DataProcessingService(ILogger logger) { // 创建一个无边界的 Channel,允许生产者快速写入而不会被阻塞。 _queue = Channel.CreateUnbounded(); _processors = new List(); + _logger = logger; } /// @@ -66,7 +69,7 @@ public class DataProcessingService : BackgroundService, IDataProcessingService /// 用于通知服务停止的取消令牌。 protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - NlogHelper.Info("数据处理服务已启动。"); + _logger.LogInformation("数据处理服务已启动。"); // 当服务未被请求停止时,持续循环 while (!stoppingToken.IsCancellationRequested) @@ -81,7 +84,7 @@ public class DataProcessingService : BackgroundService, IDataProcessingService { if (context.IsHandled) { - // NlogHelper.Info($"{context.Data.Name}的数据处理已短路,跳过后续处理器。"); + // _logger.LogInformation($"{context.Data.Name}的数据处理已短路,跳过后续处理器。"); break; // 短路,跳过后续处理器 } @@ -94,10 +97,10 @@ public class DataProcessingService : BackgroundService, IDataProcessingService } catch (Exception ex) { - NlogHelper.Error($"处理变量数据时发生错误:{ex.Message}", ex); + _logger.LogError(ex, $"处理变量数据时发生错误:{ex.Message}"); } } - NlogHelper.Info("数据处理服务已停止。"); + _logger.LogInformation("数据处理服务已停止。"); } } \ No newline at end of file diff --git a/DMS.Application/Services/Processors/HistoryProcessor.cs b/DMS.Application/Services/Processors/HistoryProcessor.cs index fdf4c13..8292971 100644 --- a/DMS.Application/Services/Processors/HistoryProcessor.cs +++ b/DMS.Application/Services/Processors/HistoryProcessor.cs @@ -1,6 +1,5 @@ using DMS.Application.Interfaces; using DMS.Application.Models; -using DMS.Core.Helper; using DMS.Core.Models; namespace DMS.Application.Services.Processors; diff --git a/DMS.Application/Services/Processors/UpdateDbVariableProcessor.cs b/DMS.Application/Services/Processors/UpdateDbVariableProcessor.cs index c79b566..df18b74 100644 --- a/DMS.Application/Services/Processors/UpdateDbVariableProcessor.cs +++ b/DMS.Application/Services/Processors/UpdateDbVariableProcessor.cs @@ -1,16 +1,18 @@ using System.Threading.Tasks; using DMS.Application.Interfaces; using DMS.Application.Models; -using DMS.Core.Helper; using DMS.Core.Models; +using Microsoft.Extensions.Logging; namespace DMS.Application.Services.Processors; public class UpdateDbVariableProcessor : IVariableProcessor { + private readonly ILogger _logger; - public UpdateDbVariableProcessor() + public UpdateDbVariableProcessor(ILogger logger) { + _logger = logger; } public async Task ProcessAsync(VariableContext context) @@ -19,18 +21,18 @@ public class UpdateDbVariableProcessor : IVariableProcessor { // 假设 DataServices 有一个方法来更新 Variable // await _dataServices.UpdateVariableAsync(context.Data); - // NlogHelper.Info($"数据库变量 {context.Data.Name} 更新成功,值为: {context.Data.DataValue}"); + // _logger.LogInformation($"数据库变量 {context.Data.Name} 更新成功,值为: {context.Data.DataValue}"); // if (!_dataServices.AllVariables.TryGetValue(context.Data.Id, out Variable oldVariable)) // { - // NlogHelper.Warn($"数据库更新完成修改变量值是否改变时在_dataServices.AllVariables中找不到Id:{context.Data.Id},Name:{context.Data.Name}的变量。"); + // _logger.LogWarning($"数据库更新完成修改变量值是否改变时在_dataServices.AllVariables中找不到Id:{context.Data.Id},Name:{context.Data.Name}的变量。"); // context.IsHandled = true; // } // oldVariable.DataValue = context.Data.DataValue; } catch (Exception ex) { - NlogHelper.Error($"更新数据库变量 {context.Data.Name} 失败: {ex.Message}", ex); + _logger.LogError(ex, $"更新数据库变量 {context.Data.Name} 失败: {ex.Message}"); } } } \ No newline at end of file diff --git a/DMS.Core/Helper/NlogHelper.cs b/DMS.Core/Helper/NlogHelper.cs deleted file mode 100644 index 1e4fe7a..0000000 --- a/DMS.Core/Helper/NlogHelper.cs +++ /dev/null @@ -1,232 +0,0 @@ - -using System; -using System.Collections.Concurrent; -using System.Runtime.CompilerServices; -using System.Threading; -using NLog; - -namespace DMS.Core.Helper; - -/// -/// NLog 日志帮助类,提供简化的日志记录方法,并自动捕获调用者信息。 -/// 新增了日志节流功能,以防止在短时间内产生大量重复的日志(日志风暴)。 -/// -public static class NlogHelper -{ - /// - /// 获取当前类的 NLog 日志实例。 - /// - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - - /// - /// 内部类,用于存储节流日志的状态信息。 - /// - private class ThrottledLogInfo - { - /// - /// 日志在节流时间窗口内的调用次数。 - /// 使用 int 类型,并通过 Interlocked.Increment 进行原子性递增,确保线程安全。 - /// - public int Count; - - /// - /// 用于在节流时间结束后执行操作的计时器。 - /// - public Timer Timer; - - /// - /// 调用日志方法的源文件完整路径。 - /// - public string CallerFilePath; - - /// - /// 调用日志方法的成员或属性名称。 - /// - public string CallerMember; - - /// - /// 调用日志方法的行号。 - /// - public int CallerLineNumber; - - /// - /// 日志级别 (e.g., Info, Error)。 - /// - public LogLevel Level; - - /// - /// 关联的异常对象(如果有)。 - /// - public Exception Exception; - } - - /// - /// 线程安全的字典,用于存储正在被节流的日志。 - /// 键 (string) 是根据日志消息和调用位置生成的唯一标识。 - /// 值 (ThrottledLogInfo) 是该日志的节流状态信息。 - /// - private static readonly ConcurrentDictionary ThrottledLogs = new ConcurrentDictionary(); - - /// - /// 定义节流的时间窗口(单位:秒)。 - /// - private const int ThrottleTimeSeconds = 30; - - /// - /// 内部核心日志记录方法,包含了节流逻辑。 - /// - /// 日志消息内容。 - /// NLog 的日志级别。 - /// 可选的异常对象。 - /// 是否启用节流。 - /// 调用此方法的源文件完整路径。 - /// 调用此方法的成员或属性名称。 - /// 调用此方法的行号。 - private static void LogInternal(string msg, LogLevel level, Exception exception, bool throttle, string callerFilePath, string callerMember, int callerLineNumber) - { - // 如果不启用节流,则直接记录日志并返回。 - if (!throttle) - { - LogWithContext(msg, level, exception, callerFilePath, callerMember, callerLineNumber); - return; - } - - // 使用消息内容和调用位置生成唯一键,以区分不同的日志来源。 - var key = $"{callerFilePath}:{callerLineNumber}:{msg}"; - - // 使用 AddOrUpdate 实现原子操作,确保线程安全。 - // 它会尝试添加一个新的节流日志条目,如果键已存在,则更新现有条目。 - ThrottledLogs.AddOrUpdate( - key, - // --- 添加逻辑 (addValueFactory):当日志第一次被节流时执行 --- - _ => - { - // 1. 首次出现,立即记录一次原始日志。 - LogWithContext(msg, level, exception, callerFilePath, callerMember, callerLineNumber); - - // 2. 创建一个新的节流信息对象。 - var newThrottledLog = new ThrottledLogInfo - { - Count = 1, - CallerFilePath = callerFilePath, - CallerMember = callerMember, - CallerLineNumber = callerLineNumber, - Level = level, - Exception = exception - }; - - // 3. 创建并启动一个一次性计时器。 - newThrottledLog.Timer = new Timer(s => - { - // --- 计时器回调:在指定时间(例如30秒)后触发 --- - // 尝试从字典中移除当前日志条目。 - if (ThrottledLogs.TryRemove(key, out var finishedLog)) - { - // 释放计时器资源。 - finishedLog.Timer.Dispose(); - // 如果在节流期间有后续调用(Count > 1),则记录一条摘要日志。 - if (finishedLog.Count > 1) - { - var summaryMsg = $"日志 '{msg}' 在过去 {ThrottleTimeSeconds} 秒内被调用 {finishedLog.Count} 次。"; - LogWithContext(summaryMsg, finishedLog.Level, finishedLog.Exception, finishedLog.CallerFilePath, finishedLog.CallerMember, finishedLog.CallerLineNumber); - } - } - }, null, ThrottleTimeSeconds * 1000, Timeout.Infinite); // 设置30秒后触发,且不重复。 - - return newThrottledLog; - }, - // --- 更新逻辑 (updateValueFactory):当日志在节流窗口内再次被调用时执行 --- - (_, existingLog) => - { - // 只需将调用次数加一。使用 Interlocked.Increment 保证原子操作,避免多线程下的竞态条件。 - Interlocked.Increment(ref existingLog.Count); - return existingLog; - }); - } - - /// - /// 将日志信息包装在 NLog 的 MappedDiagnosticsLogicalContext 中进行记录。 - /// 这允许在 nlog.config 配置文件中使用 ${mdlc:item=...} 来获取调用者信息。 - /// - private static void LogWithContext(string msg, LogLevel level, Exception exception, string callerFilePath, string callerMember, int callerLineNumber) - { - using (MappedDiagnosticsLogicalContext.SetScoped("CallerFilePath", callerFilePath)) - using (MappedDiagnosticsLogicalContext.SetScoped("CallerLineNumber", callerLineNumber)) - using (MappedDiagnosticsLogicalContext.SetScoped("CallerMember", callerMember)) - { - if (exception != null) - { - Logger.Log(level, exception, msg); - } - else - { - Logger.Log(level, msg); - } - } - } - - /// - /// 记录一个错误级别的日志,支持节流。 - /// - /// 日志消息内容。 - /// 可选:要记录的异常对象。 - /// 是否启用日志节流。如果为 true,则在30秒内对来自同一位置的相同日志消息进行节流处理。 - /// 自动捕获:调用此方法的源文件完整路径。 - /// 自动捕获:调用此方法的成员或属性名称。 - /// 自动捕获:调用此方法的行号。 - public static void Error(string msg, Exception exception = null, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) - { - LogInternal(msg, LogLevel.Error, exception, throttle, callerFilePath, callerMember, callerLineNumber); - } - - /// - /// 记录一个信息级别的日志,支持节流。 - /// - /// 日志消息内容。 - /// 是否启用日志节流。如果为 true,则在30秒内对来自同一位置的相同日志消息进行节流处理。 - /// 自动捕获:调用此方法的源文件完整路径。 - /// 自动捕获:调用此方法的成员或属性名称。 - /// 自动捕获:调用此方法的行号。 - public static void Info(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) - { - LogInternal(msg, LogLevel.Info, null, throttle, callerFilePath, callerMember, callerLineNumber); - } - - /// - /// 记录一个警告级别的日志,支持节流。 - /// - /// 日志消息内容。 - /// 是否启用日志节流。如果为 true,则在30秒内对来自同一位置的相同日志消息进行节流处理。 - /// 自动捕获:调用此方法的源文件完整路径。 - /// 自动捕获:调用此方法的成员或属性名称。 - /// 自动捕获:调用此方法的行号。 - public static void Warn(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) - { - LogInternal(msg, LogLevel.Warn, null, throttle, callerFilePath, callerMember, callerLineNumber); - } - - /// - /// 记录一个跟踪级别的日志,支持节流。 - /// - /// 日志消息内容。 - /// 是否启用日志节流。如果为 true,则在30秒内对来自同一位置的相同日志消息进行节流处理。 - /// 自动捕获:调用此方法的源文件完整路径。 - /// 自动捕获:调用此方法的成员或属性名称。 - /// 自动捕获:调用此方法的行号。 - public static void Trace(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) - { - LogInternal(msg, LogLevel.Trace, null, throttle, callerFilePath, callerMember, callerLineNumber); - } -} diff --git a/DMS.Infrastructure/Repositories/BaseRepository.cs b/DMS.Infrastructure/Repositories/BaseRepository.cs index c0bb8d6..6b66dc2 100644 --- a/DMS.Infrastructure/Repositories/BaseRepository.cs +++ b/DMS.Infrastructure/Repositories/BaseRepository.cs @@ -1,8 +1,8 @@ using System.Diagnostics; using System.Linq.Expressions; -using DMS.Core.Helper; using DMS.Core.Models; using DMS.Infrastructure.Data; +using Microsoft.Extensions.Logging; using SqlSugar; namespace DMS.Infrastructure.Repositories; @@ -15,15 +15,17 @@ public abstract class BaseRepository where TEntity : class, new() { private readonly SqlSugarDbContext _dbContext; - + protected readonly ILogger> _logger; /// /// 初始化 BaseRepository 的新实例。 /// /// SqlSugar 数据库上下文,用于数据库操作。 - protected BaseRepository(SqlSugarDbContext dbContext) + /// 日志记录器实例。 + protected BaseRepository(SqlSugarDbContext dbContext, ILogger> logger) { _dbContext = dbContext; + _logger = logger; } /// @@ -46,7 +48,7 @@ public abstract class BaseRepository var result = await Db.Insertable(entity) .ExecuteReturnEntityAsync(); stopwatch.Stop(); - NlogHelper.Info($"Add {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Add {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -62,7 +64,7 @@ public abstract class BaseRepository var result = await Db.Updateable(entity) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Update {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Update {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -78,7 +80,7 @@ public abstract class BaseRepository var result = await Db.Deleteable(entity) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -94,11 +96,10 @@ public abstract class BaseRepository var entities = await Db.Queryable() .ToListAsync(); stopwatch.Stop(); - NlogHelper.Info($"GetAll {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"GetAll {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return entities; } - /// /// 异步根据主键 ID 获取单个实体。 /// @@ -112,7 +113,7 @@ public abstract class BaseRepository .In(id) .FirstAsync(); stopwatch.Stop(); - NlogHelper.Info($"GetById {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"GetById {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return entity; } @@ -129,7 +130,7 @@ public abstract class BaseRepository .In(ids) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"DeleteByIds {typeof(TEntity).Name}, Count: {ids.Count}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"DeleteByIds {typeof(TEntity).Name}, Count: {ids.Count}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -145,7 +146,7 @@ public abstract class BaseRepository var entity = await Db.Queryable() .FirstAsync(expression); stopwatch.Stop(); - NlogHelper.Info($"GetByCondition {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"GetByCondition {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return entity; } @@ -161,7 +162,7 @@ public abstract class BaseRepository var result = await Db.Queryable() .AnyAsync(expression); stopwatch.Stop(); - NlogHelper.Info($"Exists {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Exists {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -205,7 +206,7 @@ public abstract class BaseRepository var entity = await Db.Queryable().Take(number).ToListAsync(); stopwatch.Stop(); - NlogHelper.Info($"TakeAsync {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"TakeAsync {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return entity; } @@ -215,7 +216,7 @@ public abstract class BaseRepository stopwatch.Start(); var result = await Db.Insertable(entities).ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"AddBatchAsync {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"AddBatchAsync {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result > 0; } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/DeviceRepository.cs b/DMS.Infrastructure/Repositories/DeviceRepository.cs index 810669a..aef8bbd 100644 --- a/DMS.Infrastructure/Repositories/DeviceRepository.cs +++ b/DMS.Infrastructure/Repositories/DeviceRepository.cs @@ -1,10 +1,10 @@ using System.Diagnostics; using AutoMapper; -using DMS.Core.Helper; using DMS.Core.Interfaces.Repositories; using DMS.Core.Models; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -21,8 +21,9 @@ public class DeviceRepository : BaseRepository, IDeviceRepository /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public DeviceRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public DeviceRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -86,7 +87,7 @@ public class DeviceRepository : BaseRepository, IDeviceRepository var result = await Db.Deleteable(new DbDevice() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbDevice)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbDevice)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/InitializeRepository.cs b/DMS.Infrastructure/Repositories/InitializeRepository.cs index 47d2aaf..06d051c 100644 --- a/DMS.Infrastructure/Repositories/InitializeRepository.cs +++ b/DMS.Infrastructure/Repositories/InitializeRepository.cs @@ -4,6 +4,7 @@ using DMS.Core.Models; using DMS.Infrastructure.Configurations; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; +using Microsoft.Extensions.Logging; using SqlSugar; namespace DMS.Infrastructure.Repositories; @@ -16,15 +17,18 @@ public class InitializeRepository : IInitializeRepository { private readonly SqlSugarDbContext _dbContext; private readonly SqlSugarClient _db; + private readonly ILogger _logger; /// - /// 构造函数,注入 SqlSugarDbContext。 + /// 构造函数,注入 SqlSugarDbContext 和 ILogger。 /// /// SqlSugar 数据库上下文,用于数据库操作。 - public InitializeRepository(SqlSugarDbContext dbContext) + /// 日志记录器实例。 + public InitializeRepository(SqlSugarDbContext dbContext, ILogger logger) { _dbContext = dbContext; _db = _dbContext.GetInstance(); + _logger = logger; } /// diff --git a/DMS.Infrastructure/Repositories/MenuRepository.cs b/DMS.Infrastructure/Repositories/MenuRepository.cs index 353edb3..d6b91c4 100644 --- a/DMS.Infrastructure/Repositories/MenuRepository.cs +++ b/DMS.Infrastructure/Repositories/MenuRepository.cs @@ -1,11 +1,11 @@ using System.Diagnostics; using AutoMapper; using DMS.Core.Enums; -using DMS.Core.Helper; using DMS.Core.Interfaces.Repositories; using DMS.Core.Models; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -22,8 +22,9 @@ public class MenuRepository : BaseRepository, IMenuRepository /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public MenuRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public MenuRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -39,7 +40,7 @@ public class MenuRepository : BaseRepository, IMenuRepository var dbMenuTree = await Db.Queryable() .ToTreeAsync(dm => dm.Childrens, dm => dm.ParentId, 0); stopwatch.Stop(); - NlogHelper.Info($"获取菜单树耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"获取菜单树耗时:{stopwatch.ElapsedMilliseconds}ms"); return _mapper.Map>(dbMenuTree); } @@ -101,7 +102,7 @@ public class MenuRepository : BaseRepository, IMenuRepository var result = await Db.Deleteable(new DbMenu { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbMenu)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbMenu)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -123,7 +124,7 @@ public class MenuRepository : BaseRepository, IMenuRepository .Where(m => m.Id == id) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbMenu)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbMenu)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return delConut; } @@ -147,7 +148,7 @@ public class MenuRepository : BaseRepository, IMenuRepository .Where(m => m.Id == menu.Id) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbMenu)},TargetId={targetId},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbMenu)},TargetId={targetId},耗时:{stopwatch.ElapsedMilliseconds}ms"); return delConut; } diff --git a/DMS.Infrastructure/Repositories/MqttServerRepository.cs b/DMS.Infrastructure/Repositories/MqttServerRepository.cs index c73c085..f6fa4ef 100644 --- a/DMS.Infrastructure/Repositories/MqttServerRepository.cs +++ b/DMS.Infrastructure/Repositories/MqttServerRepository.cs @@ -1,10 +1,10 @@ using System.Diagnostics; using AutoMapper; -using DMS.Core.Helper; using DMS.Core.Interfaces.Repositories; using DMS.Core.Models; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -21,8 +21,9 @@ public class MqttServerRepository : BaseRepository, IMqttServerRep /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public MqttServerRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public MqttServerRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -85,7 +86,7 @@ public class MqttServerRepository : BaseRepository, IMqttServerRep var result = await Db.Deleteable(new DbMqttServer() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbMqttServer)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbMqttServer)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/RepositoryManager.cs b/DMS.Infrastructure/Repositories/RepositoryManager.cs index fed073d..0028f50 100644 --- a/DMS.Infrastructure/Repositories/RepositoryManager.cs +++ b/DMS.Infrastructure/Repositories/RepositoryManager.cs @@ -12,32 +12,44 @@ namespace DMS.Infrastructure.Repositories; /// public class RepositoryManager : IRepositoryManager { - private readonly SqlSugarClient _db; - private readonly IMapper _mapper; private readonly SqlSugarDbContext _dbContext; + private readonly SqlSugarClient _db; /// - /// 构造函数,注入 AutoMapper 和 SqlSugarDbContext。 - /// 在此初始化所有具体的仓储实例。 + /// 构造函数,注入所有仓储实例。 /// - /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 - /// SqlSugar 数据库上下文,用于数据库操作。 - public RepositoryManager(IMapper mapper, SqlSugarDbContext dbContext) + /// 初始化仓储实例。 + /// 设备仓储实例。 + /// 变量表仓储实例。 + /// 变量仓储实例。 + /// MQTT服务器仓储实例。 + /// 变量MQTT别名仓储实例。 + /// 菜单仓储实例。 + /// 变量历史仓储实例。 + /// 用户仓储实例。 + public RepositoryManager( SqlSugarDbContext dbContext, + IInitializeRepository initializeRepository, + IDeviceRepository devices, + IVariableTableRepository variableTables, + IVariableRepository variables, + IMqttServerRepository mqttServers, + IVariableMqttAliasRepository variableMqttAliases, + IMenuRepository menus, + IVariableHistoryRepository variableHistories, + IUserRepository users) { - _mapper = mapper; _dbContext = dbContext; - _db = dbContext.GetInstance(); - - // 初始化各个仓储实例 - InitializeRepository=new InitializeRepository(dbContext); - Devices = new DeviceRepository(mapper, dbContext); - VariableTables = new VariableTableRepository(mapper, dbContext); - Variables = new VariableRepository(mapper, dbContext); - MqttServers = new MqttServerRepository(mapper, dbContext); - VariableMqttAliases = new VariableMqttAliasRepository(mapper, dbContext); - Menus = new MenuRepository(mapper, dbContext); - VariableHistories = new VariableHistoryRepository(mapper, dbContext); - Users = new UserRepository(mapper, dbContext); + InitializeRepository = initializeRepository; + Devices = devices; + VariableTables = variableTables; + Variables = variables; + MqttServers = mqttServers; + VariableMqttAliases = variableMqttAliases; + Menus = menus; + VariableHistories = variableHistories; + Users = users; + + _db = dbContext.GetInstance(); } /// @@ -45,7 +57,7 @@ public class RepositoryManager : IRepositoryManager /// public void Dispose() { - _db.Close(); + _db?.Close(); } /// @@ -89,17 +101,29 @@ public class RepositoryManager : IRepositoryManager /// 异步开始数据库事务。 /// /// 表示异步操作的任务。 - public async Task BeginTranAsync() => await _db.BeginTranAsync(); + public async Task BeginTranAsync() + { + if (_db != null) + await _db.BeginTranAsync(); + } /// /// 异步提交数据库事务。 /// /// 表示异步操作的任务。 - public async Task CommitAsync() => await _db.CommitTranAsync(); + public async Task CommitAsync() + { + if (_db != null) + await _db.CommitTranAsync(); + } /// /// 异步回滚数据库事务。 /// /// 表示异步操作的任务。 - public async Task RollbackAsync() => await _db.RollbackTranAsync(); + public async Task RollbackAsync() + { + if (_db != null) + await _db.RollbackTranAsync(); + } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/UserRepository.cs b/DMS.Infrastructure/Repositories/UserRepository.cs index dd85998..7ef1888 100644 --- a/DMS.Infrastructure/Repositories/UserRepository.cs +++ b/DMS.Infrastructure/Repositories/UserRepository.cs @@ -7,7 +7,7 @@ using DMS.Infrastructure.Entities; using AutoMapper; -using DMS.Core.Helper; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -24,8 +24,9 @@ public class UserRepository : BaseRepository, IUserRepository /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public UserRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public UserRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -88,7 +89,7 @@ public class UserRepository : BaseRepository, IUserRepository var result = await Db.Deleteable(new DbUser() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbUser)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbUser)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/VariableHistoryRepository.cs b/DMS.Infrastructure/Repositories/VariableHistoryRepository.cs index c113089..ea52cb4 100644 --- a/DMS.Infrastructure/Repositories/VariableHistoryRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableHistoryRepository.cs @@ -6,7 +6,7 @@ using DMS.Infrastructure.Entities; using AutoMapper; -using DMS.Core.Helper; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -23,8 +23,9 @@ public class VariableHistoryRepository : BaseRepository, IVar /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public VariableHistoryRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public VariableHistoryRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -87,7 +88,7 @@ public class VariableHistoryRepository : BaseRepository, IVar var result = await Db.Deleteable(new DbVariableHistory() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbVariableHistory)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbVariableHistory)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs index 30bf982..3e12b13 100644 --- a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs @@ -5,7 +5,7 @@ using DMS.Infrastructure.Entities; using AutoMapper; -using DMS.Core.Helper; +using Microsoft.Extensions.Logging; using DMS.Core.Models; namespace DMS.Infrastructure.Repositories; @@ -23,8 +23,9 @@ public class VariableMqttAliasRepository : BaseRepository, /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public VariableMqttAliasRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public VariableMqttAliasRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -87,7 +88,7 @@ public class VariableMqttAliasRepository : BaseRepository, var result = await Db.Deleteable(new DbVariableMqttAlias() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbVariableMqttAlias)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbVariableMqttAlias)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/VariableRepository.cs b/DMS.Infrastructure/Repositories/VariableRepository.cs index 73d492a..fe782ad 100644 --- a/DMS.Infrastructure/Repositories/VariableRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableRepository.cs @@ -1,10 +1,10 @@ using System.Diagnostics; using AutoMapper; -using DMS.Core.Helper; using DMS.Core.Interfaces.Repositories; using DMS.Core.Models; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -21,8 +21,9 @@ public class VariableRepository : BaseRepository, IVariableRepositor /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public VariableRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public VariableRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -98,13 +99,13 @@ public class VariableRepository : BaseRepository, IVariableRepositor } await Db.CommitTranAsync(); - //NlogHelper.Info($"成功为 {variableMqttList.Count()} 个变量请求添加/更新了MQTT服务器关联,实际影响 {affectedCount} 个。"); + //_logger.LogInformation($"成功为 {variableMqttList.Count()} 个变量请求添加/更新了MQTT服务器关联,实际影响 {affectedCount} 个。"); return affectedCount; } catch (Exception ex) { await Db.RollbackTranAsync(); - //NlogHelper.Error($"为变量添加MQTT服务器关联时发生错误: {ex.Message}", ex); + //_logger.LogError(ex, $"为变量添加MQTT服务器关联时发生错误: {ex.Message}"); // 根据需要,可以向上层抛出异常 throw; } @@ -169,7 +170,7 @@ public class VariableRepository : BaseRepository, IVariableRepositor var result = await Db.Deleteable(new DbVariable() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbVariable)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbVariable)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -186,7 +187,7 @@ public class VariableRepository : BaseRepository, IVariableRepositor .In(ids) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbVariable)},Count={ids.Count},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbVariable)},Count={ids.Count},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } diff --git a/DMS.Infrastructure/Repositories/VariableTableRepository.cs b/DMS.Infrastructure/Repositories/VariableTableRepository.cs index b2724e0..4dfeb6e 100644 --- a/DMS.Infrastructure/Repositories/VariableTableRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableTableRepository.cs @@ -6,7 +6,7 @@ using DMS.Infrastructure.Entities; using AutoMapper; -using DMS.Core.Helper; +using Microsoft.Extensions.Logging; namespace DMS.Infrastructure.Repositories; @@ -23,8 +23,9 @@ public class VariableTableRepository : BaseRepository, IVariabl /// /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 - public VariableTableRepository(IMapper mapper, SqlSugarDbContext dbContext) - : base(dbContext) + /// 日志记录器实例。 + public VariableTableRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + : base(dbContext, logger) { _mapper = mapper; } @@ -87,7 +88,7 @@ public class VariableTableRepository : BaseRepository, IVariabl var result = await Db.Deleteable(new DbVariableTable() { Id = id }) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(DbVariableTable)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete {typeof(DbVariableTable)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -122,7 +123,7 @@ public class VariableTableRepository : BaseRepository, IVariabl .Where(it => it.DeviceId == deviceId) .ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete VariableTable by DeviceId={deviceId}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); + _logger.LogInformation($"Delete VariableTable by DeviceId={deviceId}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } } \ No newline at end of file diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index 69bd256..e237c24 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -6,7 +6,6 @@ using DMS.Application.Services.Processors; using DMS.Core.Interfaces; using DMS.Core.Interfaces.Repositories; using DMS.Core.Interfaces.Services; -using DMS.Helper; using DMS.Infrastructure.Configurations; using DMS.Infrastructure.Data; using DMS.Infrastructure.Interfaces.Services; @@ -76,7 +75,8 @@ public partial class App : System.Windows.Application } catch (Exception exception) { - NotificationHelper.ShowError("加载数据时发生错误,如果是连接字符串不正确,可以在设置界面更改:{exception.Message}", exception); + var notificationService = Host.Services.GetRequiredService(); + notificationService.ShowError($"加载数据时发生错误,如果是连接字符串不正确,可以在设置界面更改:{exception.Message}", exception); } var splashWindow = Host.Services.GetRequiredService(); @@ -106,10 +106,10 @@ public partial class App : System.Windows.Application private void ConfigureServices(IServiceCollection services) { // 注册NLogLogger作为Microsoft.Extensions.Logging.ILogger的实现 - services.AddSingleton(); services.AddSingleton(); // services.AddSingleton(); + services.AddSingleton(); // services.AddHostedService(); // services.AddHostedService(); // services.AddHostedService(); @@ -148,6 +148,14 @@ public partial class App : System.Windows.Application }); services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/DMS.WPF/Services/DataServices.cs b/DMS.WPF/Services/DataServices.cs index f33c5be..7cea523 100644 --- a/DMS.WPF/Services/DataServices.cs +++ b/DMS.WPF/Services/DataServices.cs @@ -59,10 +59,10 @@ public partial class DataServices : ObservableObject /// /// DataServices类的构造函数。 - /// 注入ILogger,并初始化各个数据仓库。 + /// 初始化各个数据仓库。 /// /// AutoMapper 实例。 - /// + /// 数据服务中心实例。 public DataServices(IMapper mapper, IDataCenterService dataCenterService) { _mapper = mapper; diff --git a/DMS.WPF/Services/NavigationService.cs b/DMS.WPF/Services/NavigationService.cs index 6304a19..9201cce 100644 --- a/DMS.WPF/Services/NavigationService.cs +++ b/DMS.WPF/Services/NavigationService.cs @@ -1,6 +1,5 @@ // 文件: DMS.WPF/Services/NavigationService.cs -using DMS.Helper; using DMS.ViewModels; using DMS.WPF.ViewModels; using DMS.WPF.ViewModels.Items; @@ -11,6 +10,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; using DMS.WPF.Interfaces; +using DMS.WPF.Services; namespace DMS.WPF.Services; @@ -43,8 +43,8 @@ public class NavigationService : INavigationService var viewModel = GetViewModelByKey(menu.TargetViewKey); if (viewModel == null) { - - NotificationHelper.ShowError($"切换界面失败,没有找到界面:{menu.TargetViewKey}"); + var notificationService = App.Current.Services.GetRequiredService(); + notificationService.ShowError($"切换界面失败,没有找到界面:{menu.TargetViewKey}"); return; } diff --git a/DMS.WPF/Helper/NotificationHelper.cs b/DMS.WPF/Services/NotificationService.cs similarity index 66% rename from DMS.WPF/Helper/NotificationHelper.cs rename to DMS.WPF/Services/NotificationService.cs index c43ebb5..5342462 100644 --- a/DMS.WPF/Helper/NotificationHelper.cs +++ b/DMS.WPF/Services/NotificationService.cs @@ -1,21 +1,22 @@ - using System; using System.Collections.Concurrent; using System.Runtime.CompilerServices; using System.Threading; using CommunityToolkit.Mvvm.Messaging; using DMS.Core.Enums; -using DMS.Core.Helper; using DMS.Message; +using Microsoft.Extensions.Logging; -namespace DMS.Helper; +namespace DMS.WPF.Services; /// -/// 通知帮助类,用于显示各种类型的通知消息,并集成日志记录功能。 +/// 通知服务类,用于显示各种类型的通知消息,并集成日志记录功能。 /// 新增了通知节流功能,以防止在短时间内向用户发送大量重复的通知。 /// -public static class NotificationHelper +public class NotificationService { + private readonly ILogger _logger; + /// /// 内部类,用于存储节流通知的状态信息。 /// @@ -26,22 +27,38 @@ public static class NotificationHelper public NotificationType NotificationType; } - private static readonly ConcurrentDictionary ThrottledNotifications = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _throttledNotifications = new ConcurrentDictionary(); private const int ThrottleTimeSeconds = 30; + public NotificationService(ILogger logger) + { + _logger = logger; + } + /// /// 内部核心通知发送方法,包含了节流逻辑。 /// - private static void SendNotificationInternal(string msg, NotificationType notificationType, bool throttle, Exception exception, string callerFilePath, string callerMember, int callerLineNumber) + private void SendNotificationInternal(string msg, NotificationType notificationType, bool throttle, Exception exception, string callerFilePath, string callerMember, int callerLineNumber) { - // 根据通知类型决定日志级别,并使用 NlogHelper 记录日志(利用其自身的节流逻辑) + // 根据通知类型决定日志级别,并使用 ILogger 记录日志 if (notificationType == NotificationType.Error) { - NlogHelper.Error(msg, exception, throttle, callerFilePath, callerMember, callerLineNumber); + _logger.LogError(exception, $"[{callerFilePath}:{callerMember}:{callerLineNumber}] {msg}"); } else { - NlogHelper.Info(msg, throttle, callerFilePath, callerMember, callerLineNumber); + switch (notificationType) + { + case NotificationType.Info: + _logger.LogInformation($"[{callerFilePath}:{callerMember}:{callerLineNumber}] {msg}"); + break; + case NotificationType.Success: + _logger.LogInformation($"[{callerFilePath}:{callerMember}:{callerLineNumber}] {msg}"); + break; + case NotificationType.Warning: + _logger.LogWarning($"[{callerFilePath}:{callerMember}:{callerLineNumber}] {msg}"); + break; + } } // 如果不启用通知节流,则直接发送通知并返回。 @@ -53,7 +70,7 @@ public static class NotificationHelper var key = $"{callerFilePath}:{callerLineNumber}:{msg}"; - ThrottledNotifications.AddOrUpdate( + _throttledNotifications.AddOrUpdate( key, // --- 添加逻辑:当通知第一次被节流时执行 --- _ => @@ -71,7 +88,7 @@ public static class NotificationHelper // 3. 创建并启动计时器。 newThrottledNotification.Timer = new Timer(s => { - if (ThrottledNotifications.TryRemove(key, out var finishedNotification)) + if (_throttledNotifications.TryRemove(key, out var finishedNotification)) { finishedNotification.Timer.Dispose(); if (finishedNotification.Count > 1) @@ -100,9 +117,9 @@ public static class NotificationHelper /// 是否启用通知节流。 /// 自动捕获:调用此方法的源文件完整路径。 /// 自动捕获:调用此方法的行号。 - public static void ShowMessage(string msg, NotificationType notificationType = NotificationType.Info, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerLineNumber] int callerLineNumber = 0) + public void ShowMessage(string msg, NotificationType notificationType = NotificationType.Info, bool throttle = true, + [CallerFilePath] string callerFilePath = "", + [CallerLineNumber] int callerLineNumber = 0) { SendNotificationInternal(msg, notificationType, throttle, null, callerFilePath, "", callerLineNumber); } @@ -116,10 +133,10 @@ public static class NotificationHelper /// 自动捕获:调用此方法的源文件完整路径。 /// 自动捕获:调用此方法的成员或属性名称。 /// 自动捕获:调用此方法的行号。 - public static void ShowError(string msg, Exception exception = null, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) + public void ShowError(string msg, Exception exception = null, bool throttle = true, + [CallerFilePath] string callerFilePath = "", + [CallerMemberName] string callerMember = "", + [CallerLineNumber] int callerLineNumber = 0) { SendNotificationInternal(msg, NotificationType.Error, throttle, exception, callerFilePath, callerMember, callerLineNumber); } @@ -132,10 +149,10 @@ public static class NotificationHelper /// 自动捕获:调用此方法的源文件完整路径。 /// 自动捕获:调用此方法的成员或属性名称。 /// 自动捕获:调用此方法的行号。 - public static void ShowSuccess(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) + public void ShowSuccess(string msg, bool throttle = true, + [CallerFilePath] string callerFilePath = "", + [CallerMemberName] string callerMember = "", + [CallerLineNumber] int callerLineNumber = 0) { SendNotificationInternal(msg, NotificationType.Success, throttle, null, callerFilePath, callerMember, callerLineNumber); } @@ -148,26 +165,27 @@ public static class NotificationHelper /// 自动捕获:调用此方法的源文件完整路径。 /// 自动捕获:调用此方法的成员或属性名称。 /// 自动捕获:调用此方法的行号。 - public static void ShowInfo(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) + public void ShowInfo(string msg, bool throttle = true, + [CallerFilePath] string callerFilePath = "", + [CallerMemberName] string callerMember = "", + [CallerLineNumber] int callerLineNumber = 0) { SendNotificationInternal(msg, NotificationType.Info, throttle, null, callerFilePath, callerMember, callerLineNumber); } + /// - /// 显示一个信息通知消息,并记录信息日志。支持节流。 + /// 显示一个警告通知消息,并记录警告日志。支持节流。 /// - /// 信息消息内容。 + /// 警告消息内容。 /// 是否启用通知和日志节流。 /// 自动捕获:调用此方法的源文件完整路径。 /// 自动捕获:调用此方法的成员或属性名称。 /// 自动捕获:调用此方法的行号。 - public static void ShowWarn(string msg, bool throttle = true, - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string callerMember = "", - [CallerLineNumber] int callerLineNumber = 0) + public void ShowWarn(string msg, bool throttle = true, + [CallerFilePath] string callerFilePath = "", + [CallerMemberName] string callerMember = "", + [CallerLineNumber] int callerLineNumber = 0) { SendNotificationInternal(msg, NotificationType.Warning, throttle, null, callerFilePath, callerMember, callerLineNumber); } -} +} \ No newline at end of file diff --git a/DMS.WPF/ViewModels/DeviceDetailViewModel.cs b/DMS.WPF/ViewModels/DeviceDetailViewModel.cs index ceed95e..d305c9f 100644 --- a/DMS.WPF/ViewModels/DeviceDetailViewModel.cs +++ b/DMS.WPF/ViewModels/DeviceDetailViewModel.cs @@ -5,7 +5,6 @@ using Dm; using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Core.Enums; -using DMS.Helper; using DMS.WPF.Services; using DMS.Services; using DMS.WPF.Interfaces; @@ -28,12 +27,15 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable [ObservableProperty] private VariableTableItemViewModel _selectedVariableTable; + private readonly NotificationService _notificationService; + public DeviceDetailViewModel(IMapper mapper, IDialogService dialogService, INavigationService navigationService, - DataServices dataServices) + DataServices dataServices, NotificationService notificationService) { _mapper = mapper; _dialogService = dialogService; _navigationService = navigationService; + _notificationService = notificationService; DataServices = dataServices; } @@ -65,17 +67,17 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable if (await DataServices.AddVariableTable(_mapper.Map(variableTableItemViewModel), tableMenu, true)) { - NotificationHelper.ShowSuccess($"添加变量表成功:{variableTableItemViewModel.Name}"); + _notificationService.ShowSuccess($"添加变量表成功:{variableTableItemViewModel.Name}"); } else { - NotificationHelper.ShowError($"添加变量表失败:{variableTableItemViewModel.Name}!!"); + _notificationService.ShowError($"添加变量表失败:{variableTableItemViewModel.Name}!!"); } } catch (Exception ex) { - NotificationHelper.ShowError($"添加变量表时发生错误: {ex.Message}", ex); + _notificationService.ShowError($"添加变量表时发生错误: {ex.Message}", ex); } } @@ -86,7 +88,7 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable { if (SelectedVariableTable == null) { - NotificationHelper.ShowError("你没有选择任何变量表,请选择变量表后再点击编辑变量表"); + _notificationService.ShowError("你没有选择任何变量表,请选择变量表后再点击编辑变量表"); return; } @@ -104,16 +106,16 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable if (await DataServices.UpdateVariableTable(variableTable)) { - NotificationHelper.ShowSuccess($"编辑变量表成功:{variableTable.Name}"); + _notificationService.ShowSuccess($"编辑变量表成功:{variableTable.Name}"); } else { - NotificationHelper.ShowError($"编辑变量表失败:{variableTable.Name}"); + _notificationService.ShowError($"编辑变量表失败:{variableTable.Name}"); } } catch (Exception e) { - NotificationHelper.ShowError($"编辑变量表的过程中发生错误:{e.Message}", e); + _notificationService.ShowError($"编辑变量表的过程中发生错误:{e.Message}", e); } } @@ -124,7 +126,7 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable { if (SelectedVariableTable == null) { - NotificationHelper.ShowError("你没有选择任何变量表,请选择变量表后再点击删除变量表"); + _notificationService.ShowError("你没有选择任何变量表,请选择变量表后再点击删除变量表"); return; } @@ -135,17 +137,17 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable var tableName = SelectedVariableTable.Name; if (await DataServices.DeleteVariableTable(SelectedVariableTable,true)) { - NotificationHelper.ShowSuccess($"变量表:{tableName},删除成功。"); + _notificationService.ShowSuccess($"变量表:{tableName},删除成功。"); } else { - NotificationHelper.ShowError($"变量表:{tableName},删除失败!!!"); + _notificationService.ShowError($"变量表:{tableName},删除失败!!!"); } } } catch (Exception e) { - NotificationHelper.ShowError($"删除变量表的过程中发生错误:{e.Message}", e); + _notificationService.ShowError($"删除变量表的过程中发生错误:{e.Message}", e); } } diff --git a/DMS.WPF/ViewModels/DevicesViewModel.cs b/DMS.WPF/ViewModels/DevicesViewModel.cs index d643b8b..9b11bf7 100644 --- a/DMS.WPF/ViewModels/DevicesViewModel.cs +++ b/DMS.WPF/ViewModels/DevicesViewModel.cs @@ -5,14 +5,7 @@ using CommunityToolkit.Mvvm.Input; using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Core.Enums; -using DMS.Core.Helper; -using DMS.Core.Models; -using DMS.Helper; -using DMS.Services; -using DMS.WPF.Helper; using DMS.WPF.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using DMS.WPF.Services; using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.ViewModels.Items; @@ -45,6 +38,8 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable [ObservableProperty] private DeviceItemViewModel _selectedDevice; + private readonly NotificationService _notificationService; + /// /// 初始化 类的新实例。 /// @@ -53,13 +48,15 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable /// 数据服务。 public DevicesViewModel(IMapper mapper, IDialogService dialogService, INavigationService navigationService, - DataServices dataServices, IDeviceAppService deviceAppService) + DataServices dataServices, IDeviceAppService deviceAppService, + NotificationService notificationService) { _mapper = mapper; _dialogService = dialogService; _navigationService = navigationService; DataServices = dataServices; _deviceAppService = deviceAppService; + _notificationService = notificationService; Devices = new ObservableCollection(); DataServices.OnDeviceListChanged += (devices) => { }; } @@ -116,12 +113,12 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable // 添加设备 var addDto = await DataServices.AddDevice(dto); - NotificationHelper.ShowSuccess($"设备添加成功:{addDto.Device.Name}"); + _notificationService.ShowSuccess($"设备添加成功:{addDto.Device.Name}"); } catch (Exception e) { Console.WriteLine(e); - NotificationHelper.ShowError($"添加设备的过程中发生错误:{e.Message}", e); + _notificationService.ShowError($"添加设备的过程中发生错误:{e.Message}", e); } } @@ -135,7 +132,7 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable { if (SelectedDevice == null) { - NotificationHelper.ShowError("你没有选择任何设备,请选择设备后再点击删除设备"); + _notificationService.ShowError("你没有选择任何设备,请选择设备后再点击删除设备"); return; } @@ -145,13 +142,13 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable var deviceName = SelectedDevice.Name; if (await DataServices.DeleteDevice(SelectedDevice)) { - NotificationHelper.ShowSuccess($"删除设备成功,设备名:{deviceName}"); + _notificationService.ShowSuccess($"删除设备成功,设备名:{deviceName}"); } } } catch (Exception e) { - NotificationHelper.ShowError($"删除设备的过程中发生错误:{e.Message}", e); + _notificationService.ShowError($"删除设备的过程中发生错误:{e.Message}", e); } } @@ -165,7 +162,7 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable { if (SelectedDevice == null) { - NotificationHelper.ShowError("你没有选择任何设备,请选择设备后再点击编辑设备"); + _notificationService.ShowError("你没有选择任何设备,请选择设备后再点击编辑设备"); return; } @@ -183,12 +180,12 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable if (await DataServices.UpdateDevice(device)) { - NotificationHelper.ShowSuccess($"编辑设备成功:{device.Name}"); + _notificationService.ShowSuccess($"编辑设备成功:{device.Name}"); } } catch (Exception e) { - NotificationHelper.ShowError($"编辑设备的过程中发生错误:{e.Message}", e); + _notificationService.ShowError($"编辑设备的过程中发生错误:{e.Message}", e); } } diff --git a/DMS.WPF/ViewModels/Dialogs/ImportExcelDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/ImportExcelDialogViewModel.cs index 1a2822a..73c2b2e 100644 --- a/DMS.WPF/ViewModels/Dialogs/ImportExcelDialogViewModel.cs +++ b/DMS.WPF/ViewModels/Dialogs/ImportExcelDialogViewModel.cs @@ -6,7 +6,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DMS.Core.Interfaces.Services; using DMS.Core.Models; -using DMS.Helper; +using DMS.WPF.Services; using DMS.WPF.ViewModels.Items; namespace DMS.WPF.ViewModels.Dialogs; @@ -15,6 +15,7 @@ public partial class ImportExcelDialogViewModel : DialogViewModelBase private readonly CancellationTokenSource _cancellationTokenSource; + + /// + /// 通知服务实例 + /// + private readonly NotificationService _notificationService; /// /// 构造函数 @@ -96,10 +100,12 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase /// OPC UA服务接口实例 /// 对象映射器实例 - public ImportOpcUaDialogViewModel(IOpcUaService opcUaService, IMapper mapper) + /// 通知服务实例 + public ImportOpcUaDialogViewModel(IOpcUaService opcUaService, IMapper mapper, NotificationService notificationService) { _opcUaService = opcUaService; _mapper = mapper; + _notificationService = notificationService; // 初始化根节点 RootOpcUaNode = new OpcUaNodeItemViewModel() { DisplayName = "根节点", NodeId = Objects.ObjectsFolder, IsExpanded = true }; // 初始化取消令牌源 @@ -143,15 +149,15 @@ public partial class ImportOpcUaDialogViewModel : DialogViewModelBase _logger; private readonly DataServices _dataServices; private readonly IDialogService _dialogService; + private readonly NotificationService _notificationService; /// /// 当前正在编辑的MQTT服务器对象。 @@ -41,12 +41,14 @@ namespace DMS.ViewModels /// 日志服务。 /// 数据服务。 /// 对话框服务。 + /// 通知服务。 public MqttServerDetailViewModel(ILogger logger, DataServices dataServices, - IDialogService dialogService) + IDialogService dialogService, NotificationService notificationService) { _logger = logger; _dataServices = dataServices; _dialogService = dialogService; + _notificationService = notificationService; } public override void OnLoaded() @@ -81,7 +83,7 @@ namespace DMS.ViewModels // await _dataServices.UpdateVariableAsync(variable); // } - NotificationHelper.ShowInfo("MQTT服务器详情保存功能待实现。"); + _notificationService.ShowInfo("MQTT服务器详情保存功能待实现。"); _logger.LogInformation("Save changes for MQTT server detail initiated."); } @@ -131,7 +133,7 @@ namespace DMS.ViewModels // TODO: 实现选择变量的对话框,让用户选择要添加的变量 // 例如:var selectedVariables = await _dialogService.ShowVariableSelectionDialogAsync(); // 这里只是一个占位符,实际需要一个UI来选择变量 - NotificationHelper.ShowInfo("添加变量功能待实现,需要一个变量选择对话框。"); + _notificationService.ShowInfo("添加变量功能待实现,需要一个变量选择对话框。"); _logger.LogInformation("AddAsync variables to MQTT server initiated."); // 假设我们已经通过对话框获取到了一些要添加的变量 diff --git a/DMS.WPF/ViewModels/MqttsViewModel.cs b/DMS.WPF/ViewModels/MqttsViewModel.cs index b97d079..cf543eb 100644 --- a/DMS.WPF/ViewModels/MqttsViewModel.cs +++ b/DMS.WPF/ViewModels/MqttsViewModel.cs @@ -2,7 +2,6 @@ using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DMS.Core.Enums; -using DMS.Helper; using DMS.Services; using DMS.WPF.Helper; using DMS.WPF.Interfaces; diff --git a/DMS.WPF/ViewModels/SettingViewModel.cs b/DMS.WPF/ViewModels/SettingViewModel.cs index 13cbb40..1cfda01 100644 --- a/DMS.WPF/ViewModels/SettingViewModel.cs +++ b/DMS.WPF/ViewModels/SettingViewModel.cs @@ -1,6 +1,5 @@ using CommunityToolkit.Mvvm.Input; using DMS.WPF.Helper; -using DMS.Helper; namespace DMS.WPF.ViewModels; diff --git a/DMS.WPF/ViewModels/SplashViewModel.cs b/DMS.WPF/ViewModels/SplashViewModel.cs index 5ff9bd6..eda4e8c 100644 --- a/DMS.WPF/ViewModels/SplashViewModel.cs +++ b/DMS.WPF/ViewModels/SplashViewModel.cs @@ -19,7 +19,7 @@ namespace DMS.WPF.ViewModels; /// public partial class SplashViewModel : ObservableObject { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; private readonly IInitializeService _initializeService; private readonly IDataCenterService _dataCenterService; @@ -28,7 +28,7 @@ public partial class SplashViewModel : ObservableObject [ObservableProperty] private string _loadingMessage = "正在加载..."; - public SplashViewModel( ILogger logger,IServiceProvider serviceProvider, IInitializeService initializeService, + public SplashViewModel(ILogger logger,IServiceProvider serviceProvider, IInitializeService initializeService, IDataCenterService dataCenterService, DataServices dataServices) { _logger = logger; diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index da7456e..b6d0327 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -5,7 +5,6 @@ using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Core.Enums; using DMS.Core.Models; -using DMS.Helper; using DMS.WPF.Services; using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.ViewModels.Items; @@ -87,13 +86,16 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable private readonly ISynchronizedView _synchronizedView; public NotifyCollectionChangedSynchronizedViewList VariableItemListView { get; } + private readonly NotificationService _notificationService; + public VariableTableViewModel(IMapper mapper, IDialogService dialogService, IVariableAppService variableAppService, - DataServices dataServices) + DataServices dataServices, NotificationService notificationService) { _mapper = mapper; _dialogService = dialogService; _variableAppService = variableAppService; _dataServices = dataServices; + _notificationService = notificationService; IsLoadCompletion = false; // 初始设置为 false,表示未完成加载 @@ -170,7 +172,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 检查是否有变量被选中 if (SelectedVariable == null) { - NotificationHelper.ShowInfo("请选择要编辑的变量"); + _notificationService.ShowInfo("请选择要编辑的变量"); return; } @@ -201,17 +203,17 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 更新当前页面显示的数据:找到原数据在集合中的索引并替换 _mapper.Map(editedVariable, SelectedVariable); // 更新选中项的属性 // 显示成功通知 - NotificationHelper.ShowSuccess($"编辑变量成功:{editedVariable.Name}"); + _notificationService.ShowSuccess($"编辑变量成功:{editedVariable.Name}"); } else { - NotificationHelper.ShowError("编辑变量失败"); + _notificationService.ShowError("编辑变量失败"); } } catch (Exception e) { // 捕获并显示错误通知 - NotificationHelper.ShowError($"编辑变量的过程中发生了不可预期的错误:{e.Message}", e); + _notificationService.ShowError($"编辑变量的过程中发生了不可预期的错误:{e.Message}", e); } } @@ -257,17 +259,17 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable if (isSuccess) { _variableItemList.AddRange(_mapper.Map>(improtVariableDtos)); - NotificationHelper.ShowSuccess($"从Excel导入变量成功,共导入变量:{improtVariableDtos.Count}个"); + _notificationService.ShowSuccess($"从Excel导入变量成功,共导入变量:{improtVariableDtos.Count}个"); } } else { - NotificationHelper.ShowSuccess($"列表中没有要添加的变量了。 "); + _notificationService.ShowSuccess($"列表中没有要添加的变量了。 "); } } catch (Exception e) { - NotificationHelper.ShowError($"从TIA导入变量的过程中发生了不可预期的错误:{e.Message}", e); + _notificationService.ShowError($"从TIA导入变量的过程中发生了不可预期的错误:{e.Message}", e); } } @@ -282,14 +284,14 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable { if (CurrentVariableTable.Device == null) { - NotificationHelper.ShowError("当前变量表的Device对象为空,请检查。"); + _notificationService.ShowError("当前变量表的Device对象为空,请检查。"); return; } // 检查OPC UA Endpoint URL是否已设置 string opcUaEndpointUrl = CurrentVariableTable.Device.OpcUaServerUrl; if (string.IsNullOrEmpty(opcUaEndpointUrl)) { - NotificationHelper.ShowError("OPC UA Endpoint URL 未设置。请在设备详情中配置。"); + _notificationService.ShowError("OPC UA Endpoint URL 未设置。请在设备详情中配置。"); return; } @@ -331,21 +333,21 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable if (isSuccess) { _variableItemList.AddRange(_mapper.Map>(importedVariableDtos)); - NotificationHelper.ShowSuccess($"从OPC UA服务器导入变量成功,共导入变量:{importedVariableDtos.Count}个"); + _notificationService.ShowSuccess($"从OPC UA服务器导入变量成功,共导入变量:{importedVariableDtos.Count}个"); } else { - NotificationHelper.ShowError("从OPC UA服务器导入变量失败"); + _notificationService.ShowError("从OPC UA服务器导入变量失败"); } } else { - NotificationHelper.ShowSuccess("列表中没有要添加的变量了。"); + _notificationService.ShowSuccess("列表中没有要添加的变量了。"); } } catch (Exception e) { - NotificationHelper.ShowError($"从OPC UA服务器导入变量的过程中发生了不可预期的错误:{e.Message}", e); + _notificationService.ShowError($"从OPC UA服务器导入变量的过程中发生了不可预期的错误:{e.Message}", e); } } @@ -389,12 +391,12 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable _dataServices.AddVariable(variableItemViewModel); // // // 显示成功通知 - NotificationHelper.ShowSuccess($"添加变量成功:{variableItemViewModel.Name}"); + _notificationService.ShowSuccess($"添加变量成功:{variableItemViewModel.Name}"); } catch (Exception e) { // 捕获并显示错误通知 - NotificationHelper.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e); + _notificationService.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e); } } @@ -412,7 +414,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 检查是否有变量被选中 if (variablesToDelete == null || !variablesToDelete.Any()) { - NotificationHelper.ShowInfo("请选择要删除的变量"); + _notificationService.ShowInfo("请选择要删除的变量"); return; } @@ -436,18 +438,18 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable _dataServices.DeleteVariable(variable.Id); } // 显示成功通知 - NotificationHelper.ShowSuccess($"成功删除 {variablesToDelete.Count} 个变量"); + _notificationService.ShowSuccess($"成功删除 {variablesToDelete.Count} 个变量"); } else { // 显示删除失败通知 - NotificationHelper.ShowError("删除变量失败"); + _notificationService.ShowError("删除变量失败"); } } catch (Exception e) { // 捕获并显示错误通知 - NotificationHelper.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e); + _notificationService.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e); } } @@ -462,7 +464,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 检查是否有变量被选中 if (SelectedVariables.Count == 0) { - NotificationHelper.ShowInfo("请选择要修改轮询频率的变量"); + _notificationService.ShowInfo("请选择要修改轮询频率的变量"); return; } @@ -488,11 +490,11 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable if (result > 0) { // 显示成功通知 - NotificationHelper.ShowSuccess($"已成功更新 {validVariables.Count} 个变量的轮询频率"); + _notificationService.ShowSuccess($"已成功更新 {validVariables.Count} 个变量的轮询频率"); } else { - NotificationHelper.ShowError("更新轮询频率失败"); + _notificationService.ShowError("更新轮询频率失败"); } } } @@ -646,7 +648,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 检查是否有变量被选中 if (SelectedVariables.Count == 0) { - NotificationHelper.ShowInfo("请选择要修改启用状态的变量"); + _notificationService.ShowInfo("请选择要修改启用状态的变量"); return; } @@ -672,11 +674,11 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable if (result > 0) { // 显示成功通知 - NotificationHelper.ShowSuccess($"已成功更新 {validVariables.Count} 个变量的启用状态"); + _notificationService.ShowSuccess($"已成功更新 {validVariables.Count} 个变量的启用状态"); } else { - NotificationHelper.ShowError("更新启用状态失败"); + _notificationService.ShowError("更新启用状态失败"); } } } diff --git a/DMS.WPF/Views/Dialogs/DeviceDialog.xaml.cs b/DMS.WPF/Views/Dialogs/DeviceDialog.xaml.cs index a51a0f4..8feb217 100644 --- a/DMS.WPF/Views/Dialogs/DeviceDialog.xaml.cs +++ b/DMS.WPF/Views/Dialogs/DeviceDialog.xaml.cs @@ -1,9 +1,5 @@ -using System.Windows; using System.Windows.Controls; -using DMS.Core.Helper; using DMS.WPF.Helper; -using DMS.WPF.ViewModels.Dialogs; -using iNKORE.UI.WPF.Helpers; using iNKORE.UI.WPF.Modern.Controls; namespace DMS.WPF.Views.Dialogs; @@ -23,7 +19,7 @@ public partial class DeviceDialog : ContentDialog private void OnOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) { - //޸ĶԻݵȺ߶ + //�޸ĶԻ������ݵ�����Ⱥ����߶� var backgroundElementBorder = VisualTreeFinder.FindVisualChildByName(this, "BackgroundElement"); backgroundElementBorder.MaxWidth = ContentAreaMaxWidth; backgroundElementBorder.MaxWidth = ContentAreaMaxHeight; diff --git a/DMS.WPF/Views/Dialogs/ImportOpcUaDialog.xaml.cs b/DMS.WPF/Views/Dialogs/ImportOpcUaDialog.xaml.cs index bb26504..be2770c 100644 --- a/DMS.WPF/Views/Dialogs/ImportOpcUaDialog.xaml.cs +++ b/DMS.WPF/Views/Dialogs/ImportOpcUaDialog.xaml.cs @@ -1,6 +1,6 @@ -using DMS.Helper; using DMS.Services; using DMS.WPF.Helper; +using DMS.WPF.Services; using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.ViewModels.Items; using iNKORE.UI.WPF.Modern.Controls; @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; +using Microsoft.Extensions.DependencyInjection; namespace DMS.WPF.Views.Dialogs; @@ -22,6 +23,8 @@ public partial class ImportOpcUaDialog : ContentDialog + + public ImportOpcUaDialog() { InitializeComponent(); @@ -49,7 +52,8 @@ public partial class ImportOpcUaDialog : ContentDialog } catch (Exception ex) { - NotificationHelper.ShowError($"选择节点时发生了错误:{ex.Message}"); + var notificationService = App.Current.Services.GetRequiredService(); + notificationService.ShowError($"选择节点时发生了错误:{ex.Message}"); } diff --git a/DMS.WPF/Views/MainView.xaml.cs b/DMS.WPF/Views/MainView.xaml.cs index 9ff7d57..db41ad5 100644 --- a/DMS.WPF/Views/MainView.xaml.cs +++ b/DMS.WPF/Views/MainView.xaml.cs @@ -1,5 +1,4 @@ using System.Windows; -using DMS.Core.Helper; using DMS.WPF.Services; using DMS.WPF.ViewModels; using iNKORE.UI.WPF.Modern.Controls; @@ -23,8 +22,7 @@ public partial class MainView : Window InitializeComponent(); _viewModel = App.Current.Services.GetRequiredService(); DataContext = _viewModel; - NlogHelper.Info("主界面加载成功"); - + // Set the NotifyIcon's DataContext to the ViewModel MyNotifyIcon.DataContext = _viewModel; } diff --git a/DMS.WPF/Views/VariableTableView.xaml.cs b/DMS.WPF/Views/VariableTableView.xaml.cs index a4590da..00cb79f 100644 --- a/DMS.WPF/Views/VariableTableView.xaml.cs +++ b/DMS.WPF/Views/VariableTableView.xaml.cs @@ -2,8 +2,8 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; -using DMS.Helper; using DMS.WPF.ViewModels; +using DMS.WPF.Services; using iNKORE.UI.WPF.Modern.Controls; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -39,7 +39,8 @@ public partial class VariableTableView : UserControl } catch (Exception exception) { - NotificationHelper.ShowError($"修改变量表启用,停用时发生了错误:{exception.Message}", exception); + var notificationService = App.Current.Services.GetRequiredService(); + notificationService.ShowError($"修改变量表启用,停用时发生了错误:{exception.Message}", exception); } } @@ -47,6 +48,5 @@ public partial class VariableTableView : UserControl { IsLoadCompletion = true; } - } \ No newline at end of file