簡體   English   中英

如何將單個 IOptions POCO 交叉綁定到多個配置提供程序?

[英]How to cross-bind single IOptions POCO to multiple configuration providers?

我是 .net 內核的新手,我在為單個 POCO 使用多個配置提供程序時遇到問題。 我使用的是 .net 內核,而不是 asp.net 內核。

為了清楚起見,我試圖簡化類,請忽略任何編譯錯誤。 我的配置的model如下:

public class Configurations
{
  public EnvironmentConfig EnvironmentConfig {get; set;}
  public ServerConfig ServerConfig {get; set;}
}

public class EnvironmentConfig
{
  public string EnvironmentStr {get; set;}
}

public class ServerConfig
{
  public string Address {get; set;}
  public string Username {get; set;}
  public string Password {get; set;}
}

我有兩個提供程序 - appsettings.json和一個數據庫。 該數據庫與其他服務一起使用,因此無法輕松更改數據(可以認為是只讀的)。 appsettings.json文件具有以下層次結構:

{
  "EnvironmentConfig": {
    "EnvironmentStr": "dev"
  },
  "ServerConfig": {
    "Address": "https://example.com"
    // the other properties are not here, they're kept only in the database
  }
}

數據庫沒有層次結構,只提供缺失的屬性(我將再次使用 JSON 以保持一致性):

{
  "Username": "user"
  "Password": "password"
}

當我嘗試獲取IOptionsMonitor<Configurations> object 時,僅在ServerConfig中填充了Address屬性,就像它僅從appsettings.json讀取一樣(用戶名和密碼位於根級別,因此未正確綁定它們):

var configs = host.Services.GetService<IOptionsMonitor<Configurations>>().CurrentValue;

{
  "EnvironmentConfig": {
    "EnvironmentStr": "dev"
  },
  "ServerConfig": {
    "Address": "https://example.com"
    "Username": null,
    "Password": null
  }
}

當我嘗試獲取IOptionsMonitor<ServerConfig> object 時,它只綁定數據庫中的數據:

var serverConfig = host.Services.GetService<IOptionsMonitor<ServerConfig>>().CurrentValue;

{
  "Address": null,
  "Username": "user",
  "Password": "password"
}

看起來我沒有正確綁定它。 我嘗試了多種方法,但沒有奏效:

public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration)
{
  services
    .Configure<ServerConfig>(configuration) // the db properties are also at root level
    .Configure<Configurations>(configuration);
  return serviceCollection;
}
public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration)
{
  services
    .AddOptions<ServerConfig>()
    .Bind(configuration.GetSection("ServerConfig");
  services
    .AddOptions<Configurations>()
    .Bind(configuration);
  return serviceCollection;
}

有人可以解釋如何正確綁定它,而不管層次結構的差異如何,因此ServerConfigConfigurations中填充了所有屬性?

我假設數據庫作為自定義配置提供程序訪問

更新來自數據庫的鍵以匹配所需的層次結構

數據庫

"ServerConfig:Username" -> "user"
"ServerConfig:Password" -> "password"

所以配置框架在合並來自多個配置提供程序的所有配置時知道您指的是什么。

在加載配置時,從數據庫中提取設置並將層次結構添加到鍵中。

簡化示例:

public class ServerConfigProvider : ConfigurationProvider {
    public ServerConfigProvider (Action<DbContextOptionsBuilder> optionsAction) {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load() {
        var builder = new DbContextOptionsBuilder<MyEFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new MyEFConfigurationContext(builder.Options)) {
            Data = dbContext.MySettingsTable.ToDictionary(c => $"ServerConfig:{c.Key}", c => c.Value);
        }
    }    
}

參考自定義配置提供程序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM