Корпорация Microsoft и open source сообщество сделали для нас уже готовую конфигурацию для консольных приложений включающую расширенную комплексную конфигурацию, а так же ряд дополнительных инфтсрументов.
Давайте попробуем воспользоваться им:
В папке с нашими уроками введите команду:
dotnet new console -o lesson08
Заменим код Program.cs на:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using var host = Host.CreateDefaultBuilder(args).Build();
var config = host.Services.GetService(typeof(IConfiguration)) as IConfiguration;
var firstWord = config!["AppSettings:FirstWord"];
var secondWord = config!["AppSettings:SecondWord"];
var version = config!["AppSettings:Versions:0:Number"];
Console.WriteLine($"{firstWord} {secondWord} {version}");
Создайте новый файл appsettings.json в том же каталоге, что и ваш файл Program.cs.
{
"AppSettings": {
"FirstWord": "Hello",
"SecondWord": "dotnet",
"Versions": [
{
"Number": 7
}
]
}
}
Создайте новый файл appsettings.Development.json в том же каталоге, что и ваш файл Program.cs.
{
"AppSettings": {
"Versions": [
{
"Number": 8
}
]
}
}
В консоле перейдите в папку с проектом.
Установим зависимость через dotnet cli:
dotnet add package Microsoft.Extensions.Hosting --version 7.0.1
Добавление пакетов отразится в файле lesson08.csproj
Вместо имени файла укажите шаблон appsettings*.json в csproj, все файлы подходящие под него будут копироваться в директорию при сборке проекта. Давайте добавим нужную настройку в lesson08.csproj.
<ItemGroup>
<Content Include="appsettings*.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Должно получиться следующее:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings*.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
В этом уроке мы используем готовый шаблон проекта доступный через установленную зависимость Microsoft.Extensions.Hosting, она реализует всё, что мы делали в прошлом уроке сами и даже намного больше, но об этом уже в следующих уроках. На что тут стоит обратить внимание:
Для использования статического метода CreateDefaultBuilder класс Host мы импорировали Microsoft.Extensions.Hosting.
Мы использовали ключевое слово using перед var, это означает что объект возвращаемый методом Build объект реализует интерфейс IDisposable и после того как все ссылки на host пропадут, автоматически будет вызван метод Dispose объекта host.
<aside>
🐕🦺 Подробней про оператор using можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/statements/using.
</aside>
<aside> 🐕🦺 В целом про интерфейсы можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/interface.
</aside>
<aside>
🐕🦺 Про интерфейс IDisposable можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/api/system.idisposable?view=net-7.0.
</aside>
Интерфейс IConfiguration это интерфейс объекта config который мы использовали последние несколько уроков (обычно мы заменяли его ключевым словом var и он вычислялся из правой стороны выражения).
<aside>
🐕🦺 Про интерфейс IConfiguration можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/api/microsoft.extensions.configuration.iconfiguration?view=dotnet-plat-ext-7.0.
</aside>
Ключевое слово is приводи объект к типу если такое возможно иначе возвращает null и ключевое слово typeof - позволяет вернуть тип объекта по названию его класса или интерфейса.
<aside>
🐕🦺 Подробней про ключевые слова is и typeof можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/operators/type-testing-and-cast.
</aside>
Метод GetService возвращает объект по типу из провайдера добавленных в приложения сервисов.
Оператор прощения null - ! в записи config!["AppSettings:Versions:0:Number"] подсказывает анализатору компилятора, что хоть и оператор as выше может вернуть config как null, но фактически такое не возможно, так как в Services всегда есть зарегистрированная реализация IConfiguration. В зависимости от настроек проекта в *.csporj отсутствие оператора ! может привести либо к предупреждению при сборке либо к ошибке во время сборки.
<aside> 🐕🦺 Подробней про это можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/compiler-messages/nullable-warnings#possible-dereference-of-null.
</aside>
Запустите приложение с полным набором параметров:
DOTNET_ENVIRONMENT=Development \
AppSettings__Versions__0__Number=9 \
dotnet run AppSettings:Versions:0:Number=10
Вы получите вывод:
Hello dotnet 10
Можете поэкспериментировать и удостовериться что всё работает так же как в уроке 7.
<aside> 🐕🦺 В этом уроке мы впервые познакомились с готовой конфигурацией консольных приложений. Она позволит нам иметь всю мощь комплексной конфигурации одной строчкой. Подробней про это можно почитать тут https://learn.microsoft.com/ru-ru/dotnet/core/extensions/configuration.
</aside>
<aside> 💡 Решение доступно тут https://github.com/vahpetr/lessions/tree/main/lesson08
</aside>