EF 核心无法使用带有 SpecFlow 的 UseSqlServer 解析环境变量
EF core unable to resolve environment variable using UseSqlServer with SpecFlow
我正在将 BDD 测试项目转换为使用 EF 核心 5.x 和 SpecFlow 3.x + Specflow.Autofac。执行场景时,上下文无法从环境变量中找到连接字符串。
解决方案设置具有以下结构
- API(项目)
-
- appsettings.json(不是应该用于 specflow 测试的那个)
- 商业(项目)
-
- BusinessRegister.cs
- 数据(项目)
-
- MyContext.cs
-
- DataRegister.cs
- BddTest(项目)
-
- appsettings.json(具有用于 mycontext 的 bdd 测试的连接字符串)
-
- DependencyResolver.cs
-
- 各种场景
场景依赖在所有场景执行前注册;
public static class DependencyResolver
{
private static IConfiguration config;
[ScenarioDependencies]
public static ContainerBuilder CreateContainerBuilder()
{
var containerBuilder = new ContainerBuilder();
if (config == null)
{
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DependencyResolver)).Location;
string theDirectory = Path.GetDirectoryName(fullPath);
config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.SetBasePath(theDirectory)
.AddEnvironmentVariables()
.Build();
}
containerBuilder.RegisterInstance(config);
containerBuilder.RegisterTypes(typeof(DependencyResolver).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))).ToArray()).SingleInstance();
containerBuilder.RegisterModule(new DependencyRegister());
containerBuilder.RegisterModule(new BusinessRegister());
containerBuilder.RegisterModule(new DataRegister());
return containerBuilder;
}
}
DataRegister 寄存器 MyContext
;
public class DataRegister : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyContext>().AsSelf().InstancePerDependency();
}
}
在 MyContext
内部调用 UseSqlServer
尝试解析环境变量
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Name=ConnectionStrings:MyContext");
}
}
位于BddTest
项目中的appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"MyContext": "--"
}
}
当我尝试 运行 一个场景时,应用程序在尝试在 MyContext
中创建数据库连接时出错;
System.InvalidOperationException: 'A named connection string was used,
but the name 'ConnectionStrings:MyContext' was not found in the
application's configuration. Note that named connection strings are
only supported when using 'IConfiguration' and a service provider,
such as in a typical ASP.NET Core application.
如何注册我的 appsettings.json
以便它在 Data
项目中可用并且在使用 optionsBuilder.UseSqlServer("Name=ConnectionStrings:MyContext");
时可以解决?
使用:
_config.GetValue<string>("ConnectionStrings:MyContext")
其中 _config 是在 OnConfiguring 所在的构造函数中注入的 DI IConfiguration。
试试这个:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured)
{
var config = ConfigurationManager.ConnectionStrings["MyContext"];
var conn = new SqlConnection(config.ConnectionString);
options.UseSqlServer(conn);
}
}
为了解决这个问题,我做了一些与@Matheus Dasuke 所建议的非常相似的事情。注入 IConfiguration 然后读出值。这意味着我可以从环境变量、用户机密等中获取属性值。
private static IConfiguration _configuration;
public MyContext(IConfiguration configuration) {
_configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured) {
var builder = new NpgsqlConnectionStringBuilder("Host=" +
_configuration.GetConnectionString("Host")) {
Password = _configuration["Password"],
Username = _configuration["Username"],
Database = _configuration["Database"],
};
optionsBuilder.UseNpgsql(builder.ConnectionString);
}
}
我正在将 BDD 测试项目转换为使用 EF 核心 5.x 和 SpecFlow 3.x + Specflow.Autofac。执行场景时,上下文无法从环境变量中找到连接字符串。
解决方案设置具有以下结构
- API(项目)
-
- appsettings.json(不是应该用于 specflow 测试的那个)
- 商业(项目)
-
- BusinessRegister.cs
- 数据(项目)
-
- MyContext.cs
-
- DataRegister.cs
- BddTest(项目)
-
- appsettings.json(具有用于 mycontext 的 bdd 测试的连接字符串)
-
- DependencyResolver.cs
-
- 各种场景
场景依赖在所有场景执行前注册;
public static class DependencyResolver
{
private static IConfiguration config;
[ScenarioDependencies]
public static ContainerBuilder CreateContainerBuilder()
{
var containerBuilder = new ContainerBuilder();
if (config == null)
{
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DependencyResolver)).Location;
string theDirectory = Path.GetDirectoryName(fullPath);
config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.SetBasePath(theDirectory)
.AddEnvironmentVariables()
.Build();
}
containerBuilder.RegisterInstance(config);
containerBuilder.RegisterTypes(typeof(DependencyResolver).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))).ToArray()).SingleInstance();
containerBuilder.RegisterModule(new DependencyRegister());
containerBuilder.RegisterModule(new BusinessRegister());
containerBuilder.RegisterModule(new DataRegister());
return containerBuilder;
}
}
DataRegister 寄存器 MyContext
;
public class DataRegister : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyContext>().AsSelf().InstancePerDependency();
}
}
在 MyContext
内部调用 UseSqlServer
尝试解析环境变量
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Name=ConnectionStrings:MyContext");
}
}
位于BddTest
项目中的appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"MyContext": "--"
}
}
当我尝试 运行 一个场景时,应用程序在尝试在 MyContext
中创建数据库连接时出错;
System.InvalidOperationException: 'A named connection string was used, but the name 'ConnectionStrings:MyContext' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application.
如何注册我的 appsettings.json
以便它在 Data
项目中可用并且在使用 optionsBuilder.UseSqlServer("Name=ConnectionStrings:MyContext");
时可以解决?
使用:
_config.GetValue<string>("ConnectionStrings:MyContext")
其中 _config 是在 OnConfiguring 所在的构造函数中注入的 DI IConfiguration。
试试这个:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured)
{
var config = ConfigurationManager.ConnectionStrings["MyContext"];
var conn = new SqlConnection(config.ConnectionString);
options.UseSqlServer(conn);
}
}
为了解决这个问题,我做了一些与@Matheus Dasuke 所建议的非常相似的事情。注入 IConfiguration 然后读出值。这意味着我可以从环境变量、用户机密等中获取属性值。
private static IConfiguration _configuration;
public MyContext(IConfiguration configuration) {
_configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.EnableDetailedErrors();
if (!optionsBuilder.IsConfigured) {
var builder = new NpgsqlConnectionStringBuilder("Host=" +
_configuration.GetConnectionString("Host")) {
Password = _configuration["Password"],
Username = _configuration["Username"],
Database = _configuration["Database"],
};
optionsBuilder.UseNpgsql(builder.ConnectionString);
}
}