我正在将 BDD 测试项目转换为使用 EF 核心 5.x 和 SpecFlow 3.x + Specflow.Autofac。执行场景时,上下文无法从环境变量中找到连接字符串。
解决方案设置具有以下结构
在所有场景执行之前注册场景依赖;
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");
}
}
位于 appsettings.json
项目中的 BddTest
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"MyContext": "--"
}
}
当我尝试运行场景时,应用程序在尝试在 MyContext
内创建数据库连接时出错;
System.InvalidOperationException: '使用了一个命名的连接字符串, 但名称“ConnectionStrings:MyContext”未在 应用程序的配置。请注意,命名连接字符串是 仅在使用“IConfiguration”和服务提供者时才受支持, 例如在典型的 ASP.NET Core 应用程序中。
如何注册我的 appsettings.json
以便它在 Data
项目中可用并且可以在使用 optionsBuilder.UseSqlServer("Name=ConnectionStrings:MyContext");
时解决?
答案 0 :(得分:1)
为了解决这个问题,我做了一些与@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);
}
}
答案 1 :(得分:0)
使用:
_config.GetValue<string>("ConnectionStrings:MyContext")
其中 _config 是注入到构造函数中的 DI IConfiguration,其中 OnConfiguring 是。
答案 2 :(得分:0)
试试这个:
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);
}
}