diff --git a/DMS.Application/DTOs/Events/DataChangeType.cs b/DMS.Application/DTOs/Events/DataChangeType.cs new file mode 100644 index 0000000..8bc84fc --- /dev/null +++ b/DMS.Application/DTOs/Events/DataChangeType.cs @@ -0,0 +1,33 @@ +namespace DMS.Application.DTOs.Events +{ + /// + /// 数据变更类型枚举 + /// + public enum DataChangeType + { + /// + /// 添加 + /// + Added, + + /// + /// 更新 + /// + Updated, + + /// + /// 删除 + /// + Deleted, + + /// + /// 加载 + /// + Loaded, + + /// + /// 批量操作 + /// + BatchOperation + } +} \ No newline at end of file diff --git a/DMS.Application/DTOs/Events/DataChangedEventArgs.cs b/DMS.Application/DTOs/Events/DataChangedEventArgs.cs new file mode 100644 index 0000000..c2304bd --- /dev/null +++ b/DMS.Application/DTOs/Events/DataChangedEventArgs.cs @@ -0,0 +1,30 @@ +using System; + +namespace DMS.Application.DTOs.Events +{ + /// + /// 数据变更事件参数基类 + /// + public class DataChangedEventArgs : System.EventArgs + { + /// + /// 变更类型 + /// + public DataChangeType ChangeType { get; } + + /// + /// 变更时间 + /// + public DateTime ChangeTime { get; } + + /// + /// 构造函数 + /// + /// 变更类型 + public DataChangedEventArgs(DataChangeType changeType) + { + ChangeType = changeType; + ChangeTime = DateTime.Now; + } + } +} \ No newline at end of file diff --git a/DMS.Application/DTOs/Events/DataLoadCompletedEventArgs.cs b/DMS.Application/DTOs/Events/DataLoadCompletedEventArgs.cs new file mode 100644 index 0000000..9447a64 --- /dev/null +++ b/DMS.Application/DTOs/Events/DataLoadCompletedEventArgs.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +namespace DMS.Application.DTOs.Events +{ + /// + /// 数据加载完成事件参数 + /// + public class DataLoadCompletedEventArgs : System.EventArgs + { + /// + /// 加载的设备数量 + /// + public int DeviceCount { get; } + + /// + /// 加载的变量表数量 + /// + public int VariableTableCount { get; } + + /// + /// 加载的变量数量 + /// + public int VariableCount { get; } + + /// + /// 加载是否成功 + /// + public bool IsSuccess { get; } + + /// + /// 加载时间 + /// + public DateTime LoadTime { get; } + + /// + /// 错误信息(如果加载失败) + /// + public string ErrorMessage { get; } + + /// + /// 构造函数 + /// + /// 设备数量 + /// 变量表数量 + /// 变量数量 + /// 是否成功 + /// 错误信息 + public DataLoadCompletedEventArgs(int deviceCount, int variableTableCount, int variableCount, bool isSuccess, string errorMessage = null) + { + DeviceCount = deviceCount; + VariableTableCount = variableTableCount; + VariableCount = variableCount; + IsSuccess = isSuccess; + ErrorMessage = errorMessage; + LoadTime = DateTime.Now; + } + } +} \ No newline at end of file diff --git a/DMS.Application/DTOs/Events/DeviceChangedEventArgs.cs b/DMS.Application/DTOs/Events/DeviceChangedEventArgs.cs new file mode 100644 index 0000000..02acab4 --- /dev/null +++ b/DMS.Application/DTOs/Events/DeviceChangedEventArgs.cs @@ -0,0 +1,44 @@ +using System; + +namespace DMS.Application.DTOs.Events +{ + /// + /// 设备变更事件参数 + /// + public class DeviceChangedEventArgs : System.EventArgs + { + /// + /// 变更类型 + /// + public DataChangeType ChangeType { get; } + + /// + /// 设备ID + /// + public int DeviceId { get; } + + /// + /// 设备名称 + /// + public string DeviceName { get; } + + /// + /// 变更时间 + /// + public DateTime ChangeTime { get; } + + /// + /// 构造函数 + /// + /// 变更类型 + /// 设备ID + /// 设备名称 + public DeviceChangedEventArgs(DataChangeType changeType, int deviceId, string deviceName) + { + ChangeType = changeType; + DeviceId = deviceId; + DeviceName = deviceName; + ChangeTime = DateTime.Now; + } + } +} \ No newline at end of file diff --git a/DMS.Application/DTOs/Events/VariableChangedEventArgs.cs b/DMS.Application/DTOs/Events/VariableChangedEventArgs.cs new file mode 100644 index 0000000..4644101 --- /dev/null +++ b/DMS.Application/DTOs/Events/VariableChangedEventArgs.cs @@ -0,0 +1,51 @@ +using System; + +namespace DMS.Application.DTOs.Events +{ + /// + /// 变量变更事件参数 + /// + public class VariableChangedEventArgs : System.EventArgs + { + /// + /// 变更类型 + /// + public DataChangeType ChangeType { get; } + + /// + /// 变量ID + /// + public int VariableId { get; } + + /// + /// 变量名称 + /// + public string VariableName { get; } + + /// + /// 关联的变量表ID + /// + public int VariableTableId { get; } + + /// + /// 变更时间 + /// + public DateTime ChangeTime { get; } + + /// + /// 构造函数 + /// + /// 变更类型 + /// 变量ID + /// 变量名称 + /// 关联的变量表ID + public VariableChangedEventArgs(DataChangeType changeType, int variableId, string variableName, int variableTableId) + { + ChangeType = changeType; + VariableId = variableId; + VariableName = variableName; + VariableTableId = variableTableId; + ChangeTime = DateTime.Now; + } + } +} \ No newline at end of file diff --git a/DMS.Application/DTOs/Events/VariableTableChangedEventArgs.cs b/DMS.Application/DTOs/Events/VariableTableChangedEventArgs.cs new file mode 100644 index 0000000..04220eb --- /dev/null +++ b/DMS.Application/DTOs/Events/VariableTableChangedEventArgs.cs @@ -0,0 +1,51 @@ +using System; + +namespace DMS.Application.DTOs.Events +{ + /// + /// 变量表变更事件参数 + /// + public class VariableTableChangedEventArgs : System.EventArgs + { + /// + /// 变更类型 + /// + public DataChangeType ChangeType { get; } + + /// + /// 变量表ID + /// + public int VariableTableId { get; } + + /// + /// 变量表名称 + /// + public string VariableTableName { get; } + + /// + /// 关联的设备ID + /// + public int DeviceId { get; } + + /// + /// 变更时间 + /// + public DateTime ChangeTime { get; } + + /// + /// 构造函数 + /// + /// 变更类型 + /// 变量表ID + /// 变量表名称 + /// 关联的设备ID + public VariableTableChangedEventArgs(DataChangeType changeType, int variableTableId, string variableTableName, int deviceId) + { + ChangeType = changeType; + VariableTableId = variableTableId; + VariableTableName = variableTableName; + DeviceId = deviceId; + ChangeTime = DateTime.Now; + } + } +} \ No newline at end of file diff --git a/DMS.Application/Interfaces/IDataCenterService.cs b/DMS.Application/Interfaces/IDataCenterService.cs index 51157c4..860d75d 100644 --- a/DMS.Application/Interfaces/IDataCenterService.cs +++ b/DMS.Application/Interfaces/IDataCenterService.cs @@ -1,5 +1,7 @@ using DMS.Application.DTOs; +using DMS.Application.DTOs.Events; using DMS.Core.Models; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; @@ -11,6 +13,34 @@ namespace DMS.Application.Interfaces; /// public interface IDataCenterService { + #region 事件定义 + + /// + /// 当数据加载完成时触发 + /// + event EventHandler DataLoadCompleted; + + /// + /// 当设备数据发生变化时触发 + /// + event EventHandler DeviceChanged; + + /// + /// 当变量表数据发生变化时触发 + /// + event EventHandler VariableTableChanged; + + /// + /// 当变量数据发生变化时触发 + /// + event EventHandler VariableChanged; + + /// + /// 当数据发生任何变化时触发 + /// + event EventHandler DataChanged; + + #endregion #region 设备管理 /// diff --git a/DMS.Application/Services/DataCenterService.cs b/DMS.Application/Services/DataCenterService.cs index 46c341c..02a99a1 100644 --- a/DMS.Application/Services/DataCenterService.cs +++ b/DMS.Application/Services/DataCenterService.cs @@ -1,5 +1,6 @@ using AutoMapper; using DMS.Application.DTOs; +using DMS.Application.DTOs.Events; using DMS.Application.Interfaces; using DMS.Core.Interfaces; using DMS.Core.Models; @@ -18,6 +19,34 @@ namespace DMS.Application.Services; /// public class DataCenterService : IDataCenterService { + #region 事件定义 + + /// + /// 当数据加载完成时触发 + /// + public event EventHandler DataLoadCompleted; + + /// + /// 当设备数据发生变化时触发 + /// + public event EventHandler DeviceChanged; + + /// + /// 当变量表数据发生变化时触发 + /// + public event EventHandler VariableTableChanged; + + /// + /// 当变量数据发生变化时触发 + /// + public event EventHandler VariableChanged; + + /// + /// 当数据发生任何变化时触发 + /// + public event EventHandler DataChanged; + + #endregion private readonly IRepositoryManager _repositoryManager; private readonly IMapper _mapper; private readonly IDeviceAppService _deviceAppService; @@ -116,7 +145,10 @@ public class DataCenterService : IDataCenterService /// public void AddDeviceToMemory(DeviceDto deviceDto) { - Devices.TryAdd(deviceDto.Id, deviceDto); + if (Devices.TryAdd(deviceDto.Id, deviceDto)) + { + OnDeviceChanged(new DeviceChangedEventArgs(DataChangeType.Added, deviceDto.Id, deviceDto.Name)); + } } /// @@ -125,6 +157,7 @@ public class DataCenterService : IDataCenterService public void UpdateDeviceInMemory(DeviceDto deviceDto) { Devices.AddOrUpdate(deviceDto.Id, deviceDto, (key, oldValue) => deviceDto); + OnDeviceChanged(new DeviceChangedEventArgs(DataChangeType.Updated, deviceDto.Id, deviceDto.Name)); } /// @@ -132,7 +165,10 @@ public class DataCenterService : IDataCenterService /// public void RemoveDeviceFromMemory(int deviceId) { - Devices.TryRemove(deviceId, out _); + if (Devices.TryRemove(deviceId, out var deviceDto)) + { + OnDeviceChanged(new DeviceChangedEventArgs(DataChangeType.Deleted, deviceId, deviceDto?.Name ?? "")); + } } #endregion @@ -184,7 +220,14 @@ public class DataCenterService : IDataCenterService /// public void AddVariableTableToMemory(VariableTableDto variableTableDto) { - VariableTables.TryAdd(variableTableDto.Id, variableTableDto); + if (VariableTables.TryAdd(variableTableDto.Id, variableTableDto)) + { + OnVariableTableChanged(new VariableTableChangedEventArgs( + DataChangeType.Added, + variableTableDto.Id, + variableTableDto.Name, + variableTableDto.DeviceId)); + } } /// @@ -193,6 +236,11 @@ public class DataCenterService : IDataCenterService public void UpdateVariableTableInMemory(VariableTableDto variableTableDto) { VariableTables.AddOrUpdate(variableTableDto.Id, variableTableDto, (key, oldValue) => variableTableDto); + OnVariableTableChanged(new VariableTableChangedEventArgs( + DataChangeType.Updated, + variableTableDto.Id, + variableTableDto.Name, + variableTableDto.DeviceId)); } /// @@ -200,7 +248,14 @@ public class DataCenterService : IDataCenterService /// public void RemoveVariableTableFromMemory(int variableTableId) { - VariableTables.TryRemove(variableTableId, out _); + if (VariableTables.TryRemove(variableTableId, out var variableTableDto)) + { + OnVariableTableChanged(new VariableTableChangedEventArgs( + DataChangeType.Deleted, + variableTableId, + variableTableDto?.Name ?? "", + variableTableDto?.DeviceId ?? 0)); + } } #endregion @@ -292,7 +347,14 @@ public class DataCenterService : IDataCenterService /// public void AddVariableToMemory(VariableDto variableDto) { - Variables.TryAdd(variableDto.Id, variableDto); + if (Variables.TryAdd(variableDto.Id, variableDto)) + { + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Added, + variableDto.Id, + variableDto.Name, + variableDto.VariableTableId)); + } } /// @@ -301,6 +363,11 @@ public class DataCenterService : IDataCenterService public void UpdateVariableInMemory(VariableDto variableDto) { Variables.AddOrUpdate(variableDto.Id, variableDto, (key, oldValue) => variableDto); + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Updated, + variableDto.Id, + variableDto.Name, + variableDto.VariableTableId)); } /// @@ -308,7 +375,14 @@ public class DataCenterService : IDataCenterService /// public void RemoveVariableFromMemory(int variableId) { - Variables.TryRemove(variableId, out _); + if (Variables.TryRemove(variableId, out var variableDto)) + { + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Deleted, + variableId, + variableDto?.Name ?? "", + variableDto?.VariableTableId ?? 0)); + } } /// @@ -318,8 +392,16 @@ public class DataCenterService : IDataCenterService { foreach (var variable in variables) { - Variables.TryAdd(variable.Id, variable); + if (Variables.TryAdd(variable.Id, variable)) + { + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Added, + variable.Id, + variable.Name, + variable.VariableTableId)); + } } + OnDataChanged(new DataChangedEventArgs(DataChangeType.BatchOperation)); } /// @@ -330,7 +412,13 @@ public class DataCenterService : IDataCenterService foreach (var variable in variables) { Variables.AddOrUpdate(variable.Id, variable, (key, oldValue) => variable); + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Updated, + variable.Id, + variable.Name, + variable.VariableTableId)); } + OnDataChanged(new DataChangedEventArgs(DataChangeType.BatchOperation)); } /// @@ -340,8 +428,69 @@ public class DataCenterService : IDataCenterService { foreach (var variableId in variableIds) { - Variables.TryRemove(variableId, out _); + if (Variables.TryRemove(variableId, out var variableDto)) + { + OnVariableChanged(new VariableChangedEventArgs( + DataChangeType.Deleted, + variableId, + variableDto?.Name ?? "", + variableDto?.VariableTableId ?? 0)); + } } + OnDataChanged(new DataChangedEventArgs(DataChangeType.BatchOperation)); + } + + #endregion + + #region 事件触发方法 + + /// + /// 触发数据加载完成事件 + /// + /// 事件参数 + protected virtual void OnDataLoadCompleted(DataLoadCompletedEventArgs e) + { + DataLoadCompleted?.Invoke(this, e); + OnDataChanged(new DataChangedEventArgs(DataChangeType.Loaded)); + } + + /// + /// 触发设备变更事件 + /// + /// 事件参数 + protected virtual void OnDeviceChanged(DeviceChangedEventArgs e) + { + DeviceChanged?.Invoke(this, e); + OnDataChanged(new DataChangedEventArgs(e.ChangeType)); + } + + /// + /// 触发变量表变更事件 + /// + /// 事件参数 + protected virtual void OnVariableTableChanged(VariableTableChangedEventArgs e) + { + VariableTableChanged?.Invoke(this, e); + OnDataChanged(new DataChangedEventArgs(e.ChangeType)); + } + + /// + /// 触发变量变更事件 + /// + /// 事件参数 + protected virtual void OnVariableChanged(VariableChangedEventArgs e) + { + VariableChanged?.Invoke(this, e); + OnDataChanged(new DataChangedEventArgs(e.ChangeType)); + } + + /// + /// 触发数据变更事件 + /// + /// 事件参数 + protected virtual void OnDataChanged(DataChangedEventArgs e) + { + DataChanged?.Invoke(this, e); } #endregion @@ -399,9 +548,18 @@ public class DataCenterService : IDataCenterService { Variables.TryAdd(variableDto.Id, variableDto); } + + // 触发数据加载完成事件 + OnDataLoadCompleted(new DataLoadCompletedEventArgs( + deviceDtos.Count, + variableTableDtos.Count, + variableDtos.Count, + true)); } catch (Exception ex) { + // 触发数据加载失败事件 + OnDataLoadCompleted(new DataLoadCompletedEventArgs(0, 0, 0, false, ex.Message)); throw new ApplicationException($"加载所有数据到内存时发生错误,错误信息:{ex.Message}", ex); } } diff --git a/DMS.Infrastructure.UnitTests/DataCenterServiceTests.cs b/DMS.Infrastructure.UnitTests/DataCenterServiceTests.cs index 75cbf7f..a767bca 100644 --- a/DMS.Infrastructure.UnitTests/DataCenterServiceTests.cs +++ b/DMS.Infrastructure.UnitTests/DataCenterServiceTests.cs @@ -1,8 +1,10 @@ using DMS.Application.DTOs; +using DMS.Application.DTOs.Events; using DMS.Application.Interfaces; using DMS.Application.Services; using DMS.Core.Interfaces; using Moq; +using System; using System.Collections.Concurrent; using Xunit; @@ -139,5 +141,36 @@ namespace DMS.Infrastructure.UnitTests // Assert Assert.False(dataCenterService.Devices.ContainsKey(1)); } + + [Fact] + public void DataCenterService_Should_Raise_DeviceChanged_Event_On_Add() + { + // Arrange + var mockRepositoryManager = new Mock(); + var mockMapper = new Mock(); + var mockDeviceAppService = new Mock(); + var mockVariableTableAppService = new Mock(); + var mockVariableAppService = new Mock(); + var dataCenterService = new DataCenterService( + mockRepositoryManager.Object, + mockMapper.Object, + mockDeviceAppService.Object, + mockVariableTableAppService.Object, + mockVariableAppService.Object); + + DeviceChangedEventArgs eventArgs = null; + dataCenterService.DeviceChanged += (sender, args) => eventArgs = args; + + var deviceDto = new DeviceDto { Id = 1, Name = "Test Device" }; + + // Act + dataCenterService.AddDeviceToMemory(deviceDto); + + // Assert + Assert.NotNull(eventArgs); + Assert.Equal(DataChangeType.Added, eventArgs.ChangeType); + Assert.Equal(1, eventArgs.DeviceId); + Assert.Equal("Test Device", eventArgs.DeviceName); + } } } \ No newline at end of file