Общие настройки в .NET Core?

У меня есть 3 файла с именем appsettings.[int/stg/prod].json в моем основном приложении asp.net:

{
    "EmailForFailedNonCrucial":
    {
        "Email": "royin...",
        "Subject": "...",
        "Body": "...",
        "ConnectionString": "Staging-Connection-String"
    },
    "Servers": [
    {
        "Name": "aaa",
        "Services": [
            ...
        ]
    },
    {
        "Name": "bbb",
        "Services": [
            ...
        ]
    }]
}

Каждому разделу соответствует раздел в классе C#. (для IOptions).

У меня есть 3 версии этого файла для каждой среды:

Общие настройки в .NET Core?

Я могу использовать его через:

 public static IConfigurationRoot ConfigureConfiguration()
        {
            return new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($@"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
                .AddEnvironmentVariables()
                .Build();

        }

Но вещь Только, которая должна быть разной в разных средах, — это ConnectionString.
Раздел Serversто же самое для всех сред.

Вопрос:

Кажется странным дублировать Servers во всех трех файлах.
Как я могу выполнить (наследование?), указав его один раз, и иметь только EmailForFailedNonCrucial для каждой среды?

Источники конфигурации .NET Core переопределяют предыдущие записи. Вам не нужно дублировать файлы, просто укажите новые значения для каждой среды. Кстати, не поместил Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") в строку. Это не только усложняет чтение и понимание кода, вы можете прочитать это значение из командная строка, например, во время тестирования.

Panagiotis Kanavos 27.05.2019 10:20

То, что вы написали, говорит Read my settings from a local 'appsettings.json' file, then read another json file and merge or override the new settings, finally merge or override settings pulled from environment variables. Вы можете добавить AddConsole(), чтобы позволить вам переопределять настройки во время выполнения.

Panagiotis Kanavos 27.05.2019 10:22

@PanagiotisKanavos Спасибо за предупреждение (относительно ASPNETCORE_ENVIRONMENT), так как бы вы решили это?

Royi Namir 27.05.2019 10:25

Поместите общие настройки в appsettings.json и поместите только новый/переопределяет в файлы, специфичные для среды. Если раздел Servers одинаков для всех сред, повторять его не нужно. Если вам нужно заменить только параметр один, добавьте только его. Значения параметров представляют собой пару ключ/значение, без наследования.

Panagiotis Kanavos 27.05.2019 10:29

@PanagiotisKanavos Я говорил о другом комментарии (Кстати, не помещайте Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") в строку)

Royi Namir 27.05.2019 10:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
2 105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Еще немного чтения: Конфигурация в ядре

Ответ принят как подходящий

Параметры конфигурации в .NET Core обрабатываются как значения в словаре "ключ-значение". Значения от нескольких поставщиков объединяются вместе, при этом более новые значения заменяют старые. Имена файлов не имеют особого значения, важен только порядок вызовов.

Это объясняется в Essential .NET — конфигурация в .NET Core и Конфигурация в ASP.NET Core. Несмотря на название, библиотека конфигурации доступна и для приложений Full Framework.

Настройки преобразуются в пары ключ/значение при загрузке. Содержимое этого файла:

{
  "section0": {
    "key0": "value",
    "key1": "value"
  },
  "section1": {
    "key0": "value",
    "key1": "value"
  }
}

Сведены всего к 4 парам, чьи ключи:

- section0:key0
- section0:key1
- section1:key0
- section1:key1

Другой файл или поставщик могут переопределить предыдущую настройку, если они создают тот же ключ. SomeotherFile.json может заменить section1:key0, указав новое значение только для этого ключа:

{
  "section1": {
    "key0": "value",
  }
}

Нет необходимости дублировать настройки.

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

var envSpecificFile=...
return new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile(envSpecificFile, optional: true)
            .AddEnvironmentVariables()
            .Build();

Использование appsettings.prod.json — это просто условность. Чтение конкретной переменной среды для определения среды также является просто соглашением.

Общим соглашением для проектов ASP.NET Core является использование переменной среды ASPNETCORE_ENVIRONMENT:

var env=Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var envSpecificFile = $"appsettings.{env}.json";

С таким же успехом среда может быть получена из аргумента командной строки. Это позволит протестировать различные конфигурации на сервере QA, например:

string env;
if (args.Length>0)
{
    env=args[0];
}
else
{
    env=Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
}

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

Например:

  var dictSettings = new Dictionary<string, string>()
  {
      ["section0:key1"] = args[1],
  };

Может использоваться для переопределения значения section0:key1:

return new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env}.json", optional: true)
            .AddInMemoryCollection(dictSettings)
            .AddEnvironmentVariables()
            .Build();

Этот пример немного надуманный. Словари обычно используются для предоставления значений по умолчанию, поэтому они обычно добавляются перед другими поставщиками.

.AddInMemoryCollection(defaultSettings)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", optional: true)
.AddEnvironmentVariables()

Другие вопросы по теме