NavisworksTransport/SystemManagement_Integration_Plan.md

14 KiB
Raw Blame History

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创建基础架构

  1. 创建SystemManagementViewModel类
  2. 定义所需接口
  3. 创建默认实现类
  4. 设置依赖注入

阶段2迁移核心功能

  1. 迁移日志管理功能
  2. 迁移设置管理功能
  3. 迁移性能监控功能
  4. 测试基本功能

阶段3集成和优化

  1. 集成到LogisticsControlViewModel
  2. 调整UI绑定
  3. 实现事件通信
  4. 性能优化

阶段4测试和部署

  1. 全面测试
  2. 修复问题
  3. 文档更新
  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;
}

这个解耦方案确保了:

  1. 清晰的职责分离:系统管理功能完全独立
  2. 向后兼容性现有UI和代码不会立即失效
  3. 渐进式迁移:可以分步骤进行迁移
  4. 良好的测试性:每个组件都可以独立测试
  5. 事件驱动通信:组件间通过事件解耦