Andriy Shyrokoryadov

.Net developer, data scientist

№8 Переменные среды в Asp.Net Core [#60].

Текст к видео "Переменные среды Asp.Net Core" на канале YouTube

Привет всем! Сегодня мы поговорим о среде приложения ASP.NET Core. По моему скромному мнению, концепция среды приложения используется в большей степени для конфигурации приложения на основании того, на каком сервере (физическом сервере или на виртуальной машине) данное приложение запущено. То есть в физическом плане среда приложения это конкретный компьютер, конкретная физическая машина на которой запущено наше приложение. В зависимости от того, где запущено наше приложение, мы можем настроить его определенным образом.

У вас может появиться вопрос – зачем каким-то образом привязываться к конкретной машине, к конкретному компьютеру. Данный вопрос имеет смысл. В большинстве компаний, где я работал, процесс разработки приложений выглядел следующим образом.

  1. После получения технического задания программист работает над заданием и после его выполнения, приложение с новой функциональностью было протестировано самим программистом на его локальном компьютере. Давайте назовём этот компьютер «средой разработки».

  2. Если программист после тестирования на локальном компьютере доволен результатами своей работы, то приложение с новой функциональность можно установить на другой компьютер, который предназначен специально для тестов. К этому компьютеру имеют доступ тестеры или бизнес-аналитики, которые тестируют определенную логику. Как правило программист также имеет доступ к этому компьютеру, который предназначен исключительно для тестов. Давайте назовём этот компьютер «средой тестирования»

  3. Если тестеры или бизнес-аналитики после тестирования новой функциональности довольны результатами тестов и, соответственно, результатами работы программиста, они могут подтвердить, что новая функциональность готова для использования конечными пользователями. В этом случае приложение можно установить на компьютер – сервер, к которому имеют доступ конечные пользователи. То есть определенная функциональность отдается в использование пользователям и можно сказать, что создание данной функциональности было завершено. Давайте назовём этот третий компьютер, к которому имеют доступ пользователи, «производственной средой»

Каждая из этих вышеназванных трёх сред может иметь определенную конфигурацию. Опций конфигурации может быть превеликое множество. Всё зависит от того на сколько наше приложение большое и сложное. Самым простым примером опции конфигурации, которая может зависеть от среды, является настройка доступа к базе данных. Так называемый connectionString. Я думаю, здесь нет необходимости дополнительно объяснять почему программисты, тестеры и конечные пользователи должны иметь разные базы данных. А если объяснение всё-таки необходимо, то в двух словах можно сказать, что если программисты и тестеры будут иметь доступ к базе данных конечных пользователей, то они, т. е. программисты и тестеры, могут ненароком испортить данные конечных пользователей. В этом случае конечные пользователи будут очень недовольны. Как правило очень хорошей практикой является ограничение доступа программистов и тестеров к производственной среде приложения.

Ну а теперь собственно ответ на вопрос – зачем привязывать конфигурацию приложения к конкретной машине. Если Ваше приложение очень маленькое и имеет буквально пару настроек, то разбитие конфигурации на несколько сред фактически не имеет смысла – вы только себе подкинете побольше работы, результаты которой никто не увидит. Однако, если вы работаете с большим приложением – разбитие разработки приложение на несколько этапов или сред это единственный путь для достижения успеха. Как правило таких этапов 3: разработкатестированиеустановка и использование. И каждый из этапов происходит в отдельной среде, то есть на отдельном компьютере и с определенной конфигурацией, которая зависит от среды.

Теперь у вас может возникнуть вопрос – а как наше приложение знает в какой среде оно запущено? Это тоже хороший вопрос. Для определения среды используются так называемые переменные среды или на английском environment variables. Переменные среды – это переменные, которые, по сути, не привязаны только лишь к приложению ASP.NET Core. Это переменные, которые задекларированы глобально на уровне операционной системы или на уровне конкретной сессии. Это значит, что если вы знаете, как называется переменная среды, то вы можете получить доступ к её значению из любого приложения, запущенного в операционной системе или в определенной сессии. Приложение ASP.NET Core ищет среди множества переменных среды 2 конкретные переменные:

  • первая из них это DOTNET_ENVIRONMENT;
  • а вторая – это ASPNETCORE_ENVIRONMENT когда при создании хоста вызывается метод ConfigureWebHostDefaults. По умолчанию в шаблоне веб приложения ASP.NET есть вызов метода ConfigureWebHostDefaults. Переменная ASPNETCORE_ENVIRONMENT надписывает значение переменной DOTNET_ENVIRONMENT.

На основании значений одной из этих двух переменных среды приложение ASP.NET Core определяет в какой среде оно запущено и в зависимости от значения переменной считывает определенные настройки характерные для данной среды.

Чуть ранее я привел пример разработки приложения с тремя средами: среда программирования, среда тестирования и производственная среда. Так сложилось, что эти 3 среды уже предопределены во фреймворке ASP.NET Core и они имеют определенные названия:

  • Development - разработка. Файлe launchSettings.json приписывает значение Development переменной ASPNETCORE_ENVIRONMENT на локальном компьютере разработчика.
  • Staging – эта среда используется как правило для тестирования
  • Production – производственная среда. Если переменным DOTNET_ENVIRONMENT и ASPNETCORE_ENVIRONMENT не приписаны значения — это среда по умолчанию.

Доступ к значению среды в приложении осуществляется через свойство EnvironmentName объекта класса, который реализует интерфейс IWebHostEnvironment. Данный объект внедряется в виде зависимости в методе Configure класса Startup.

Предположим, что в проекте, над которым вы работаете, вы решили использовать специфические названия сред или серверов. Такое также бывает. Я видел проект, где в качестве названий среды использовались имена героев космической оперы «Звездные войны». В этом проекте производственный сервер назывался DarthVader. Так вот – на каждом сервере Вы можете самостоятельно и глобально приписать значения переменным среды DOTNET_ENVIRONMENT и ASPNETCORE_ENVIRONMENT. Так как Asp.Net Core это кроссплатформенная среды – это означает что такие переменные можно определить в различных операционных системах: Windows, Linux и MacOS. Данное видео, как и все остальные, снимается с использованием операционной системы Windows, поэтому я покажу как приписать значение переменной среды в данной операционной системе.

В системе Windows 10:

  • Откройте меню «Старт» и найдите пункт «Изменение системных переменных среды».
  • В появившемся диалоговом окне необходимо нажать кнопку «Переменные среды…». Она находится в самом низу диалогового окна.
  • Появится окно с 2 списками переменных: переменными пользователя и системными переменными.
  • Добавьте переменную для пользователя нажав соответствующую кнопку «Создать…». Появится окно с двумя текстовыми полями для названия и значения переменной.
  • После добавления переменной необходимо выйти из системы и зайти обратно определенным пользователем, чтобы переменная была загружена в память.

В системе Windows 10 проверить наличие определенной переменной среды можно из командной строки вызвав команду «echo %VARIABLE_NAME%». Если переменная существует, то на экран консоли будет выведено её значение. Если переменная не существует, то на экран будет выведено название переменной, обрамленной знаком процентов.

Во время запуска приложения из Visual Studio некоторые настройки считываются из файла launchSettings.json. В этом файле также приписывается определенной значение переменной среды ASPNETCORE_ENVIRONMENT. Это значение надписывает значение переменной, которое мы определили в памяти. Поэтому если мы хотели бы использовать значение из памяти, приложение Asp.Net Core необходимо запустить само по себе без VisualStudio.

Как уже было сказано ранее в зависимости от переменных среды мы можем определенным образом настроить наше приложение. Есть еще более элегантный способ использования переменных среды. Наше приложение может использовать несколько файлов StartUp. В фреймворке Asp.Net Core существует определенная конвенция названий. Если мы назовем какой-то конкретный класс StartUp названием StartUp{название_среды} и компьютер, на котором будет запущено данное приложение будет иметь переменную среды со значением {название_среды}, то при запуске будет использован класс StartUp{название_среды}. Я чувствую, что моё объяснение немного запутанное. Приведу пример. Если у нас есть 3 среды нашего приложения: Development, Staging, Production, то мы можем создать 3 класса StartUp, которые будут называется StartupDevelopment, StartupStaging, StartupProduction. И зависимости от того, какая среда у нас определена Development, Staging или Production, у нас будет использоваться соответствующий класс StartUp при запуске приложения. Также в этом случае желательно иметь класс StartUp, который просто называется StartUp – этот класс будет использоваться по умолчанию, если на основании переменной среды не был подобран соответствующий класс StartUp или переменная среды не была определена. Если данной объяснение всё еще непонятно, то давайте рассмотрим практический пример.

Эти же правила применимы и к методам в файле StartUp. То есть у вас будет один класс StartUp в котором задекларированы не только 2 стандартных метода ConfigureService и Configure, но и специфические версии вышеуказанных методов для определенных сред. Например, для 3 сред из примера у нас могут быть 3 метода ConfigureDevelopment, ConfigureStaging и ConfigureProduction. То же самое с методом ConfigureService – будет 3 версии: ConfigureDevelopmentService, ConfigureStagingService и ConfigureProductionService. Обратите внимание что в случае метода ConfigureService название среды добавляется в середину названия между словами Configure и Service. Также неплохо всегда оставлять методы по умолчанию без названий среды ConfigureService и Configure, они будут использованы если подходящий для среды метод не был найден или переменная среды неопределенна.

Что можно сказать еще о переменных среды? Стоит помнить, что одно определенное одинаковое значение переменной среды может быть добавлено на несколько серверах. Это означает что при прочих равных условиях наше приложение на этих серверах будет сконфигурировано одинаково. Например, у нас будет 2 тестовых сервера с одинаковым значением переменных DOTNET_ENVIRONMENT и ASPNETCORE_ENVIRONMENT. Это нормально. Наше приложение должно быть настроено одинаково на этих двух серверах.

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

Пример кода из видео на GitHub

Для открытия файла проекта необходимо Visual Studio 2019.