diff --git a/CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs b/CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs index 941a5d9..6d19886 100644 --- a/CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs +++ b/CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs @@ -59,7 +59,7 @@ namespace CoreAgent.WebSocketTransport.Extensions if (services == null) throw new ArgumentNullException(nameof(services)); - services.AddScoped(); + services.AddTransient(); return services; } diff --git a/CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs b/CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs index 33b2826..af453b1 100644 --- a/CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs +++ b/CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using CoreAgent.WebSocketTransport.Models; namespace CoreAgent.WebSocketTransport.Middleware; @@ -15,11 +16,11 @@ public class CacheMiddleware : IMessageMiddleware private readonly WebSocketConfig _config; private static readonly string[] _cacheablePrefixes = { "CONFIG_", "SETTINGS_" }; - public CacheMiddleware(IMemoryCache cache, ILogger logger, WebSocketConfig config) + public CacheMiddleware(IMemoryCache cache, ILogger logger, IOptions config) { - _cache = cache; - _logger = logger; - _config = config; + _cache = cache ?? throw new ArgumentNullException(nameof(cache)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _config = config?.Value ?? throw new ArgumentNullException(nameof(config)); } /// diff --git a/modify.md b/modify.md index 52772a9..db6d721 100644 --- a/modify.md +++ b/modify.md @@ -545,4 +545,110 @@ - 中间件注册和初始化顺序 - 应用程序启动时的服务注册 - 内存缓存服务的可用性 -- 错误处理和异常预防 \ No newline at end of file +- 错误处理和异常预防 + +### CacheMiddleware构造函数依赖注入修复 + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.WebSocketTransport/Middleware/CacheMiddleware.cs` + +**修改内容**: + +1. **修复构造函数参数类型** + - 将构造函数参数从 `WebSocketConfig config` 改为 `IOptions config` + - 添加 `using Microsoft.Extensions.Options;` 引用 + - 在构造函数中通过 `config?.Value` 获取配置值 + +2. **增强空值检查** + - 为所有构造函数参数添加空值检查和异常抛出 + - 使用 `ArgumentNullException` 确保参数有效性 + - 提供更明确的错误信息 + +3. **具体实现**: + ```csharp + // 修复前 + public CacheMiddleware(IMemoryCache cache, ILogger logger, WebSocketConfig config) + { + _cache = cache; + _logger = logger; + _config = config; + } + + // 修复后 + public CacheMiddleware(IMemoryCache cache, ILogger logger, IOptions 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` 模式获取配置 + - **强化的错误处理**:提供详细的空值检查和异常信息 + - **类型安全**:确保配置对象正确获取 + - **符合最佳实践**:遵循 .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. **具体实现**: + ```csharp + // 修复前 + services.AddScoped(); + + // 修复后 + services.AddTransient(); + ``` + +4. **设计优势**: + - **生命周期兼容**:瞬时服务可以被单例服务安全解析 + - **性能优化**:中间件每次使用都是新实例,避免状态污染 + - **线程安全**:瞬时服务天然线程安全 + - **内存管理**:中间件使用完毕后自动释放 + +5. **修复的问题**: + - `Cannot resolve scoped service 'System.Collections.Generic.IEnumerable`1[CoreAgent.WebSocketTransport.Middleware.IMessageMiddleware]' from root provider` + - 单例服务无法解析作用域服务的依赖注入异常 + - 生命周期不匹配导致的运行时错误 + +6. **生命周期说明**: + - **Singleton**: 整个应用程序生命周期内只有一个实例 + - **Scoped**: 每个请求作用域内有一个实例 + - **Transient**: 每次请求都创建新实例 + - 单例服务只能解析瞬时服务,不能解析作用域服务 + +**影响范围**: +- WebSocket中间件的生命周期管理 +- 依赖注入容器的服务解析 +- 应用程序启动时的服务注册 +- 中间件的实例化策略 +- 性能和内存使用优化 \ No newline at end of file