如何在Asp.Net Core的另一个项目的DbContext中读取appsettings.json?
解决EF Core中Web项目与类库共享ConnectionString的问题
我明白你现在的困扰:Web项目Insig.Api里的appsettings.json存着连接字符串,但类库Insig.Infrastructure里的DbContext因为Code First迁移的需求,也需要用到这个连接字符串,硬编码肯定不是长久之计,之前尝试注入IConfiguration还报错了。
问题出在EF Core的设计时创建逻辑:当你执行Add-Migration这类命令时,EF不会通过Web项目的DI容器来创建DbContext实例,所以构造函数里的IConfiguration会是null,这就是你看到Value cannot be null错误的原因。
下面是可行的解决方案,推荐第一种,因为能保持配置的单一来源:
方案一:通过IDesignTimeDbContextFactory读取Web项目的配置
你已经实现了IDesignTimeDbContextFactory接口,现在只需要修改它的CreateDbContext方法,让它手动读取Web项目的appsettings.json即可:
首先,确保Insig.Infrastructure项目安装了以下NuGet包:
Microsoft.Extensions.Configuration.JsonMicrosoft.Extensions.Configuration.EnvironmentVariables(可选,支持环境特定配置)
然后修改InsigContext.cs中的CreateDbContext方法:
public InsigContext CreateDbContext(string[] args) { // 定位到Web项目的目录(根据你的解决方案结构调整路径) // 假设类库和Web项目在解决方案根目录下的同级文件夹中 var webProjectRoot = Path.Combine(Directory.GetCurrentDirectory(), "..", "Insig.Api"); // 构建配置,和Web项目的Startup里逻辑一致 var configBuilder = new ConfigurationBuilder() .SetBasePath(webProjectRoot) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"}.json", optional: true) .AddEnvironmentVariables(); var configuration = configBuilder.Build(); var connectionString = configuration.GetConnectionString("DefaultConnection"); var optionsBuilder = new DbContextOptionsBuilder<InsigContext>(); optionsBuilder.UseSqlServer(connectionString); return new InsigContext(optionsBuilder.Options); }
关键说明:
Directory.GetCurrentDirectory()在执行迁移命令时,返回的是解决方案的根目录,所以我们用相对路径定位到Web项目的文件夹。如果你的项目结构不同(比如Web项目在子目录里),需要调整Path.Combine的参数。- 这样做的好处是,连接字符串只需要在Web项目的
appsettings.json里维护一处,类库的迁移会自动读取最新的配置。
验证迁移命令
现在你可以回到Package Manager Console,确保默认项目选择Insig.Infrastructure,然后执行:
Add-Migration Init
或者用dotnet CLI:
dotnet ef migrations add Init --project Insig.Infrastructure --startup-project Insig.Api
(用方案一的话,不加--startup-project也能正常工作,但加上更稳妥)
内容的提问来源于stack exchange,提问作者DiPix
相关产品推荐
相关产品推荐

