Browse Source

"修复WebSocket传输服务依赖注入问题,添加IMemoryCache服务注册"

feature/protocol-log-Perfect
hyh 1 week ago
parent
commit
55c16b6bbe
  1. 3
      CoreAgent.API/Startup.cs
  2. 198
      CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs
  3. 75
      modify.md

3
CoreAgent.API/Startup.cs

@ -43,6 +43,9 @@ namespace CoreAgent.API
// 添加网络命令配置
services.Configure<NetworkCommandConfig>(Configuration.GetSection("networkCommand"));
// 添加内存缓存服务(WebSocket中间件需要)
services.AddMemoryCache();
// 添加 WebSocket 传输服务
services.AddWebSocketTransport(Configuration, "WebSocket");
}

198
CoreAgent.WebSocketTransport/Extensions/WebSocketTransportExtensions.cs

@ -2,129 +2,121 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Caching.Memory;
using CoreAgent.WebSocketTransport.Interfaces;
using CoreAgent.WebSocketTransport.Models;
using CoreAgent.WebSocketTransport.Services;
using CoreAgent.WebSocketTransport.Middleware;
using Microsoft.Extensions.Caching.Memory;
namespace CoreAgent.WebSocketTransport.Extensions;
using CoreAgent.WebSocketTransport.Models;
/// <summary>
/// WebSocket 传输服务注册扩展
/// 遵循依赖注入原则,注册所有组件
/// </summary>
public static class WebSocketTransportExtensions
namespace CoreAgent.WebSocketTransport.Extensions
{
/// <summary>
/// 添加 WebSocket 传输服务
/// WebSocket 传输服务扩展
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="configuration">配置</param>
/// <param name="configSection">配置节名称</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddWebSocketTransport(
this IServiceCollection services,
IConfiguration configuration,
string configSection = "WebSocket")
public static class WebSocketTransportExtensions
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));
// 注册配置
services.Configure<WebSocketConfig>(options =>
/// <summary>
/// 添加 WebSocket 传输服务
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="configuration">配置</param>
/// <param name="configSection">配置节名称</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddWebSocketTransport(
this IServiceCollection services,
IConfiguration configuration,
string configSection = "WebSocket")
{
configuration.GetSection(configSection).Bind(options);
});
if (services == null)
throw new ArgumentNullException(nameof(services));
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));
// 注册核心服务
RegisterCoreServices(services);
// 注册默认中间件
RegisterDefaultMiddleware(services);
return services;
}
// 注册配置
services.Configure<WebSocketConfig>(options =>
{
configuration.GetSection(configSection).Bind(options);
});
// 注册默认中间件(在核心服务之前)
RegisterDefaultMiddleware(services);
// 注册核心服务
RegisterCoreServices(services);
/// <summary>
/// 添加 WebSocket 中间件
/// </summary>
/// <typeparam name="T">中间件类型</typeparam>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddWebSocketMiddleware<T>(this IServiceCollection services)
where T : class, IMessageMiddleware
{
if (services == null)
throw new ArgumentNullException(nameof(services));
return services;
}
services.AddScoped<IMessageMiddleware, T>();
return services;
}
/// <summary>
/// 添加 WebSocket 中间件
/// </summary>
/// <typeparam name="T">中间件类型</typeparam>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddWebSocketMiddleware<T>(this IServiceCollection services)
where T : class, IMessageMiddleware
{
if (services == null)
throw new ArgumentNullException(nameof(services));
/// <summary>
/// 注册核心服务
/// </summary>
/// <param name="services">服务集合</param>
private static void RegisterCoreServices(IServiceCollection services)
{
// 注册核心组件
services.AddSingleton<IWebSocketConnection, WebSocketConnection>();
services.AddSingleton<IMessageSerializer, JsonMessageSerializer>();
services.AddScoped<IMessageMiddleware, T>();
return services;
}
// 注册消息通道管理器
services.AddSingleton<IMessageChannelManager>(provider =>
/// <summary>
/// 注册核心服务
/// </summary>
/// <param name="services">服务集合</param>
private static void RegisterCoreServices(IServiceCollection services)
{
var logger = provider.GetRequiredService<ILogger<MessageChannelManager>>();
var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
return new MessageChannelManager(
logger,
config.QueueCapacity,
config.QueueCapacity,
100);
});
// 注册核心组件
services.AddSingleton<IWebSocketConnection, WebSocketConnection>();
services.AddSingleton<IMessageSerializer, JsonMessageSerializer>();
// 注册 WebSocket 传输
services.AddSingleton<IWebSocketTransport>(provider =>
{
var logger = provider.GetRequiredService<ILogger<CoreAgent.WebSocketTransport.Services.WebSocketTransport>>();
var connection = provider.GetRequiredService<IWebSocketConnection>();
var serializer = provider.GetRequiredService<IMessageSerializer>();
var middlewares = provider.GetServices<IMessageMiddleware>();
var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
var channelManager = provider.GetRequiredService<IMessageChannelManager>();
return new CoreAgent.WebSocketTransport.Services.WebSocketTransport(
logger,
connection,
serializer,
middlewares,
config,
channelManager);
});
}
// 注册消息通道管理器
services.AddSingleton<IMessageChannelManager>(provider =>
{
var logger = provider.GetRequiredService<ILogger<MessageChannelManager>>();
var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
return new MessageChannelManager(
logger,
config.QueueCapacity,
config.QueueCapacity,
100);
});
/// <summary>
/// 注册默认中间件
/// </summary>
/// <param name="services">服务集合</param>
private static void RegisterDefaultMiddleware(IServiceCollection services)
{
// 注册日志中间件
services.AddWebSocketMiddleware<LoggingMiddleware>();
// 注册 WebSocket 传输
services.AddSingleton<IWebSocketTransport>(provider =>
{
var logger = provider.GetRequiredService<ILogger<CoreAgent.WebSocketTransport.Services.WebSocketTransport>>();
var connection = provider.GetRequiredService<IWebSocketConnection>();
var serializer = provider.GetRequiredService<IMessageSerializer>();
var middlewares = provider.GetServices<IMessageMiddleware>();
var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
var channelManager = provider.GetRequiredService<IMessageChannelManager>();
return new CoreAgent.WebSocketTransport.Services.WebSocketTransport(
logger,
connection,
serializer,
middlewares,
config,
channelManager);
});
}
// 注册缓存中间件(可选)
services.AddScoped<IMessageMiddleware>(provider =>
/// <summary>
/// 注册默认中间件
/// </summary>
/// <param name="services">服务集合</param>
private static void RegisterDefaultMiddleware(IServiceCollection services)
{
var cache = provider.GetRequiredService<IMemoryCache>();
var logger = provider.GetRequiredService<ILogger<CacheMiddleware>>();
var config = provider.GetRequiredService<IOptions<WebSocketConfig>>().Value;
return new CacheMiddleware(cache, logger, config);
});
// 注册日志中间件
services.AddWebSocketMiddleware<LoggingMiddleware>();
// 注册缓存中间件(使用正确的注册方式)
services.AddWebSocketMiddleware<CacheMiddleware>();
}
}
}

75
modify.md

@ -472,4 +472,77 @@
- 调用方代码需要处理返回值
- 网络启动和停止流程的状态判断
- 日志记录详细程度提升
- 错误处理和状态监控能力增强
- 错误处理和状态监控能力增强
### 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.cs``ConfigureServices` 方法中添加 `services.AddMemoryCache()`
- 确保 `CacheMiddleware` 能够正确获取 `IMemoryCache` 依赖
- 在 WebSocket 传输服务注册之前添加内存缓存服务
4. **具体实现**:
```csharp
// 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.IEnumerable`1[CoreAgent.WebSocketTransport.Middleware.IMessageMiddleware]' from root provider`
- 依赖注入容器无法找到 `IMessageMiddleware` 服务
- `CacheMiddleware` 无法获取 `IMemoryCache` 依赖
**影响范围**:
- WebSocket传输服务的依赖注入配置
- 中间件注册和初始化顺序
- 应用程序启动时的服务注册
- 内存缓存服务的可用性
- 错误处理和异常预防
Loading…
Cancel
Save