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

ASP.NET 6 Web API带参数DatabaseContext依赖注入异常解决

ASP.NET 6中带参数DatabaseContext的依赖注入问题解决

问题场景

使用ASP.NET 6开发Web API时,相关代码及异常情况如下:

控制器代码

public AccountController(IAccountService service) { }

服务代码

public AccountService(DatabaseContext db) { }

DatabaseContext代码

public class DatabaseContext : DbContext
{
    public DatabaseContext(string connectionString) : base() { }
}

Startup.cs中的服务注册

// ...
services.AddTransient<IAccountService, AccountService>();
services.AddSingleton<AccountController, AccountController>();
var connectionString = "we can get connection string here";
services.AddTransient(_ => new DatabaseContext(connectionString));

编译正常,但运行时抛出异常:

Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: API.Common.DatabaseContext Lifetime: Scoped ImplementationType: API.Common.DatabaseContext': Unable to resolve service for type 'System.String' while attempting to activate 'API.Common.DatabaseContext'.)

System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: API.Common.DatabaseContext Lifetime: Scoped ImplementationType: API.Common.DatabaseContext': Unable to resolve service for type 'System.String' while attempting to activate 'API.Common.DatabaseContext'.

System.InvalidOperationException: Unable to resolve service for type 'System.String' while attempting to activate 'API.Common.DatabaseContext'.

当DatabaseContext使用无参构造函数时一切正常,添加参数后触发上述异常,需解决带参数的DatabaseContext依赖注入问题。

解决方案

核心原因

异常根源是ASP.NET Core DI容器在服务验证阶段,检测到DatabaseContext的构造函数依赖string类型参数,但容器中未注册对应的string服务,因此抛出验证错误。

具体解决方法

方法1:使用EF Core推荐的DbContextOptions构造函数(优先选择)

这是符合框架设计的标准做法,能避免多数依赖注入冲突:

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
}

在Startup.cs中更新注册逻辑(根据你的数据库类型调整UseSqlServer,比如PostgreSQL用UseNpgsql):

var connectionString = "we can get connection string here";
services.AddDbContext<DatabaseContext>(options => 
    options.UseSqlServer(connectionString));

方法2:保留原构造函数,调整注册逻辑

若必须保留string参数的构造函数,可通过明确指定工厂创建逻辑,跳过容器对构造函数依赖的自动解析:

var connectionString = "we can get connection string here";
services.AddTransient<DatabaseContext>(sp => new DatabaseContext(connectionString));

注意:若之前有调用AddDbContext注册DatabaseContext,需移除该调用,避免服务描述符冲突。

额外优化:修正控制器生命周期注册

代码中把AccountController注册为Singleton是不推荐的,ASP.NET Core控制器默认是Scoped生命周期,Singleton控制器会导致后续依赖的Scoped服务(如DatabaseContext)出现生命周期不匹配问题,建议移除该行注册:

// 移除以下代码
// services.AddSingleton<AccountController, AccountController>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:46:24