从 dot net core 中的配置获取多个连接字符串的推荐方法

Recommended way to get multiple connection strings from configuration in dot net core

目前我正在使用 ABP 3.3.0 并且我有 2 个 DbContext。一个是 MSSQL 上下文,另一个是 MySQL。 为了获取连接字符串,我继承了 DefaultConnectionStringResolver class 并覆盖了 GetNameOrConnectionString 方法。 这在开发中工作正常,但是每当我尝试 运行 单元测试时,我都会得到以下异常

Castle.MicroKernel.Handlers.HandlerException : Can't create component 'Portal.EntityFrameworkCore.CustomerDbConnectionStringResolver' as it has dependencies to be satisfied.

'Portal.EntityFrameworkCore.CustomerDbConnectionStringResolver' is waiting for the following dependencies: - Service 'Microsoft.AspNetCore.Hosting.IHostingEnvironment' which was not registered.

我的理解是因为我正在将 IHostingEnvironment 注入连接字符串解析器。

所以我的问题是,如果我不能将 IHostingEnvironment 注入连接字符串解析器 class,我还能如何访问连接字符串?

为清楚起见, 在开发中,连接字符串存储为用户机密。 在 Staging/Production 中,它们存储在各自的 appSettings.{EnvironmentName}.json 文件中。

这里是连接字符串解析器的实现 class。

public class CustomerDbConnectionStringResolver : DefaultConnectionStringResolver
{
    private readonly IHostingEnvironment _env;
    public CustomerDbConnectionStringResolver(
        IAbpStartupConfiguration configuration,
        IHostingEnvironment env)
        : base(configuration)
    {
        _env = env;
    }

    public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
    {
         var configuration = AppConfigurations.Get(_env.ContentRootPath, _env.EnvironmentName,_env.IsDevelopment());

        switch (args["DbContextType"].ToString())
        {
            case "Portal.EntityFrameworkCore.FreeRadiusDbContext":
                return configuration.GetConnectionString(PortalConsts.FreeRadiusConnectionStringName);
            default:
                return configuration.GetConnectionString(PortalConsts.ConnectionStringName);
        }
    }
}

非常感谢!

编辑

当前 DBContextFactory 的示例。

    public  class FreeRadiusDbContextFactory : IDesignTimeDbContextFactory<FreeRadiusDbContext>
   {
       public FreeRadiusDbContext CreateDbContext(string[] args)
       {
            var builder = new DbContextOptionsBuilder<FreeRadiusDbContext>();
            var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

            FreeRadiusDbContextConfigurator.Configure(
                builder,
                configuration.GetConnectionString(PortalConsts.FreeRadiusConnectionStringName)
                );

            return new FreeRadiusDbContext(builder.Options);
        }
   }

@aaron 好的所以我想我终于找到了一个适用于所有环境的解决方案。

注意:至于双反斜杠问题,看起来我在环境变量中使用双反斜杠连接字符串,而它本应是单反斜杠。

所以这是最后的 CustomDbConnectionStringResolver class.

public class CustomDbConnectionStringResolver : DefaultConnectionStringResolver
{
    public CustomDbConnectionStringResolver(
        IAbpStartupConfiguration configuration
    )
        : base(configuration)
    {
    }

    public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
    {
        var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
        var configuration = AppConfigurations.Get(Directory.GetCurrentDirectory(), environment, environment == "Development");

        switch (args["DbContextType"].ToString())
        {
            case "Portal.EntityFrameworkCore.FreeRadiusDbContext":
                return configuration.GetConnectionString(PortalConsts.FreeRadiusConnectionStringName);
            default:
                return configuration.GetConnectionString(PortalConsts.ConnectionStringName);
        }
    }
}

它可以很好地重用模板中已经存在的代码,并且仍然允许为各种环境加载不同的配置。

非常感谢@aaron 的协助!