14 KiB
14 KiB
SystemManagementViewModel 集成方案
1. 与LogisticsControlViewModel的解耦策略
1.1 依赖关系处理
原始依赖关系问题:
- LogisticsControlViewModel 直接包含所有系统管理代码
- UI更新、状态管理、业务逻辑混合在一起
- 违反单一职责原则
解耦方案:
// 在LogisticsControlViewModel中
public class LogisticsControlViewModel : ViewModelBase
{
// 移除所有系统管理相关的字段和属性
// private string _modelSplitterStatus; // 删除
// private ObservableCollection<string> _logLevels; // 删除
// ... 其他系统管理相关代码
// 添加SystemManagementViewModel的引用
private SystemManagementViewModel _systemManagementViewModel;
public SystemManagementViewModel SystemManagement
{
get => _systemManagementViewModel;
private set => SetProperty(ref _systemManagementViewModel, value);
}
public LogisticsControlViewModel() : base()
{
try
{
// 原有初始化代码...
// 初始化系统管理ViewModel
SystemManagement = new SystemManagementViewModel();
// 订阅系统管理事件(如果需要)
SubscribeToSystemManagementEvents();
}
catch (Exception ex)
{
// 错误处理
}
}
// 移除所有系统管理相关的方法
// private async Task InitializeSystemManagementSettingsAsync() // 删除
// private void ExecuteClearLog() // 删除
// private void ExecuteExportLog() // 删除
// ... 其他系统管理方法
}
1.2 事件通信机制
// 定义系统管理事件接口
public interface ISystemManagementEvents
{
event EventHandler<SystemStatusChangedEventArgs> SystemStatusChanged;
event EventHandler<PerformanceAlertEventArgs> PerformanceAlert;
event EventHandler<ConfigurationChangedEventArgs> ConfigurationChanged;
}
// 在SystemManagementViewModel中实现事件发布
public class SystemManagementViewModel : ViewModelBase, ISystemManagementEvents
{
public event EventHandler<SystemStatusChangedEventArgs> SystemStatusChanged;
public event EventHandler<PerformanceAlertEventArgs> PerformanceAlert;
public event EventHandler<ConfigurationChangedEventArgs> ConfigurationChanged;
// 触发系统状态变更事件
private void OnSystemStatusChanged(string newStatus, string color)
{
SystemStatusChanged?.Invoke(this, new SystemStatusChangedEventArgs
{
Status = newStatus,
StatusColor = color,
Timestamp = DateTime.Now
});
}
// 触发性能警告事件
private void OnPerformanceAlert(PerformanceAlertType alertType, string message)
{
PerformanceAlert?.Invoke(this, new PerformanceAlertEventArgs
{
AlertType = alertType,
Message = message,
Timestamp = DateTime.Now
});
}
}
// 在LogisticsControlViewModel中订阅事件
private void SubscribeToSystemManagementEvents()
{
if (SystemManagement != null)
{
SystemManagement.SystemStatusChanged += OnSystemStatusChanged;
SystemManagement.PerformanceAlert += OnPerformanceAlert;
SystemManagement.ConfigurationChanged += OnConfigurationChanged;
}
}
private void OnSystemStatusChanged(object sender, SystemStatusChangedEventArgs e)
{
// 处理系统状态变更(如果主ViewModel需要知道)
// 例如:更新主界面的状态指示器
StatusText = $"系统状态: {e.Status}";
}
2. UI集成策略
2.1 XAML绑定方案
<!-- 原始的SystemManagementView.xaml -->
<!-- 通过DataContext绑定到LogisticsControlViewModel.SystemManagement -->
<UserControl x:Class="NavisworksTransport.UI.WPF.Views.SystemManagementView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 原有的UI控件绑定路径需要调整 -->
<!-- 原来: -->
<!-- <ComboBox ItemsSource="{Binding LogLevels}" SelectedItem="{Binding SelectedLogLevel}" /> -->
<!-- 现在: -->
<!-- 通过父级LogisticsControlViewModel的SystemManagement属性访问 -->
<ComboBox ItemsSource="{Binding SystemManagement.LogLevels}"
SelectedItem="{Binding SystemManagement.SelectedLogLevel}" />
<Button Content="查看日志" Command="{Binding SystemManagement.ViewLogCommand}" />
<Button Content="清空日志" Command="{Binding SystemManagement.ClearLogCommand}" />
<Button Content="导出日志" Command="{Binding SystemManagement.ExportLogCommand}" />
<!-- 性能监控控件 -->
<TextBlock Text="{Binding SystemManagement.MemoryUsage}" />
<TextBlock Text="{Binding SystemManagement.RunningTime}" />
<TextBlock Text="{Binding SystemManagement.PerformanceInfo}" />
<!-- 系统状态控件 -->
<TextBlock Text="{Binding SystemManagement.SystemStatus}"
Foreground="{Binding SystemManagement.SystemStatusColor}" />
</UserControl>
2.2 ViewModelLocator调整
// 在ViewModelLocator中注册SystemManagementViewModel
public class ViewModelLocator
{
public LogisticsControlViewModel LogisticsControl => ServiceLocator.Current.GetInstance<LogisticsControlViewModel>();
// 可以选择直接注册SystemManagementViewModel
public SystemManagementViewModel SystemManagement => ServiceLocator.Current.GetInstance<SystemManagementViewModel>();
static ViewModelLocator()
{
// 注册服务
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
// 注册SystemManagementViewModel及其依赖
SimpleIoc.Default.Register<ISystemLogManager, DefaultSystemLogManager>();
SimpleIoc.Default.Register<ISystemConfigManager, DefaultSystemConfigManager>();
SimpleIoc.Default.Register<IPerformanceMonitor, DefaultPerformanceMonitor>();
SimpleIoc.Default.Register<IModelSplitterManager, DefaultModelSplitterManager>();
SimpleIoc.Default.Register<SystemManagementViewModel>();
SimpleIoc.Default.Register<LogisticsControlViewModel>();
}
}
3. 初始化和生命周期管理
3.1 初始化顺序
public class LogisticsControlViewModel : ViewModelBase
{
private async void InitializeViewModelAsync()
{
await SafeExecuteAsync(async () =>
{
// 1. 先初始化核心组件
await UpdateInstructionTextAsync();
await UpdateSelectionDisplayAsync();
await InitializeCategoriesAsync();
// 2. 初始化系统管理ViewModel
await InitializeSystemManagementAsync();
// 3. 最后更新UI状态
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
StatusText = "插件已就绪";
AnimationStatus = "动画状态: 就绪";
AnimationProgress = 0;
WidthLimit = 3.0;
});
// 4. 初始化动画设置
await InitializeAnimationSettingsAsync();
LogManager.Info("LogisticsControlViewModel 初始化完成");
}, "初始化ViewModel");
}
private async Task InitializeSystemManagementAsync()
{
await SafeExecuteAsync(async () =>
{
// 创建SystemManagementViewModel实例
SystemManagement = new SystemManagementViewModel(
logManager: ServiceProvider.GetService<ISystemLogManager>(),
configManager: ServiceProvider.GetService<ISystemConfigManager>(),
performanceMonitor: ServiceProvider.GetService<IPerformanceMonitor>(),
modelSplitterManager: ServiceProvider.GetService<IModelSplitterManager>()
);
// 订阅系统管理事件
SubscribeToSystemManagementEvents();
LogManager.Info("系统管理ViewModel初始化完成");
}, "初始化系统管理");
}
}
3.2 清理机制
public class LogisticsControlViewModel : ViewModelBase
{
// 添加清理方法
public void Cleanup()
{
try
{
LogManager.Info("开始清理LogisticsControlViewModel资源");
// 清理系统管理ViewModel
if (SystemManagement != null)
{
UnsubscribeFromSystemManagementEvents();
SystemManagement.Cleanup();
SystemManagement = null;
}
// 原有的清理代码...
LogManager.Info("LogisticsControlViewModel资源清理完成");
}
catch (Exception ex)
{
LogManager.Error($"LogisticsControlViewModel清理失败: {ex.Message}");
}
}
private void UnsubscribeFromSystemManagementEvents()
{
if (SystemManagement != null)
{
SystemManagement.SystemStatusChanged -= OnSystemStatusChanged;
SystemManagement.PerformanceAlert -= OnPerformanceAlert;
SystemManagement.ConfigurationChanged -= OnConfigurationChanged;
}
}
}
4. 命令重定向机制
4.1 保持向后兼容性
public class LogisticsControlViewModel : ViewModelBase
{
// 保持原有命令接口,但重定向到SystemManagementViewModel
public ICommand ViewLogCommand => SystemManagement?.ViewLogCommand;
public ICommand ClearLogCommand => SystemManagement?.ClearLogCommand;
public ICommand ExportLogCommand => SystemManagement?.ExportLogCommand;
public ICommand OpenSettingsCommand => SystemManagement?.OpenSettingsCommand;
public ICommand ResetSettingsCommand => SystemManagement?.ResetSettingsCommand;
public ICommand ImportConfigCommand => SystemManagement?.ImportConfigCommand;
public ICommand CheckUpdateCommand => SystemManagement?.CheckUpdateCommand;
public ICommand GeneratePerformanceReportCommand => SystemManagement?.GeneratePerformanceReportCommand;
// 或者使用代理模式
private void InitializeCommandProxies()
{
ViewLogCommand = new RelayCommand(async () =>
{
if (SystemManagement != null)
await SystemManagement.ViewLogCommand.ExecuteAsync(null);
});
ClearLogCommand = new RelayCommand(async () =>
{
if (SystemManagement != null)
await SystemManagement.ClearLogCommand.ExecuteAsync(null);
});
// ... 其他命令代理
}
}
5. 测试策略
5.1 单元测试
[TestFixture]
public class SystemManagementViewModelTests
{
private SystemManagementViewModel _viewModel;
private Mock<ISystemLogManager> _mockLogManager;
private Mock<ISystemConfigManager> _mockConfigManager;
[SetUp]
public void Setup()
{
_mockLogManager = new Mock<ISystemLogManager>();
_mockConfigManager = new Mock<ISystemConfigManager>();
_viewModel = new SystemManagementViewModel(
_mockLogManager.Object,
_mockConfigManager.Object
);
}
[Test]
public async Task ExecuteViewLogAsync_ShouldCallLogManager()
{
// Arrange
_mockLogManager.Setup(x => x.OpenLogViewerAsync()).Returns(Task.CompletedTask);
// Act
await _viewModel.ViewLogCommand.ExecuteAsync(null);
// Assert
_mockLogManager.Verify(x => x.OpenLogViewerAsync(), Times.Once);
Assert.AreEqual("日志查看器已打开", _viewModel.LogStatus);
}
}
5.2 集成测试
[TestFixture]
public class SystemManagementIntegrationTests
{
[Test]
public void LogisticsControlViewModel_ShouldInitializeSystemManagement()
{
// Arrange & Act
var logisticsVM = new LogisticsControlViewModel();
// Assert
Assert.IsNotNull(logisticsVM.SystemManagement);
Assert.IsInstanceOf<SystemManagementViewModel>(logisticsVM.SystemManagement);
}
[Test]
public void SystemManagementEvents_ShouldPropagateToMainViewModel()
{
// Arrange
var logisticsVM = new LogisticsControlViewModel();
var systemManagementVM = logisticsVM.SystemManagement;
string receivedStatus = null;
logisticsVM.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(LogisticsControlViewModel.StatusText))
receivedStatus = logisticsVM.StatusText;
};
// Act
systemManagementVM.SystemStatus = "测试状态";
// 触发SystemStatusChanged事件
// Assert
Assert.IsTrue(receivedStatus?.Contains("测试状态"));
}
}
6. 迁移计划
6.1 分阶段迁移
阶段1:创建基础架构
- 创建SystemManagementViewModel类
- 定义所需接口
- 创建默认实现类
- 设置依赖注入
阶段2:迁移核心功能
- 迁移日志管理功能
- 迁移设置管理功能
- 迁移性能监控功能
- 测试基本功能
阶段3:集成和优化
- 集成到LogisticsControlViewModel
- 调整UI绑定
- 实现事件通信
- 性能优化
阶段4:测试和部署
- 全面测试
- 修复问题
- 文档更新
- 部署验证
6.2 兼容性保证
// 在迁移期间,保持旧接口可用
public class LogisticsControlViewModel : ViewModelBase
{
// 新的系统管理ViewModel
private SystemManagementViewModel _systemManagement;
// 保持旧属性兼容性(标记为过时)
[Obsolete("请使用SystemManagement.LogLevels", false)]
public ObservableCollection<string> LogLevels => SystemManagement?.LogLevels;
[Obsolete("请使用SystemManagement.SelectedLogLevel", false)]
public string SelectedLogLevel
{
get => SystemManagement?.SelectedLogLevel;
set { if (SystemManagement != null) SystemManagement.SelectedLogLevel = value; }
}
// 保持旧命令兼容性
[Obsolete("请使用SystemManagement.ViewLogCommand", false)]
public ICommand ViewLogCommand => SystemManagement?.ViewLogCommand;
}
这个解耦方案确保了:
- 清晰的职责分离:系统管理功能完全独立
- 向后兼容性:现有UI和代码不会立即失效
- 渐进式迁移:可以分步骤进行迁移
- 良好的测试性:每个组件都可以独立测试
- 事件驱动通信:组件间通过事件解耦