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

Однако задумывались ли вы, почему это так и как это работает? Оказалось, что речь идет не только о appsettings.json, есть еще немного о конфигурациях, которые могут вас удивить.

Сегодня мы более подробно рассмотрим некоторые исходные коды из ASP.Net и посмотрим, как все работает под капотом.

Почти каждый шаблон для проекта ASP содержит класс Program с такой конфигурацией. Он может немного отличаться от версии к версии, но в основном он остается прежним.

То, что нас интересует, находится в строке номер 9, ее метод CreateDefaultBuilder(args). Этот метод настраивает поведение по умолчанию для нашего сервера, такое как маршрутизация, DI, ведение журнала и т. д. Отложите все в сторону, и все, что вы получите, это то, как осуществляется управление конфигурацией:

Есть несколько ключевых моментов, на которые стоит обратить внимание:

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

Давайте разобьем его на части и исследуем все по порядку.

приоритет

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

Чтобы не делать ASP здесь исключением и следовать общепринятой практике, ребятам из Microsoft пришлось имитировать такое поведение, реализовав все своими руками. И здесь важен правильный порядок. Помнить:

Более поздняя зарегистрированная конфигурация имеет более высокий приоритет

Итак, в конце приоритет конфигурации находится в порядке от высокого к низкому:

  • Аргументы командной строки
  • Переменные среды
  • Секреты пользователя
  • Зависит от среды appsettings
  • Обычный appsettings

Иерархия Suck характерна для Python, Java и других слов. Это легко запомнить. Чем конкретнее, чем глобальнее конфигурация, тем более высокий приоритет они будут иметь.

appsettings.json

Несмотря на то, что appsettings.json всегда регистрируется, appsettings.Development.json — нет. В этом есть некоторая свобода, но есть и недостаток. Всякий раз, когда мы создаем appsettings.Staging.json, он не будет загружаться в проект сразу. Для этого нам нужно изменить среду хостинга. И как это сделать, отредактировав Properties/launchSettings.json:

Вот мой. Мне пришлось указать в строке 11, какая среда мне нужна в данный момент. Вы можете иметь несколько профилей для разных целей и запускать их из VisualStudio в зависимости от ваших потребностей.

Стоит отметить, что при развертывании вашего проекта ASP в рабочей среде вам может понадобиться команда dotnet publish, которая установит вашу среду как Production и попытается загрузить appsettings.Production.json, если она присутствует.

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

Секреты пользователя

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

Это можно сделать с помощью секретов пользователя.

Right click в своем проекте ASP и выберите 'Manage User secrets'. При этом произойдет несколько вещей:

Во-первых, свойство UserSecretsId будет добавлено в ваш файл csproj:

Во-вторых, под вашим пользователем будет создана новая папка с именем SecretsId. Скорее всего, будет использоваться путь по умолчанию:

C:\Users\<YourUser>\AppData\Roaming\Microsoft\UserSecrets\1b7d0a0a-8a15–4bb2-bfcd-21c5fb4d53a4

И последний файл secrets.json будет находиться в этой папке.

secrets.json — это обычный файл json, похожий на appsettings.json. Ключевым моментом здесь является то, что он хранится настолько далеко от вашего проекта, что ваша система контроля версий не может его отследить, поэтому GitHub не будет иметь об этом ни малейшего представления, и вы можете хранить там любую личную информацию, которую хотите.

Важно отметить, что секреты будут загружаться только в среде Development. Он имеет встроенную поддержку для стадии разработки, но в остальном это недоступная опция.

Переменная среды

Вы когда-нибудь создавали глобальную переменную в своем коде? Переменная среды - это то же самое. Единственная разница здесь в том, что это глобальная переменная не только для вашей программы, но и для всего вашего компьютера и доступна для каждой программы.

Вы уже видели, как мы определили переменные среды в launchSettings.json в строке 10:

Но они специфичны для нашего приложения. Если вам нужна истинная переменная окружения, нажмите Windows+R, напишите sysdm.cpl и нажмите Enter. В появившемся окне выберите Advanced и Environment Variables…

Теперь вы можете определить пользовательские и системные переменные. Переменная, как и следовало ожидать, представляет собой просто пару ключ-значение. Доступ к системным переменным среды имеет глобальный доступ для всех пользователей, а переменные среды пользователя относятся только к вошедшему в систему пользователю.

Жизнь была бы проще, если бы не Microsoft 😃

Небольшое замечание: IIS не использует переменные среды user:

Если вы хотите использовать переменные среды, зависящие от пользователя, то для параметра пула приложений LoadUserProfile должно быть установлено значение true (по умолчанию — false).

Кроме этого, мы готовы идти.

Когда вы хотели бы использовать переменную среды?

В процессе разработки, чтобы снизить затраты на обработку нескольких секретов или appsettings файлов в нескольких проектах и ​​разделить их между разработчиками, вам лучше определить одну переменную среды один раз на каждой рабочей станции и забыть об этом.

Чаще всего они используются при развертывании приложения. Например, развертывая в Azure как AppService, вы, скорее всего, укажете строку подключения к вашей реальной базе данных. Эта конфигурация ведет себя как переменная среды и поэтому доступна в вашем проекте ASP, который переопределяет appsettings.Production.json.

Если вы знакомы с Docker, вы, возможно, видели, что переменные среды используются повсеместно…

…in Dockerfile:

… при работе с CLI:

… и, очевидно, в docker-compose.yml:

Похоже, кому-то действительно нравятся переменные среды 😃

Аргументы командной строки

И, наконец, кубок за наивысший приоритет достается аргументам командной строки.

Не все используют VisualStudio. Некоторые люди ненавидят сверкающие пуговицы и хотят почувствовать себя Нео из Матрицы. Если вы один из них, возможно, вы знакомы с CLI. У него есть некоторые преимущества, поскольку у вас больше контроля над тем, что вы делаете.

Например, запуск проекта ASP из CLI с указанием среды и передачей некоторых аргументов может выглядеть следующим образом:

Старый добрый launchSettings.json также имеет свойство commandLineArgs для нашего удобства, поэтому нам не нужно указывать их каждый раз. Как продуманно с их стороны 😌.

Итак, теперь мы можем запустить наш профиль с CLI и будут выбраны соответствующие аргументы:

Можем мы? 🤔 Еще раз повторюсь, все было бы не так просто, если бы не Microsoft 😃

Существует известная и нерешенная проблема, заключающаяся в том, что commandLineArgs игнорируются при работе с CLI, в то время как environmentVariables работают нормально. Дорогой, дорогой, Майкрософт, у тебя была одна работа 😌

Лично я не видел, чтобы это использовалось много. Единственные случаи, когда мне это нужно, когда наш конвейер CI требует немного сложной логики, поэтому мне нужно добавить консольное приложение, которое ведет себя по-разному в зависимости от предоставленных вами аргументов. В остальном он вам не понадобится, но все же стоит знать, что он существует и его можно использовать.

ещё немного…

После всего сказанного осталось еще немного. Не волнуйтесь, я знаю, что это был долгий путь, и вы устали, но осталось еще несколько шагов, и мы закончили. Обещаю 😅

То, что мы обсудили, является конфигурацией по умолчанию. Однако вы можете расширить их так, как вам нравится. Например, в одном проекте я видел, как люди создавали отдельные файлы для каждого типа конфигурации, например connection-strings.json, logger-config.jsonи так далее. С другой стороны, мы добавили собственный поставщик конфигурации для Azure Key Vault (по сути, большой словарь в Azure), поскольку все остальные параметры не полностью удовлетворяют наши потребности. В другом случае у нас не было appsettings.Development.json.Вместо этого мы переопределяли некоторые настройки в appsettings.json во время локальной установки.

Просто помните, что вы не ограничены в своих действиях (если только это не запрещено законом 😕)

Заключение

Это была длинная статья, но вы дочитали ее до самого конца. Мои поздравления. Для этого нужно не мало терпения. Кто ты воин? Вы многое видели, многое испытали. Вы мудры не по годам. Вы видели восход солнца, вы видели падение империй, как осуществляется управление конфигурацией в проекте ASP и какие типы существуют; их приоритеты, как их настроить и маленькие дурацкие моменты при работе с ними.

Но не позволяйте гордыне поглотить вас. Ни один человек не является островом. Знания ценны только тогда, когда есть люди, которые ими делятся. Поделись этой статьей с другими и только тогда у тебя на душе будет мир 🧙‍♂️

👏 Хлопаем, если вам понравилась эта статья

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

☕️ Купите мне кофе по ссылке ниже, если хотите получать больше таких

✅ И не забудьте подписаться, если хотите узнать больше о внутренней реализации ASP