You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8启动注册依赖报错:服务集合只读无法修改

解决ASP.NET Core 8中服务集合只读的问题

你遇到的错误是因为调用builder.Build()后,服务集合会被锁定为只读状态,此时无法再通过builder.Services添加新的服务注册。ASP.NET Core 8设计为容器构建后不可变,以确保服务配置的一致性。

以下是几种可行的解决方案:

方案一:构建应用前解析依赖(临时服务提供者)

如果第一个依赖不需要依赖WebApplication实例(比如不需要已加载的配置或中间件相关服务),可以先创建一个临时的服务提供者来解析它,再完成第二个服务的注册,最后构建应用:

var builder = WebApplication.CreateBuilder(args);

// 注册第一个依赖
builder.Services.AddTransient<IMyDependency, MyDependency>();

// 创建临时服务提供者解析依赖
using (var tempServiceProvider = builder.Services.BuildServiceProvider())
using (var scope = tempServiceProvider.CreateScope())
{
    var myDependency = scope.ServiceProvider.GetRequiredService<IMyDependency>();
    // 注册第二个依赖
    builder.Services.AddTransient<IAnotherDependency>(_ => new AnotherDependency(myDependency));
}

// 构建应用
var app = builder.Build();

// 后续中间件配置...
app.Run();

方案二:利用DI容器自动解析依赖(推荐)

更符合依赖注入设计原则的方式是,在注册第二个服务时,直接让容器自动解析第一个依赖,不需要手动提前获取实例:

var builder = WebApplication.CreateBuilder(args);

// 注册第一个依赖
builder.Services.AddTransient<IMyDependency, MyDependency>();

// 注册第二个依赖时,从容器中获取第一个依赖实例
builder.Services.AddTransient<IAnotherDependency>(serviceProvider => 
    new AnotherDependency(serviceProvider.GetRequiredService<IMyDependency>()));

var app = builder.Build();

// 后续配置...
app.Run();

这种方式的优势在于:

  • 遵循DI的松耦合原则,依赖关系由容器管理
  • 避免临时服务提供者带来的潜在资源问题
  • 支持依赖的生命周期管理(比如如果IMyDependency是Scoped类型,容器会自动处理作用域)

方案三:应用启动后注册(特殊场景)

如果第一个依赖必须在WebApplication构建完成后才能获取(比如依赖于应用的运行时状态),可以通过IHostApplicationLifetime在应用启动阶段处理,但这种场景较少见,且需要额外的扩展方式(比如使用自定义服务容器扩展),一般不推荐优先使用。


内容的提问来源于stack exchange,提问作者osotorrio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:12:41