У меня есть 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 версии этого файла для каждой среды:
Я могу использовать его через:
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
для каждой среды?
То, что вы написали, говорит 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()
, чтобы позволить вам переопределять настройки во время выполнения.
@PanagiotisKanavos Спасибо за предупреждение (относительно ASPNETCORE_ENVIRONMENT
), так как бы вы решили это?
Поместите общие настройки в appsettings.json
и поместите только новый/переопределяет в файлы, специфичные для среды. Если раздел Servers
одинаков для всех сред, повторять его не нужно. Если вам нужно заменить только параметр один, добавьте только его. Значения параметров представляют собой пару ключ/значение, без наследования.
@PanagiotisKanavos Я говорил о другом комментарии (Кстати, не помещайте Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") в строку)
Просто поместив раздел 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()
Источники конфигурации .NET Core переопределяют предыдущие записи. Вам не нужно дублировать файлы, просто укажите новые значения для каждой среды. Кстати, не поместил
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
в строку. Это не только усложняет чтение и понимание кода, вы можете прочитать это значение из командная строка, например, во время тестирования.