Hot Chocolate Web应用依赖注入:静态还是实例级?架构问询
问题分析与解决方案
架构可行性判断
这个架构本身是可行的,Hot Chocolate基于ASP.NET Core,完全支持单进程内启动多个独立的WebHost(对应不同端口),每个WebHost可以拥有独立的DI配置和GraphQL Schema,对应不同的模拟数据仓库。
DI容器的独立性
ASP.NET Core的DI容器是每个WebHost实例独立存在的,不存在全局静态共享的默认容器。你遇到所有端口拿到同一个Repo的问题,大概率是实现逻辑有以下问题:
- 错误地将Repo注册为
Singleton,且初始化Repo时用了静态的数据库配置(而非每个WebHost专属的配置); - 启动多个WebHost时复用了同一个
IServiceCollection实例,导致后注册的Repo覆盖了之前的,所有WebHost共享同一个Repo实例; - Repo的数据库配置逻辑存在静态依赖,没有根据每个WebHost的上下文(比如端口、模拟ID)动态生成。
如何获取正确的Repo
你完全可以实现每个端口对应正确Repo的需求,需要修正以下几点:
- 为每个WebHost独立构建服务配置:启动每个端口的Web应用时,创建全新的
IServiceCollection,根据当前模拟的数据库标识(比如CosmosDB的数据库ID)注册专属的Repo实例,注册时使用Scoped或Transient生命周期(不要用Singleton)。 - 动态传递数据库配置:启动WebHost时,通过
IConfiguration传入当前模拟对应的CosmosDB参数,Repo初始化时读取该配置创建专属的数据库访问实例。 - 验证WebHost独立性:启动每个WebHost时,记录当前注册的Repo对应的数据库标识,确认每个实例的Repo配置是独立的。
举个简单的启动逻辑示例(伪代码):
foreach (var simulation in runningSimulations) { var host = Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseUrls($"http://localhost:{simulation.Port}"); webBuilder.ConfigureServices(services => { // 为当前模拟注册专属Repo services.AddScoped<IRepo>(sp => new CosmosDbRepo(simulation.DatabaseId, sp.GetRequiredService<CosmosClient>())); // 注册Hot Chocolate服务 services.AddGraphQLServer() .AddQueryType<Query>(); }); }) .Build(); await host.StartAsync(); }
总结
你的核心问题并非架构不可行,而是启动多个WebHost时的服务注册逻辑存在共享或静态依赖的错误。修正后,每个端口的Hot Chocolate API会注入对应模拟的专属Repo,实现预期功能。
内容的提问来源于stack exchange,提问作者Andrew Matthews
相关产品推荐
相关产品推荐

