You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 KiB

修改记录

2024年修改记录

修复NetworkProtocolLogObserver中的StopChannelManager方法并支持重新创建

修改时间: 2024年12月 修改文件:

  • CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
  • CoreAgent.WebSocketTransport/Interfaces/IMessageChannelManager.cs
  • CoreAgent.WebSocketTransport/Services/MessageChannelManager.cs

修改内容:

  1. 问题描述:

    • StopChannelManager() 方法直接调用 _ChannelManager.Dispose() 可能导致资源过早释放
    • IMessageChannelManager 接口已实现 IDisposable,生命周期应由DI容器管理
    • 直接调用 Dispose() 可能影响其他使用该实例的组件
  2. 修复方案:

    • 修改 MessageChannelManager 设计,不在构造函数中创建通道

    • 移除构造函数中的默认参数,要求必须传入容量参数

    • 添加容量参数验证,确保参数有效性

    • 扩展 WebSocketConfig 配置类,添加分别的通道容量配置

    • 更新依赖注入注册,从配置中读取不同的通道容量

    • 优化通道管理方法,职责更加清晰:

      • CreateChannels() - 安全创建(已存在则跳过)
      • ClearAllChannels() - 清空通道消息(保持通道可用)
      • CompleteAllChannels() - 完成通道(标记不再接受新消息,但保持可读)
      • ReleaseChannels() - 完全释放通道资源
    • StopChannelManager() 改为调用 ReleaseChannels()

    • RecreateChannelManager() 改为调用 CreateChannels()

    • 优化通道创建逻辑

      • 修改 CreateChannels() 方法,如果通道已存在则先释放再创建
      • 移除 ResetChannels() 方法,避免功能重复
      • 简化接口设计,减少方法数量
    • WebSocketTransport 集成通道管理

      • 重构 ConnectInternalAsync() 方法,提取为多个独立方法:
        • CreateMessageChannels() - 先创建消息通道(同步方法)
        • EstablishWebSocketConnectionAsync() - 再建立WebSocket连接(异步方法)
        • StartBackgroundTasks() - 最后启动后台任务(同步方法)
      • CloseAsync() 中调用 _channelManager.ReleaseChannels() 释放通道
      • 在重连失败时也释放通道,确保资源正确清理
      • 通道生命周期与WebSocket连接生命周期完全同步
    • 添加自动重连配置选项

      • WebSocketConfig 中添加 EnableAutoReconnect 配置项
      • TriggerReconnect() 方法中添加配置检查
      • 支持通过配置文件控制是否启用自动重连功能
    • 修复WebSocket配置文件

      • 更新 websocket.jsonwebsocket.Development.json 配置文件
      • 添加所有新增的配置项:EnableAutoReconnectSendChannelCapacityReceiveChannelCapacityPriorityChannelCapacityMaxChunkSizeChunkDelayMs
      • 为开发环境和生产环境提供不同的配置值
    • 添加重复调用检查,避免二次调用导致异常

    • 添加异常处理和日志记录

    • 保持方法功能的同时避免资源管理问题

  3. 具体修改: IMessageChannelManager 接口新增方法:

    /// <summary>
    /// 创建所有通道
    /// </summary>
    void CreateChannels();
    
    /// <summary>
    /// 释放所有通道
    /// </summary>
    void ReleaseChannels();
    

    MessageChannelManager 实现:

    // 构造函数要求必须传入容量参数,并验证参数有效性
    public MessageChannelManager(ILogger<MessageChannelManager> logger, int sendChannelCapacity, int receiveChannelCapacity, int priorityChannelCapacity)
    {
        // 验证容量参数
        if (sendChannelCapacity <= 0) throw new ArgumentOutOfRangeException(...);
        // 保存容量配置,不创建通道
    }
    
    // 安全创建通道(如果已存在则跳过)
    public void CreateChannels()
    {
        // 检查通道是否已存在,如果存在则跳过创建
    }
    
    // 清空通道消息(保持通道可用)
    public void ClearAllChannels()
    {
        // 清空所有通道中的消息,但保持通道结构
    }
    
    // 完成通道(标记不再接受新消息,但保持可读)
    public void CompleteAllChannels()
    {
        // 标记通道完成,不再接受新消息,但可以继续读取
    }
    
    // 完全释放通道资源
    public void ReleaseChannels()
    {
        // 完成通道,释放资源,清空引用
    }
    
    
    

    WebSocketConfig 配置扩展:

    public class WebSocketConfig
    {
        // 是否启用自动重连功能
        public bool EnableAutoReconnect { get; set; } = true;
    
        // 最大重连尝试次数
        public int MaxReconnectAttempts { get; set; } = 5;
    
        // 发送通道容量
        public int SendChannelCapacity { get; set; } = 1000;
    
        // 接收通道容量
        public int ReceiveChannelCapacity { get; set; } = 1000;
    
        // 优先级通道容量
        public int PriorityChannelCapacity { get; set; } = 100;
    }
    

    依赖注入注册更新:

    services.AddSingleton<IMessageChannelManager>(provider =>
    {
        var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
        return new MessageChannelManager(logger, config.SendChannelCapacity, config.ReceiveChannelCapacity, config.PriorityChannelCapacity);
    });
    

    NetworkProtocolLogObserver 修改:

    public void StopChannelManager()
    {
        // 调用 ReleaseChannels() 释放通道
        _ChannelManager.ReleaseChannels();
    }
    
    public void RecreateChannelManager()
    {
        // 调用 CreateChannels() 重新创建通道(会自动释放现有通道)
        _ChannelManager.CreateChannels();
    }
    

    WebSocketTransport 重构:

    // 连接时先创建通道,再建立连接
    private async Task ConnectInternalAsync(CancellationToken cancellationToken)
    {
        // 1. 先创建消息通道
        await CreateMessageChannelsAsync();
    
        // 2. 再建立 WebSocket 连接
        await EstablishWebSocketConnectionAsync(cancellationToken);
    
        // 3. 最后启动后台任务
        await StartBackgroundTasksAsync();
    }
    
    // 提取的独立方法
    private void CreateMessageChannels()
    {
        _channelManager.CreateChannels();
    }
    
    private async Task EstablishWebSocketConnectionAsync(CancellationToken cancellationToken)
    {
        await _connection.ConnectAsync(...);
    }
    
    private void StartBackgroundTasks()
    {
        // 启动发送、接收、心跳任务
    }
    
  4. 修复优势:

    • 配置灵活性: 支持通过配置文件分别设置不同通道的容量,更加灵活
    • 参数验证: 构造函数中验证容量参数,确保参数有效性
    • 方法职责清晰: 每个方法职责明确,避免功能重叠
    • 生命周期控制: 通道的创建和释放完全由用户控制,更加灵活
    • 资源管理: 避免在构造函数中创建资源,符合延迟初始化原则
    • 重复使用: 支持多次创建和释放,满足业务需求
    • 重复调用保护: 防止二次调用导致异常,提高系统稳定性
    • 异常处理: 添加了完整的异常处理和日志记录,但不影响主程序运行
    • 业务连续性: 异常被捕获并记录,但不会中断主程序流程
    • 功能保持: 仍然能够正确停止和重新创建通道管理器
    • 日志完善: 提供了详细的调试和错误日志信息

创建蜂窝网络配置实体类

创建蜂窝网络配置实体类

修改时间: 2024年 修改文件:

  • CoreAgent.Domain/Models/Network/CellularNetworkConfiguration.cs (新建)

修改内容:

  1. 创建CellularNetworkConfiguration实体类

    • 包含设备代码(DeviceCode)字符串属性
    • 包含运行时代码(RuntimeCode)字符串属性
    • 包含无线接入网配置(RadioAccessNetworkConfiguration)字符串属性
    • 包含核心网IMS配置集合(List)属性
  2. 创建CoreNetworkImsConfiguration实体类

    • 包含索引(Index)整数属性
    • 包含PLMN标识(Plmn)字符串属性
    • 包含核心网配置(CoreNetworkConfiguration)字符串属性
    • 包含IMS服务配置(ImsServiceConfiguration)字符串属性
  3. 具体实现:

    /// <summary>
    /// 蜂窝网络配置实体
    /// </summary>
    public class CellularNetworkConfiguration
    {
        /// <summary>
        /// 设备代码
        /// </summary>
        public string DeviceCode { get; set; }
    
        /// <summary>
        /// 运行时代码
        /// </summary>
        public string RuntimeCode { get; set; }
    
        /// <summary>
        /// 无线接入网配置
        /// </summary>
        public string RadioAccessNetworkConfiguration { get; set; }
    
        /// <summary>
        /// 核心网IMS配置集合
        /// </summary>
        public List<CoreNetworkImsConfiguration> CoreNetworkImsConfigurations { get; set; } = new List<CoreNetworkImsConfiguration>();
    }
    
    /// <summary>
    /// 核心网IMS配置对象
    /// </summary>
    public class CoreNetworkImsConfiguration
    {
        /// <summary>
        /// 索引
        /// </summary>
        public int Index { get; set; }
    
        /// <summary>
        /// PLMN标识
        /// </summary>
        public string Plmn { get; set; }
    
        /// <summary>
        /// 核心网配置
        /// </summary>
        public string CoreNetworkConfiguration { get; set; }
    
        /// <summary>
        /// IMS服务配置
        /// </summary>
        public string ImsServiceConfiguration { get; set; }
    }
    
  4. 设计优势:

    • 命名规范:遵循C#命名约定,使用PascalCase
    • 命名清晰:类名明确表达业务含义,提高代码可读性
    • 属性专业:使用完整的专业术语,避免缩写和模糊命名
    • 类型安全:使用强类型属性,避免类型错误
    • 文档完整:每个属性都有详细的XML文档注释
    • 集合初始化:使用集合初始化器确保集合不为null
    • 职责清晰:每个类都有明确的职责和用途
    • 易于扩展:结构清晰,便于后续添加新属性
    • 业务导向:类名直接反映业务领域概念
    • 专业术语:使用标准的电信网络术语,提高代码专业性

添加蜂窝网络配置数据校验功能

修改时间: 2024年 修改文件:

  • CoreAgent.Domain/Models/Network/CellularNetworkConfiguration.cs

修改内容:

  1. 添加数据校验功能

    • DeviceCodeRuntimeCode 添加 [Required] 特性,确保不能为空
    • Plmn 添加 [Required] 特性,确保不能为空
    • 添加 ValidateConfiguration() 方法进行业务逻辑校验
  2. 业务规则校验

    • 验证 DeviceCodeRuntimeCode 不能为空
    • 验证 RadioAccessNetworkConfigurationCoreNetworkImsConfigurations 至少有一个有数据
    • 验证 CoreNetworkImsConfiguration 中的 CoreNetworkConfigurationImsServiceConfiguration 至少有一个有数据
  3. 创建ValidationResult类

    • 提供统一的验证结果返回格式
    • 支持成功和失败两种状态
    • 提供详细的错误消息
    • 支持隐式转换操作符
  4. 具体实现:

    // 必填字段校验
    [Required(ErrorMessage = "设备代码不能为空")]
    public string DeviceCode { get; set; }
    
    [Required(ErrorMessage = "运行时代码不能为空")]
    public string RuntimeCode { get; set; }
    
    // 业务逻辑校验
    public ValidationResult ValidateConfiguration()
    {
        // 验证必填字段
        if (string.IsNullOrWhiteSpace(DeviceCode))
        {
            return new ValidationResult("设备代码不能为空");
        }
    
        // 验证无线接入网配置和核心网IMS配置至少有一个有数据
        var hasRadioAccessConfig = !string.IsNullOrWhiteSpace(RadioAccessNetworkConfiguration);
        var hasCoreNetworkConfigs = CoreNetworkImsConfigurations?.Any() == true;
    
        if (!hasRadioAccessConfig && !hasCoreNetworkConfigs)
        {
            return new ValidationResult("无线接入网配置和核心网IMS配置至少需要配置其中一项");
        }
    
        return ValidationResult.Success;
    }
    
  5. 设计优势:

    • 数据完整性:确保必填字段不为空
    • 业务规则校验:验证业务逻辑的正确性
    • 统一验证接口:提供一致的验证方法
    • 详细错误信息:提供具体的错误描述
    • 分层校验:支持嵌套对象的校验
    • 易于扩展:可以轻松添加新的校验规则

影响范围:

  • 蜂窝网络配置数据模型定义
  • 核心网IMS配置管理
  • 数据实体结构标准化
  • 领域模型完整性
  • 代码可读性和维护性提升
  • 数据校验和业务规则验证
  • 错误处理和用户反馈

创建MessageTransferProtocolLog模型解决命名冲突

修改时间: 2024年 修改文件:

  • CoreAgent.WebSocketTransport/Models/MessageTransferProtocolLog.cs (新建)
  • CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs

修改内容:

  1. 创建MessageTransferProtocolLog模型

    • CoreAgent.WebSocketTransport 项目中创建新的协议日志模型
    • CoreAgent.ProtocolClient 中的 TransferProtocolLog 区分开
    • 保持相同的字段结构,避免命名冲突
    • 专门用于WebSocket传输层的协议日志数据传输
  2. 修改NetworkProtocolLogObserver转换逻辑

    • OnProtocolLogsReceived 方法中添加类型转换
    • CoreAgent.ProtocolClient.TransferProtocolLog 转换为 CoreAgent.WebSocketTransport.MessageTransferProtocolLog
    • 保持所有字段的完整映射
    • 添加必要的using语句引用
  3. 具体实现:

    // 时间跟踪和性能监控
    var startTime = DateTime.UtcNow;
    
    // 空值检查
    if (logDetails == null)
    {
        _logger.LogWarning("接收到的协议日志为空");
        return;
    }
    
    // 转换为列表以避免多次枚举
    var logList = logDetails.ToList();
    var logCount = logList.Count;
    
    // 空集合检查
    if (logCount == 0)
    {
        _logger.LogDebug("接收到的协议日志集合为空,跳过处理");
        return;
    }
    
    // 类型转换逻辑
    var webSocketLogs = logList.Select(log => new MessageTransferProtocolLog
    {
        Id = log.Id,
        LayerType = log.LayerType.ToString(),
        MessageDetailJson = log.MessageDetailJson,
        CellID = log.CellID,
        IMSI = log.IMSI,
        Direction = log.Direction,
        UEID = log.UEID,
        PLMN = log.PLMN,
        TimeMs = log.TimeMs,
        Timestamp = log.Timestamp,
        Info = log.Info,
        Message = log.Message
    });
    
    // 通道写入状态监控
    var writeSuccess = _ChannelManager.SendChannel.TryWrite(webSocketLogs);
    var processingTime = DateTime.UtcNow - startTime;
    
    if (writeSuccess)
    {
        _logger.LogDebug("协议日志处理成功,数量: {LogCount}, 处理时间: {ProcessingTime}ms", 
            logCount, processingTime.TotalMilliseconds);
    }
    else
    {
        _logger.LogWarning("协议日志写入通道失败,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 通道可能已满或已关闭", 
            logCount, processingTime.TotalMilliseconds);
    }
    
  4. 设计优势:

    • 命名清晰MessageTransferProtocolLog 明确表示用于消息传输
    • 避免冲突:与原始 TransferProtocolLog 有明确区分
    • 职责分离:WebSocket传输层有独立的协议日志模型
    • 类型安全:通过显式转换确保类型安全
    • 易于维护:清晰的命名约定便于理解和维护
    • 性能监控:添加时间跟踪和通道写入状态监控
    • 错误处理:完善的异常处理和日志记录
    • Bug修复:修复空引用检查和多次枚举的性能问题
    • 边界处理:添加空集合检查,避免处理空集合
    • 代码规范:优化ProtocolMessage模型注释,提高代码可读性

影响范围:

  • WebSocket传输层协议日志处理
  • 协议日志观察者模式实现
  • 跨项目类型转换逻辑
  • 协议消息模型注释优化

CellularNetworkService.StartNetworkAsync 方法添加协议客户端配置创建

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

修改内容:

  1. 调整执行步骤顺序

    • 将原来的第5.5步改为第6步(创建协议客户端配置)
    • 将WebSocket传输连接移到第7步(在网络配置启动之前)
    • 重新编号后续步骤(8-11步)
    • 优化执行顺序:确保WebSocket连接在网络配置启动之前完成
  2. 添加第7步WebSocket传输连接

    • StartNetworkAsync 方法的第6步(创建协议客户端配置)之后添加第7步
    • 注入 IWebSocketTransport 依赖
    • 创建独立的 StartWebSocketTransportAsync() 方法处理连接逻辑
    • 返回 bool 值表示连接是否成功
    • 添加连接状态检查和错误处理
    • 严格检查:WebSocket连接失败时立即返回失败结果,提示服务端可能未启动
  3. 修复Logger类型问题

    • 添加 ILoggerFactory 依赖注入到构造函数
    • 使用 _loggerFactory.CreateLogger<ProtocolClientConfigFactory>() 创建正确类型的Logger
    • 确保 ProtocolClientConfigFactory 获得正确的Logger实例
  4. 具体实现:

    // 6. 创建协议客户端配置
    var protocolConfigFactory = new ProtocolClientConfigFactory(_loggerFactory.CreateLogger<ProtocolClientConfigFactory>(), _context);
    var configCreated = protocolConfigFactory.CreateFromEntities();
    if (configCreated)
    {
        _logger.LogInformation("协议客户端配置创建成功,共创建 {ConfigCount} 个配置", protocolConfigFactory.ConfigCount);
    }
    else
    {
        _logger.LogWarning("协议客户端配置创建失败");
        return CellularNetworkOperationResult.Failure("协议客户端配置创建失败");
    }
    
    // 7. 启动 WebSocket 传输连接
    var webSocketConnected = await StartWebSocketTransportAsync();
    if (!webSocketConnected)
    {
        _logger.LogError("WebSocket 传输连接启动失败,服务端可能未启动");
        return CellularNetworkOperationResult.Failure("WebSocket 传输连接启动失败,服务端可能未启动");
    }
    _logger.LogInformation("WebSocket 传输连接启动成功");
    
  5. 添加必要的依赖注入

    • 添加 ILoggerFactory loggerFactory 参数到构造函数
    • 添加 IWebSocketTransport webSocketTransport 参数到构造函数
    • 添加 using CoreAgent.Infrastructure.Services.Network; 以支持 ProtocolClientConfigFactory
    • 添加 using CoreAgent.WebSocketTransport.Interfaces; 以支持 IWebSocketTransport
  6. 设计优势:

    • 在IP端点信息准备完成后立即创建协议客户端配置
    • 不依赖网络启动结果,确保配置创建的独立性
    • 在网络配置启动之前启动WebSocket传输连接
    • 提供详细的日志记录便于调试
    • 保持代码的简洁性和可维护性
    • 正确处理Logger类型,避免类型不匹配问题
    • 优化执行顺序,提高错误隔离能力
    • 完善的错误处理机制,确保配置创建失败时及时停止
    • 严格检查机制,WebSocket连接失败时立即停止网络启动流程
    • 方法职责单一,WebSocket连接逻辑独立封装

影响范围:

  • 蜂窝网络启动流程
  • 协议客户端配置管理
  • WebSocket传输服务集成
  • 网络状态监控
  • 依赖注入配置(需要更新服务注册)

CellularNetworkService构造函数添加IProtocolLogObserver依赖

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

修改内容:

  1. 添加IProtocolLogObserver依赖注入

    • 在构造函数中添加 IProtocolLogObserver protocolLogObserver 参数
    • 添加私有字段 _protocolLogObserver 存储依赖
    • 添加空值检查和异常抛出
  2. 添加必要的using语句

    • 添加 using CoreAgent.ProtocolClient.ProtocolEngineCore; 以支持 IProtocolLogObserver
  3. 具体实现:

    // 构造函数参数
    public CellularNetworkService(
        // ... 其他参数
        IWebSocketTransport webSocketTransport,
        IProtocolLogObserver protocolLogObserver)
    
    // 私有字段
    private readonly IProtocolLogObserver _protocolLogObserver;
    
    // 构造函数初始化
    _protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
    
  4. 设计优势:

    • 为后续协议客户端管理提供必要的依赖
    • 保持依赖注入的一致性
    • 提供空值检查确保服务稳定性
    • 为协议日志观察者模式提供支持

影响范围:

  • 蜂窝网络服务依赖注入配置
  • 协议客户端日志观察者集成
  • 服务注册配置更新

StartNetworkAsync方法添加时间跟踪记录

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

修改内容:

  1. 添加整体时间跟踪

    • 在方法开始时记录开始时间
    • 在方法结束时计算总耗时并记录
    • 使用UTC时间确保时间一致性
  2. 为每个步骤添加详细时间跟踪

    • 为11个步骤中的每个步骤添加开始和结束时间记录
    • 使用 LogDebug 级别记录每个步骤的耗时
    • 保持原有的 LogInformationLogError 级别日志不变
  3. 具体实现:

    // 方法开始时间跟踪
    var startTime = DateTime.UtcNow;
    _logger.LogInformation("开始启动网络配置 {ConfigKey},开始时间: {StartTime}", key, startTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
    
    // 每个步骤的时间跟踪
    var stepXStart = DateTime.UtcNow;
    _logger.LogDebug("步骤X开始:[步骤描述]");
    
    // 步骤执行逻辑...
    
    var stepXDuration = (DateTime.UtcNow - stepXStart).TotalMilliseconds;
    _logger.LogDebug("步骤X完成:[步骤描述],耗时: {Duration}ms", stepXDuration.ToString("F2"));
    
    // 方法结束时间跟踪
    var endTime = DateTime.UtcNow;
    var duration = endTime - startTime;
    _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status},总耗时: {Duration}ms", 
        key, state.CurrentStatus, duration.TotalMilliseconds.ToString("F2"));
    
  4. 设计优势:

    • 性能监控:可以识别网络启动过程中的性能瓶颈
    • 调试支持:详细的时间信息有助于问题定位和性能优化
    • 日志分级:使用Debug级别避免生产环境日志过多
    • 时间精度:使用毫秒级精度提供准确的性能数据
    • UTC时间:确保时间记录的一致性和准确性
    • 非侵入性:不影响原有的业务逻辑和错误处理
  5. 跟踪的步骤:

    • 步骤1:获取并验证网络配置
    • 步骤2:执行网络接口初始化命令
    • 步骤3:复制配置值到临时目录
    • 步骤4:获取并验证 IP 端点信息
    • 步骤5:更新 IP 端点管理器
    • 步骤6:创建协议客户端配置
    • 步骤7:启动 WebSocket 传输连接
    • 步骤8:启动网络配置
    • 步骤9:更新网络配置类型
    • 步骤10:检查网络端点连接状态
    • 步骤11:更新网络状态

影响范围:

  • 网络启动性能监控
  • 调试和问题定位
  • 日志记录详细程度
  • 性能优化分析

ProtocolWsClientManager方法参数优化

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs

修改内容:

  1. 简化构造函数

    • 移除 ProtocolClientConfig[] configs 参数
    • 构造函数只保留必要的依赖:ILoggerIProtocolLogObserverILoggerFactory
    • 移除私有字段 _configs,不再在构造函数中存储配置
  2. 修改StartAllClients方法签名

    • 添加 ProtocolClientConfig[] configs 参数
    • 方法接收配置数组作为参数,而不是依赖构造函数中的配置
    • 添加参数验证,检查 configs 是否为 null 或空数组
  3. 优化方法逻辑

    • 将配置验证移到方法开始处
    • 使用传入的 configs 参数替代私有字段
    • 保持原有的客户端创建和启动逻辑不变
  4. 具体实现:

    // 构造函数简化
    public ProtocolWsClientManager(
        ILogger<ProtocolWsClientManager> logger,
        IProtocolLogObserver protocolLogObserver,
        ILoggerFactory loggerFactory)  // 移除 configs 参数
    
    // StartAllClients方法修改
    public void StartAllClients(ProtocolClientConfig[] configs)  // 添加参数
    {
        if (configs == null || configs.Length == 0)  // 参数验证
        {
            _logger.LogWarning("没有可用的协议客户端配置");
            return;
        }
    
        // 使用传入的 configs 参数
        _logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", configs.Length);
        foreach (var config in configs)  // 遍历传入的配置
    
  5. 设计优势:

    • 更灵活的使用方式:可以在不同时间传入不同的配置
    • 减少内存占用:不需要在构造函数中存储配置数组
    • 简化构造函数:降低构造函数的复杂度
    • 更好的测试性:可以更容易地测试不同的配置组合
    • 符合单一职责原则:构造函数只负责初始化,方法负责执行具体操作

影响范围:

  • 协议客户端管理器使用方式
  • 配置传递方式
  • 调用方代码适配
  • 测试用例更新

ProtocolWsClientManager采用面向接口编程

修改时间: 2024年 修改文件:

  • CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs (新建)
  • CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs

修改内容:

  1. 创建IProtocolWsClientManager接口

    • 在CoreAgent.ProtocolClient项目中定义接口契约
    • 继承 IDisposable 接口
    • 定义 StartAllClientsStopAllClients 方法
    • 使用 ProtocolClientConfig[] 作为参数类型
  2. 修改ProtocolWsClientManager实现类

    • 实现 IProtocolWsClientManager 接口
    • 添加 using CoreAgent.ProtocolClient.Interfaces; 引用
    • 保持原有的实现逻辑不变
  3. 具体实现:

    // 接口定义
    public interface IProtocolWsClientManager : IDisposable
    {
        void StartAllClients(ProtocolClientConfig[] configs);
        void StopAllClients();
    }
    
    // 实现类
    public class ProtocolWsClientManager : IProtocolWsClientManager
    {
        // 原有实现保持不变
    }
    
  4. 设计优势:

    • 依赖倒置:高层模块依赖抽象,不依赖具体实现
    • 易于测试:可以轻松创建Mock实现进行单元测试
    • 松耦合:降低组件间的耦合度
    • 可扩展性:可以轻松添加新的实现类
    • 符合SOLID原则:遵循依赖倒置原则和开闭原则
    • 便于依赖注入:可以注册接口而不是具体实现
  5. 接口设计原则:

    • 单一职责:接口只定义协议客户端管理的核心功能
    • 简洁明了:只包含必要的方法定义
    • 易于理解:方法名称和参数清晰明确
    • 向后兼容:保持与原有API的兼容性

影响范围:

  • 依赖注入配置更新
  • 服务注册方式调整
  • 单元测试Mock创建
  • 调用方代码适配(使用接口类型)
  • 项目引用关系调整(CoreAgent.ProtocolClient项目包含接口定义)

CellularNetworkService集成IProtocolWsClientManager

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs

修改内容:

  1. 添加IProtocolWsClientManager依赖注入

    • 在构造函数中添加 IProtocolWsClientManager protocolWsClientManager 参数
    • 添加私有字段 _protocolWsClientManager 存储依赖
    • 添加空值检查和异常抛出
  2. StartNetworkAsync方法添加第12步

    • 在步骤11(更新网络状态)之后添加第12步
    • 调用 protocolConfigFactory.GetAllConfigs() 获取配置数组
    • 调用 _protocolWsClientManager.StartAllClients(protocolConfigs) 启动所有协议客户端
    • 添加时间跟踪和错误处理
    • 如果启动失败,立即返回失败结果
  3. StopAsync方法集成协议客户端停止

    • 在步骤4(禁用网络配置)之后添加步骤5(停止所有协议客户端)
    • 调用 _protocolWsClientManager.StopAllClients() 停止所有协议客户端
    • 添加错误处理,但不中断停止流程
    • 重新编号后续步骤(6-9步)
  4. 修复StopWebSocketTransportAsync方法

    • 修正方法实现,使用 CloseAsync() 而不是 DisconnectAsync()
    • 修正日志信息和返回值逻辑
    • 确保方法名称和实现一致
  5. 具体实现:

    // 构造函数添加依赖
    public CellularNetworkService(
        // ... 其他参数
        IProtocolWsClientManager protocolWsClientManager)
    
    // StartNetworkAsync第12步
    // 12. 启动所有协议客户端
    var protocolConfigs = protocolConfigFactory.GetAllConfigs();
    _protocolWsClientManager.StartAllClients(protocolConfigs);
    
    // StopAsync步骤5
    // 5. 停止所有协议客户端
    _protocolWsClientManager.StopAllClients();
    
  6. 设计优势:

    • 完整的生命周期管理:启动和停止时都正确处理协议客户端
    • 错误隔离:启动失败时立即停止,停止失败时继续执行
    • 时间跟踪:为协议客户端操作添加详细的时间记录
    • 依赖注入:使用接口编程,便于测试和扩展
    • 日志完整:提供详细的启动和停止日志记录

影响范围:

  • 蜂窝网络服务依赖注入配置
  • 协议客户端生命周期管理
  • 网络启动和停止流程
  • 服务注册配置更新

LogLayerHelp类名规范化

修改时间: 2024年 修改文件:

  • `

ProtocolWsClientManager方法返回类型优化

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
  • CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs

修改内容:

  1. StartAllClients方法返回类型修改

    • 将返回类型从 void 改为 bool
    • 添加连接状态检查逻辑,使用 client.IsConnected 判断连接状态
    • 统计已连接的客户端数量
    • 返回 bool 值表示是否所有客户端都成功启动并连接
    • 添加详细的日志记录,包括连接状态信息
  2. StopAllClients方法返回类型修改

    • 将返回类型从 void 改为 bool
    • 添加断开连接状态检查逻辑,使用 client.IsConnected 判断连接状态
    • 记录停止前的连接状态和停止后的连接状态
    • 统计已断开连接的客户端数量
    • 返回 bool 值表示是否所有客户端都成功停止并断开连接
    • 添加详细的日志记录,包括连接状态变化信息
  3. GetAllClientsStatus方法修复

    • 修复语法错误,完善方法实现
    • 添加线程安全锁保护
    • 遍历所有客户端并记录其状态信息
    • 包括客户端名称、连接状态(IsConnected)和客户端状态(State)
    • 添加空客户端检查
  4. 接口定义更新

    • 更新 IProtocolWsClientManager 接口中的方法签名
    • StartAllClients 方法返回 bool 类型
    • StopAllClients 方法返回 bool 类型
    • 添加详细的XML文档注释说明返回值含义
  5. 具体实现:

    // StartAllClients方法
    public bool StartAllClients(ProtocolClientConfig[] configs)
    {
        // 检查连接状态
        if (existingClient.IsConnected)
        {
            connectedCount++;
        }
    
        var allConnected = connectedCount == configs.Length;
        return allConnected;
    }
    
    // StopAllClients方法
    public bool StopAllClients()
    {
        var client = kvp.Value;
        var wasConnected = client.IsConnected;
    
        client.Stop();
    
        // 检查连接状态
        if (!client.IsConnected)
        {
            disconnectedCount++;
        }
    
        var allDisconnected = disconnectedCount == _clients.Count;
        return allDisconnected;
    }
    
    // GetAllClientsStatus方法
    public void GetAllClientsStatus() 
    {
        foreach (var kvp in _clients)
        {
            var client = kvp.Value;
            _logger.LogInformation("客户端状态 - 名称: {ClientName}, 连接状态: {IsConnected}, 客户端状态: {State}", 
                kvp.Key, client.IsConnected, client.State);
        }
    }
    
  6. 设计优势:

    • 状态可追踪:通过返回值可以明确知道操作是否完全成功
    • 连接状态监控:使用 IsConnected 属性准确判断连接状态
    • 详细日志记录:提供完整的操作过程和状态变化日志
    • 线程安全:使用锁保护共享资源访问
    • 错误处理完善:提供详细的错误信息和状态统计
    • 接口一致性:接口和实现保持完全一致
    • 向后兼容:保持方法签名的一致性,只改变返回类型
  7. 返回值含义:

    • StartAllClients 返回 true:所有客户端都成功启动并连接
    • StartAllClients 返回 false:部分或全部客户端启动失败或未连接
    • StopAllClients 返回 true:所有客户端都成功停止并断开连接
    • StopAllClients 返回 false:部分或全部客户端停止失败或仍保持连接

影响范围:

  • 协议客户端管理器接口契约
  • 调用方代码需要处理返回值
  • 网络启动和停止流程的状态判断
  • 日志记录详细程度提升
  • 错误处理和状态监控能力增强

WebSocket传输服务依赖注入修复

修改时间: 2024年 修改文件:

  • CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs
  • CoreAgent.API/Startup.cs

修改内容:

  1. 修复依赖注入顺序问题

    • RegisterDefaultMiddleware 移到 RegisterCoreServices 之前调用
    • 确保中间件在核心服务注册之前就已经注册到容器中
    • 解决 provider.GetServices<IMessageMiddleware>() 无法找到服务的问题
  2. 修复CacheMiddleware注册方式

    • CacheMiddleware 的注册方式从手动工厂方法改为使用 AddWebSocketMiddleware<T>
    • 简化注册逻辑,确保依赖注入容器能正确处理构造函数参数
    • 移除复杂的工厂方法注册,使用标准的依赖注入模式
  3. 添加IMemoryCache服务注册

    • Startup.csConfigureServices 方法中添加 services.AddMemoryCache()
    • 确保 CacheMiddleware 能够正确获取 IMemoryCache 依赖
    • 在 WebSocket 传输服务注册之前添加内存缓存服务
  4. 具体实现:

    // WebSocketTransportExtensions.cs - 调整注册顺序
    public static IServiceCollection AddWebSocketTransport(...)
    {
        // 注册配置
        services.Configure<WebSocketConfig>(...);
    
        // 注册默认中间件(在核心服务之前)
        RegisterDefaultMiddleware(services);
    
        // 注册核心服务
        RegisterCoreServices(services);
    
        return services;
    }
    
    // Startup.cs - 添加内存缓存服务
    public void ConfigureServices(IServiceCollection services)
    {
        // ... 其他服务注册 ...
    
        // 添加内存缓存服务(WebSocket中间件需要)
        services.AddMemoryCache();
    
        // 添加 WebSocket 传输服务
        services.AddWebSocketTransport(Configuration, "WebSocket");
    }
    
  5. 设计优势:

    • 依赖顺序正确:确保中间件在核心服务之前注册
    • 简化注册逻辑:使用标准的依赖注入模式
    • 完整的服务注册:包含所有必要的依赖服务
    • 错误预防:避免运行时依赖注入异常
    • 代码清晰:注册逻辑更加直观和易于理解
  6. 修复的问题:

    • System.InvalidOperationException: Cannot resolve scoped service 'System.Collections.Generic.IEnumerable1[CoreAgent.WebSocketTransport.Middleware.IMessageMiddleware]' from root provider`
    • 依赖注入容器无法找到 IMessageMiddleware 服务
    • CacheMiddleware 无法获取 IMemoryCache 依赖

影响范围:

  • WebSocket传输服务的依赖注入配置
  • 中间件注册和初始化顺序
  • 应用程序启动时的服务注册
  • 内存缓存服务的可用性
  • 错误处理和异常预防

CacheMiddleware构造函数依赖注入修复

修改时间: 2024年 修改文件:

  • CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs

修改内容:

  1. 修复构造函数参数类型

    • 将构造函数参数从 WebSocketConfig config 改为 IOptions<WebSocketConfig> config
    • 添加 using Microsoft.Extensions.Options; 引用
    • 在构造函数中通过 config?.Value 获取配置值
  2. 增强空值检查

    • 为所有构造函数参数添加空值检查和异常抛出
    • 使用 ArgumentNullException 确保参数有效性
    • 提供更明确的错误信息
  3. 具体实现:

    // 修复前
    public CacheMiddleware(IMemoryCache cache, ILogger<CacheMiddleware> logger, WebSocketConfig config)
    {
        _cache = cache;
        _logger = logger;
        _config = config;
    }
    
    // 修复后
    public CacheMiddleware(IMemoryCache cache, ILogger<CacheMiddleware> logger, IOptions<WebSocketConfig> config)
    {
        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _config = config?.Value ?? throw new ArgumentNullException(nameof(config));
    }
    
  4. 设计优势:

    • 正确的依赖注入模式:使用 IOptions<T> 模式获取配置
    • 强化的错误处理:提供详细的空值检查和异常信息
    • 类型安全:确保配置对象正确获取
    • 符合最佳实践:遵循 .NET 依赖注入的标准模式
  5. 修复的问题:

    • Unable to resolve service for type 'CoreAgent.WebSocketTransport.Models.WebSocketConfig'
    • 依赖注入容器无法直接解析 WebSocketConfig 类型
    • 中间件构造函数参数类型不匹配

影响范围:

  • CacheMiddleware的依赖注入配置
  • WebSocket传输服务的启动
  • 配置对象的正确获取
  • 错误处理和异常预防

WebSocket中间件生命周期修复

修改时间: 2024年 修改文件:

  • CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs

修改内容:

  1. 修复生命周期不匹配问题

    • 将中间件注册从 AddScoped 改为 AddTransient
    • 解决单例服务无法解析作用域服务的问题
    • 确保中间件每次使用都创建新实例
  2. 生命周期分析

    • IWebSocketTransport 注册为 Singleton(单例)
    • 中间件注册为 Transient(瞬时)
    • 单例服务可以安全地解析瞬时服务
    • 每次获取中间件都会创建新实例
  3. 具体实现:

    // 修复前
    services.AddScoped<IMessageMiddleware, T>();
    
    // 修复后
    services.AddTransient<IMessageMiddleware, T>();
    
  4. 设计优势:

    • 生命周期兼容:瞬时服务可以被单例服务安全解析
    • 性能优化:中间件每次使用都是新实例,避免状态污染
    • 线程安全:瞬时服务天然线程安全
    • 内存管理:中间件使用完毕后自动释放
  5. 修复的问题:

    • Cannot resolve scoped service 'System.Collections.Generic.IEnumerable1[CoreAgent.WebSocketTransport.Middleware.IMessageMiddleware]' from root provider`
    • 单例服务无法解析作用域服务的依赖注入异常
    • 生命周期不匹配导致的运行时错误
  6. 生命周期说明:

    • Singleton: 整个应用程序生命周期内只有一个实例
    • Scoped: 每个请求作用域内有一个实例
    • Transient: 每次请求都创建新实例
    • 单例服务只能解析瞬时服务,不能解析作用域服务

影响范围:

  • WebSocket中间件的生命周期管理
  • 依赖注入容器的服务解析
  • 应用程序启动时的服务注册
  • 中间件的实例化策略
  • 性能和内存使用优化

NetworkConfigCopier方法Bug修复和日志增强

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
  • CoreAgent.Domain/Models/Network/NetworkConfigCopyResult.cs
  • CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs

修改内容:

  1. 返回类型统一化

    • 统一返回类型:所有方法都返回 NetworkConfigCopyResult 类型,不再抛出异常
    • 泛型结果类型:创建 NetworkConfigCopyResult<T> 泛型类,支持返回数据
    • 接口更新:更新 INetworkConfigCopier 接口以匹配新的返回类型
    • 错误处理改进:使用结果对象而不是异常来处理错误情况
  2. CreateCellularNetworkConfigurationFile方法修复

    • 返回类型修改:从 Task<NetworkConfiguration> 改为 Task<NetworkConfigCopyResult>
    • 路径构建Bug修复:修复 Path.Combine 使用不当的问题,正确构建文件路径
    • 参数验证增强:添加完整的参数空值检查,返回失败结果而不是抛出异常
    • 目录创建:确保目标目录存在,避免文件写入失败
    • 详细日志:添加每个步骤的详细日志记录,包括开始、成功、警告和错误信息
  3. CreateRadioAccessNetworkConfigurationFile方法修复

    • 返回类型修改:从 Task<bool> 改为 Task<NetworkConfigCopyResult>
    • 参数命名规范化:使用小写开头的参数名,符合C#命名约定
    • 目录创建逻辑:添加目录存在性检查和自动创建
    • 错误处理增强:返回失败结果而不是抛出异常
    • 参数验证:验证文件路径和配置内容不为空
  4. CreateCoreNetworkImsConfigurationFiles方法重构

    • 返回类型修改:从 Task<List<CoreImsConfig>> 改为 Task<NetworkConfigCopyResult<List<CoreImsConfig>>>
    • 方法重命名:避免与RAN配置文件创建方法名冲突
    • 参数验证完善:验证RuntimeCode、配置列表和AppSettings
    • 配置项验证:验证每个配置项的PLMN和配置内容
    • 目录创建:为CN和IMS配置文件分别创建目录
    • 错误隔离:单个配置项失败不影响其他配置项处理
    • 详细日志:记录每个配置项的处理过程和结果
  5. DeleteCellularNetworkConfigurationFile方法增强

    • 返回类型修改:从 bool 改为 NetworkConfigCopyResult
    • 文件存在性检查:删除前检查文件是否存在,避免异常
    • 错误隔离:单个文件删除失败不影响其他文件删除
    • 删除统计:统计成功删除的文件数量
    • 详细日志:记录每个文件的删除状态和结果
    • 参数验证:验证NetworkConfiguration参数不为空
  6. NetworkConfigCopyResult类扩展

    • 泛型支持:添加 NetworkConfigCopyResult<T> 泛型类
    • 数据返回:支持返回操作结果的同时返回数据
    • 继承关系:泛型类继承自基础类,保持类型安全
    • 静态工厂方法:提供 Success(T data)Failure(string errorMessage) 方法
  7. 具体修复的Bug:

    // 修复前 - 路径构建错误
    string RanConfigPath = $"{appSettings.RanConfigDirectory}{Path.Combine("RAN", $"{cellular.RuntimeCode}.cfg")}";
    
    // 修复后 - 正确的路径构建
    string ranConfigPath = Path.Combine(appSettings.RanConfigDirectory, "RAN", $"{cellular.RuntimeCode}.cfg");
    
    // 修复前 - 抛出异常
    throw new ArgumentNullException(nameof(cellular));
    
    // 修复后 - 返回失败结果
    return NetworkConfigCopyResult.Failure("CellularNetworkConfiguration 参数为空");
    
    // 修复前 - 返回原始类型
    public async Task<NetworkConfiguration> CreateCellularNetworkConfigurationFile(...)
    
    // 修复后 - 返回结果类型
    public async Task<NetworkConfigCopyResult> CreateCellularNetworkConfigurationFile(...)
    
  8. 设计优势:

    • 统一错误处理:所有方法都使用结果对象,避免异常传播
    • 类型安全:泛型结果类型确保类型安全
    • Bug修复:修复路径构建、方法名冲突、文件删除等关键Bug
    • 错误处理完善:添加完整的错误处理和错误隔离机制
    • 日志详细:提供完整的操作跟踪和调试信息
    • 参数验证:确保所有输入参数的有效性
    • 目录管理:自动创建必要的目录结构
    • 错误隔离:单个操作失败不影响整体流程
    • 命名规范:遵循C#命名约定,提高代码可读性
    • 方法职责清晰:每个方法都有明确的职责和边界
  9. 修复的关键问题:

    • 异常处理不一致:统一使用结果对象而不是异常
    • 路径构建错误Path.Combine 使用不当导致路径错误
    • 方法名冲突:两个不同功能的方法使用相同名称
    • 文件删除异常:删除不存在的文件导致异常
    • 目录不存在:目标目录不存在导致文件写入失败
    • 错误传播:单个错误导致整个操作失败
    • 日志缺失:缺少关键操作的日志记录

影响范围:

  • 网络配置文件创建和删除的稳定性
  • 错误处理和异常预防
  • 日志记录和调试能力
  • 代码可读性和维护性
  • 文件系统操作的可靠性
  • 配置管理的完整性
  • 接口契约的一致性
  • 调用方代码的错误处理方式

NetworkConfigCopier返回类型优化和GeneralCellularNetworkService适配

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
  • CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs
  • CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs

修改内容:

  1. CreateCellularNetworkConfigurationFile返回类型优化

    • 返回类型修改:从 Task<NetworkConfigCopyResult> 改为 Task<NetworkConfigCopyResult<NetworkConfiguration>>
    • 数据返回:成功时返回包含 NetworkConfiguration 对象的结果
    • 接口更新:更新接口定义以匹配新的返回类型
    • 调用方适配:修改调用方代码以正确使用返回的数据
  2. GeneralCellularNetworkService调用修复

    • 返回类型适配:修改调用方式以适配新的泛型返回类型
    • 数据获取:直接从结果对象的 Data 属性获取 NetworkConfiguration
    • 错误处理改进:使用 IsSuccess 属性检查操作是否成功
    • 代码简化:移除手动创建 NetworkConfiguration 的代码
  3. 接口定义更新

    • 泛型支持:接口方法返回 Task<NetworkConfigCopyResult<NetworkConfiguration>>
    • 文档更新:更新XML文档注释说明返回的数据类型
  4. 具体修改:

    // NetworkConfigCopier.cs - 返回类型修改
    // 修复前
    public async Task<NetworkConfigCopyResult> CreateCellularNetworkConfigurationFile(...)
    {
        // ... 创建NetworkConfiguration对象
        return NetworkConfigCopyResult.Success(); // 没有返回数据
    }
    
    // 修复后
    public async Task<NetworkConfigCopyResult<NetworkConfiguration>> CreateCellularNetworkConfigurationFile(...)
    {
        // ... 创建NetworkConfiguration对象
        return NetworkConfigCopyResult<NetworkConfiguration>.Success(network); // 返回数据
    }
    
    // GeneralCellularNetworkService.cs - 调用修复
    // 修复前 - 手动创建配置对象
    var createResult = await _configCopier.CreateCellularNetworkConfigurationFile(cellular, _context.GetAppSettings());
    if (!createResult.IsSuccess)
    {
        return CellularNetworkOperationResult.Failure($"创建网络配置文件失败: {createResult.ErrorMessage}");
    }
    
    var config = NetworkConfiguration.Create(cellular.RuntimeCode, 
        Path.Combine(_context.GetAppSettings().RanConfigDirectory, "RAN", $"{cellular.RuntimeCode}.cfg"), 
        new List<CoreImsConfig>());
    
    // 修复后 - 直接使用返回的数据
    var createResult = await _configCopier.CreateCellularNetworkConfigurationFile(cellular, _context.GetAppSettings());
    if (!createResult.IsSuccess)
    {
        return CellularNetworkOperationResult.Failure($"创建网络配置文件失败: {createResult.ErrorMessage}");
    }
    
    var config = createResult.Data; // 直接获取返回的NetworkConfiguration对象
    
  5. 设计优势:

    • 数据完整性:返回完整的 NetworkConfiguration 对象,包含所有配置信息
    • 类型安全:泛型结果类型确保类型安全
    • 代码简化:调用方无需手动创建配置对象
    • 错误处理统一:保持统一的错误处理模式
    • 接口一致性:接口和实现保持完全一致
  6. 修复的关键问题:

    • 数据丢失:原方法创建了 NetworkConfiguration 但没有返回
    • 代码重复:调用方需要手动创建配置对象
    • 类型不匹配:返回类型与实际需求不匹配
    • 接口不一致:接口定义与实际实现不一致

影响范围:

  • 网络配置创建流程的数据完整性
  • 调用方代码的简化
  • 接口契约的一致性
  • 类型安全和错误处理

修改CreateCellularNetworkConfigurationFile为元组返回

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs
  • CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs
  • CoreAgent.Infrastructure/Services/Network/GeneralCellularNetworkService.cs

修改内容:

  1. 修改CreateCellularNetworkConfigurationFile返回类型

    • 将返回类型从 Task<NetworkConfigCopyResult<NetworkConfiguration>> 改为元组 Task<(bool IsSuccess, string ErrorMessage, NetworkConfiguration NetworkConfiguration)>
    • 简化返回结构,直接返回三个值:是否成功、错误信息、网络配置对象
  2. 更新接口定义

    • 更新 INetworkConfigCopier 接口中的方法签名
    • 更新XML文档注释说明新的返回类型
  3. 更新调用代码

    • 修改 GeneralCellularNetworkService.cs 中的调用逻辑
    • 使用元组解构语法 var (isSuccess, errorMessage, config) = await ...
    • 直接使用解构后的变量
  4. 具体实现:

    // 修改前
    public async Task<NetworkConfigCopyResult<NetworkConfiguration>> CreateCellularNetworkConfigurationFile(...)
    {
        return NetworkConfigCopyResult<NetworkConfiguration>.Failure("错误信息");
        return NetworkConfigCopyResult<NetworkConfiguration>.Success(network);
    }
    
    // 修改后
    public async Task<(bool IsSuccess, string ErrorMessage, NetworkConfiguration NetworkConfiguration)> CreateCellularNetworkConfigurationFile(...)
    {
        return (false, "错误信息", null);
        return (true, null, network);
    }
    
  5. 调用代码修改:

    // 修改前
    var createResult = await _configCopier.CreateCellularNetworkConfigurationFile(cellular, _context.GetAppSettings());
    if (!createResult.IsSuccess)
    {
        return CellularNetworkOperationResult.Failure($"创建网络配置文件失败: {createResult.ErrorMessage}");
    }
    var config = createResult.Data;
    
    // 修改后
    var (isSuccess, errorMessage, config) = await _configCopier.CreateCellularNetworkConfigurationFile(cellular, _context.GetAppSettings());
    if (!isSuccess)
    {
        return CellularNetworkOperationResult.Failure($"创建网络配置文件失败: {errorMessage}");
    }
    
  6. 设计优势:

    • 简洁性:元组返回比包装类更简洁
    • 直观性:直接返回三个值,语义更清晰
    • 性能:避免创建额外的包装对象
    • 易用性:使用元组解构语法,代码更简洁
    • 类型安全:保持强类型,编译时检查

影响范围:

  • 网络配置创建方法的返回类型简化
  • 调用代码的简化
  • 接口定义的更新
  • 代码可读性的提升

修改CreateCoreNetworkImsConfigurationFiles为元组返回

修改时间: 2024年 修改文件:

  • CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs

修改内容:

  1. 修改CreateCoreNetworkImsConfigurationFiles返回类型

    • 将返回类型从 Task<NetworkConfigCopyResult<List<CoreImsConfig>>> 改为元组 Task<(bool IsSuccess, string ErrorMessage, List<CoreImsConfig> CoreImsConfigs)>
    • 简化返回结构,直接返回三个值:是否成功、错误信息、核心IMS配置列表
  2. 更新调用代码

    • 修改 CreateCellularNetworkConfigurationFile 方法中对 CreateCoreNetworkImsConfigurationFiles 的调用
    • 使用元组解构语法 var (coreImsSuccess, coreImsError, coreImsConfigs) = await ...
    • 直接使用解构后的变量
  3. 具体实现:

    // 修改前
    public async Task<NetworkConfigCopyResult<List<CoreImsConfig>>> CreateCoreNetworkImsConfigurationFiles(...)
    {
        return NetworkConfigCopyResult<List<CoreImsConfig>>.Failure("错误信息");
        return NetworkConfigCopyResult<List<CoreImsConfig>>.Success(list);
    }
    
    // 修改后
    public async Task<(bool IsSuccess, string ErrorMessage, List<CoreImsConfig> CoreImsConfigs)> CreateCoreNetworkImsConfigurationFiles(...)
    {
        return (false, "错误信息", null);
        return (true, null, list);
    }
    
  4. 调用代码修改:

    // 修改前
    var coreImsResult = await CreateCoreNetworkImsConfigurationFiles(cellular.RuntimeCode, cellular.CoreNetworkImsConfigurations, appSettings);
    if (!coreImsResult.IsSuccess)
    {
        return (false, $"创建核心网络和IMS配置文件失败: {coreImsResult.ErrorMessage}", null);
    }
    list = coreImsResult.Data;
    
    // 修改后
    var (coreImsSuccess, coreImsError, coreImsConfigs) = await CreateCoreNetworkImsConfigurationFiles(cellular.RuntimeCode, cellular.CoreNetworkImsConfigurations, appSettings);
    if (!coreImsSuccess)
    {
        return (false, $"创建核心网络和IMS配置文件失败: {coreImsError}", null);
    }
    list = coreImsConfigs;
    
  5. 设计优势:

    • 一致性:与 CreateCellularNetworkConfigurationFile 方法保持相同的返回模式
    • 简洁性:元组返回比包装类更简洁
    • 直观性:直接返回三个值,语义更清晰
    • 性能:避免创建额外的包装对象
    • 易用性:使用元组解构语法,代码更简洁
  6. 接口说明:

    • CreateCoreNetworkImsConfigurationFiles 是内部方法,不在接口中定义
    • 只在 NetworkConfigCopier 实现类中使用
    • 保持接口的简洁性

影响范围:

  • 核心网络和IMS配置文件创建方法的返回类型简化
  • 内部方法调用代码的简化
  • 代码一致性的提升
  • 性能的优化