我有一个常规的 ASP.NET 应用程序,它使用路由等。我还想将具有数据库连接的 WebSocket 添加到应用程序,并得出结论中间件是执行此操作的最佳方法,但我无法得到它使用数据库。这是目前我的
WebSocketMiddleware
课程:
public class WebSocketMiddleware
{
private readonly RequestDelegate next;
private readonly DatabaseService databaseService;
public WebSocketMiddleware(RequestDelegate next, DatabaseService databaseService)
{
this.next = next;
this.databaseService = databaseService;
}
public async Task Invoke(HttpContext context)
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await HandleWebSocketConnection(context, webSocket);
} else
{
Console.WriteLine("Not ws");
await next(context);
}
}
这是程序:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<DatabaseContext>(options =>
options.UseNpgsql("address"));
builder.Services.AddScoped<DatabaseService>();
builder.Services.AddScoped<WebSocketMiddleware>();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowLocalhost",
builder =>
{
builder.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowCredentials()
.AllowAnyMethod();
});
});
var app = builder.Build();
app.UseCors("AllowLocalhost");
app.UseWebSockets();
app.UseMiddleware<WebSocketMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
这是我尝试注入的 DatabaseService:
public class DatabaseService
{
private readonly DatabaseContext databaseContext;
public DatabaseService(DatabaseContext databaseContext)
{
this.databaseContext = databaseContext;
}
// methods //
}
我尝试删除并添加 WebSocketMiddleware 作为
AddScoped
,但都因各自的原因而失败。如果我从中间件中删除 DatabaseService,它就会按预期工作。
错误: 添加作用域时:“尝试激活 WebSocketMiddleware 时无法解析 Http.RequestDelegate 类型的服务”
删除范围时:“无法从根提供程序解析范围服务 DatabaseService”
如果我从中间件中删除 RequestDelegate,则会收到以下错误: “无法找到 WebSocketMiddleware 类型的合适构造函数”
注入到中间件类构造函数中的依赖项不能按设计确定作用域,因为中间件类是signleton。
要将范围服务注入中间件,首先删除中间件注册,然后将服务作为方法参数获取。
public class WebSocketMiddleware
{
private readonly RequestDelegate next;
public WebSocketMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context, DatabaseService databaseService)
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await HandleWebSocketConnection(context, webSocket);
} else
{
Console.WriteLine("Not ws");
await next(context);
}
}