Разверните переменные среды в файле appSettings. json - PullRequest
1 голос
/ 14 марта 2020

Есть ли способ "из коробки", чтобы переменные окружения в appsettings.json значениях расширялись автоматически?

Чтобы взять надуманный пример:

{
  ...
  "MyPath1": "C:/MyApp/%ENV%/Myfolder1/MyFile1.dat",
  "MyConnectionString":  "Server=MyServer%ENV%..."
  ...
}

Моя цель состоит в том, чтобы быть способным переключать мою среду, изменяя одну переменную среды и влияя на несколько значений параметров приложения, а не на файлы конфигурации для каждой среды.

ОБНОВЛЕНИЕ

I Я просмотрел исходный код JsonConfigurationProvider и, насколько я вижу, такой функции не существует "из коробки".

Я вижу, что это должно быть возможно путем получения пользовательского класс из JsonConfigurationProvider и переопределение метода Load():

public override void Load()
{
    base.Load();
    foreach(var key in Data.Keys)
    {
        Data[key] = Environment.ExpandEnvironmentVariables(key);
    }
}

Но я довольно новичок в этом. NET Конфигурация ядра, что приводит ко второму вопросу:

Как получить эту пользовательскую реализацию, чтобы заменить стандартную? Т.е. удалить стандартные настройки appsettings. json и appsettings.environment. json и заменить их на пользовательские. Предположительно что-то будет добавлено в Program.cs:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration(config =>
        {
            config.??? what do I need here?
        }
        );

1 Ответ

4 голосов
/ 17 марта 2020

Для создания и использования источника пользовательской конфигурации необходимы две реализации:

  1. IConfigurationSource
  2. IConfigurationProvider

Это реализация IConfigurationSource, которая добавляется к источникам IConfigurationBuilder. Эта реализация также отвечает за создание собственного IConfigurationProvider, который отвечает за загрузку данных из источника.

Здесь представлены пользовательские реализации IConfigurationSource (ExpandJsonConfigurationSource) и IConfigurationProvider (ExpandJsonConfigurationProvider):

public class ExpandJsonConfigurationSource : JsonConfigurationSource
{
    public override IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        EnsureDefaults(builder);
        return new ExpandJsonConfigurationProvider(this);
    }
}

public class ExpandJsonConfigurationProvider : JsonConfigurationProvider
{
    public ExpandJsonConfigurationProvider(ExpandJsonConfigurationSource source)
        : base(source) { }

    public override void Load()
    {
        base.Load();
        Data = Data.ToDictionary(
            x => x.Key,
            x => Environment.ExpandEnvironmentVariables(x.Value));
    }
}

Здесь мало что происходит. Эти реализации просто следуют тому же подходу, что и существующие реализации JsonConfigurationSource и JsonConfigurationProvider, с настраиваемой обработкой для расширения переменных среды.

Чтобы заменить предварительно сконфигурированные источники на основе JSON, используйте следующее:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration((ctx, builder) =>
        {
            var jsonConfigurationSources = builder.Sources
                .OfType<JsonConfigurationSource>()
                .ToList();

            foreach (var jsonConfigurationSource in jsonConfigurationSources)
            {
                var indexOfJsonConfigurationSource = builder.Sources
                    .IndexOf(jsonConfigurationSource);

                builder.Sources.RemoveAt(indexOfJsonConfigurationSource);
                builder.Sources.Insert(
                    indexOfJsonConfigurationSource,
                    new ExpandJsonConfigurationSource
                    {
                        FileProvider = jsonConfigurationSource.FileProvider,
                        Path = jsonConfigurationSource.Path,
                        Optional = jsonConfigurationSource.Optional,
                        ReloadOnChange = jsonConfigurationSource.ReloadOnChange
                    });
            }
        });

Делегат, переданный в ConfigureAppConfiguration, выполняет следующие действия:

  1. Поиск всех настроенных экземпляров JsonConfigurationSource. Должно быть два экземпляра: для appsettings.json и, например, appsettings.Development.json.
  2. Для каждого экземпляра:

    1. Определите положение экземпляра в предварительно сконфигурированных источниках.
    2. Удалить экземпляр.
    3. Заменить удаленный экземпляр на экземпляр ExpandJsonConfigurationSource, скопировав через свойства, чтобы убедиться, что он имеет тот же путь, дополнительный флаг и т. Д. c.
...