|
3 / 3 / 1
Регистрация: 21.04.2023
Сообщений: 14
|
|
.NET 9 Конфигурация json с параметрами вместе с DI .NET11.06.2025, 08:37. Показов 1515. Ответов 10
У меня возникла проблема при конфигурировании приложения с использованием внедрения зависимостей и IOptions<T>. У программы есть конфиг с пользовательскими настройками. Для редактирования настроек пользователь может использовать саму программу, но я допускаю, что любознательный пользователь может хотеть открыть сам файл конфигурации. Для этого я стараюсь поддерживать его в красивом виде. Чтобы это сделать, нужно использовать некоторые опции и атрибуты. К примеру, сериализация перечислений в виде именований, а не значений. Для этого требуется использовать JsonStringEnumConverter, но поставщик конфигурации json видимо это делает за меня. Было бы всё отлично, но с .NET 9 пришла возможность задавать иные имена полям перечисления для сериализации. Для этого был добавлен JsonStringEnumMemberNameAttribute, который поставщик конфигураций json видимо не использует и из-за чего я не могу сделать конфиги еще краше. Мне кажется, что для решения проблемы нужно писать свой поставщик. Может быть я что-то упускаю и у кого-то есть более элегантное решение?
0
|
|
| 11.06.2025, 08:37 | |
|
Ответы с готовыми решениями:
10
Конфигурация приложения .NET. XML конфигурация Как правильно прописать коллекцию в JSON конфигурации appsettings.json? Ошибка при обработке Json - Cannot deserialize the current JSON array because the type requires a JSON object |
|
|
||
| 11.06.2025, 08:52 | ||
![]() Можно использовать не файл в редактируемом формате, а файл локальной СУБД, к примеру SQLite, в него точно просто так не залезешь...
1
|
||
|
3 / 3 / 1
Регистрация: 21.04.2023
Сообщений: 14
|
|
| 11.06.2025, 09:07 [ТС] | |
|
Это был бы подходящий вариант, но я идеалист и стремлюсь к совершенству, я сам бы хотел, чтобы конфиг был красивый, даже если его никогда не откроет ни один пользователь. В данном случае моя идеальность подорвана и я вынужден поинтересоваться о существующих вариантах решения проблемы.
Как я указал в тексте вопроса, мне кажется, что можно написать собственный поставщик. Правильно ли это? Вообще, конфигурации храню в AppData, куда вряд ли залезет пользователь, но хотелось бы совершенства.
0
|
|
|
19 / 18 / 1
Регистрация: 25.05.2025
Сообщений: 39
|
|||
| 11.06.2025, 20:39 | |||
Поэтому мне пришлось самому написать пакеты, которые анализирует любой текст, находят в нём блоки секретов и в рантайме выполняют затребованную операцию: шифруют, расшифровывают или распаковывают все найденные секреты. Всё это делается через сертификаты хранилища уровня Local Machine или Curent User (смотря что указано в настройках конкретного секрета). Сейчас используем эти пакеты во всех наших проектах. А по поводу организации конфигов... Обычно я разношу разные настройки по разным конфигурационным JSON-файлам, сохраняемым в подкаталоге .\Configurations. В рантайме, при построении IConfigurationRoot, загружаю те конфиги, которые либо являются общими для любого окружения, либо соответствуют целевому окружению. В процессе загрузки, через написанный мною метод расширения, выполняю расшифровку всех зашифрованных значений. А при считывании инфы из конфигов всегда делаю биндинги на соответствующие классы. Набор конфигурационных файлов может выглядеть по разному, например:
Саму конфигурацию в DI (Майкрософта или Autofac) я регистрирую просто как синглтон интерфейсов IConfigurationRoot и IConfiguration. Мне пока хватало этого. Да, если конфиг будет отредактирован, то при таком подходе приложение нужно перезапускать, чтобы изменения подхватились. Но мы не часто правим конфиги, поэтому такой вариант использования нас пока устраивает. В процессе детализации главное - вовремя остановиться. ![]() А по поводу енумов... Я предпочитаю, чтобы они в конфигах записывались как реальные имена енум-значений, используемых в коде, без трансформации во что-то более читабельное (меня это будет только сбивать с толку, т.к. придётся постоянно держать в голове: мол записано так, а на самом деле это означает нечто иное, особенно если значения близки по смыслу).
1
|
|||
|
14 / 13 / 1
Регистрация: 13.02.2025
Сообщений: 32
|
||
| 12.06.2025, 03:21 | ||
Кстати, подобных самописных решений у меня много, но в суть в том, что все они работают в комплексе. То есть, начиная новый проект, мне достаточно поставить нужные пакеты и полдела уже готово. Призываю вас создавать для себя комплексные решения — это реально помогает. Так вот к чему я это всё. А к тому, что если вам действительно не хватает существующей реализации, и вы понимаете, что ваша сборка будет вам реально помогать, то ответ "да, почему бы и нет"...
1
|
||
|
14073 / 9290 / 1347
Регистрация: 21.01.2016
Сообщений: 34,877
|
||
| 12.06.2025, 03:36 | ||
|
Ты точно решаешь реальную проблему?
1
|
||
|
3 / 3 / 1
Регистрация: 21.04.2023
Сообщений: 14
|
|
| 12.06.2025, 05:42 [ТС] | |
|
Проблема на самом деле и не совсем в пользователях, на самом деле, как я уже указывал выше, мне просто самому нравится, когда у меня чистый, красивый, опрятный конфиг.
Но я уже написал провайдер, спасибо за советы.
0
|
|
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 12.06.2025, 19:11 | ||
|
Один и тот же объект конфига может быть разбит на части и считываться кусками из разных мест в разных форматах. Через это поставщики не занимаются десериализацией настроек в объекты конфига, они только предоставляют словарь строк ключ/значение, потому на стадии считывания файла конфига поставщик понятия не имеет какой на выходе должен быть тип. Следовательно, конвертеры не используются. Десериализацией этих словарей в объекты уже занимется ConfigurationBinder, который понятия не имеет о формате хранилища откуда они были получены: он работает с ключами вида "Logging:LogLevel:Default" и значениями типа "Information", и использует обычную рефлексию, плюс где может — конвертеры типов (TypeConverter), которые применяет только для конвертации значений терминальных узлов ключа. В примере выше — только для конвертации значения "Information" для свойства Default. Корневой узел и LogLevel создаст через обычный конструктор типа для соответствующего свойства (с небольшими исключениями для коллекций). Если нужна кастомная десериализация, то для указанного типа надо писать свой TypeConverter из строки там уже прописывать нужную логику. В репозитории открыта тема для расширения возможностей настроек этого байндера, но пока как-то вяло: https://github.com/dotnet/runtime/issues/83599
2
|
||
|
|
|||
| 13.06.2025, 07:51 | |||
|
Лол, таки "просто указать правила сериализации" не прокатит. Занятно, хотя с точки зрения абстракций наверное это даже хорошо. Всё же JsonStringEnumConverter находится в совершенно другой сборке, нежели Microsoft.Extensions.Configuration.
IDictionary<string, string?>, а дальше ноль понимания в какую модель потом эти данные будут пихаться. Если глянуть интерфейс IConfigurationProvider, там тоже ноль завязок на тип данных, только строки.Непосредственным распихиванием значений по полям занимается уже ConfigurationBinder, который внезапно static. Я лично не нашел средств надоумить его принять какие-то специфические правила, но смотрел не то что бы подробно. Довольно неожиданно что эту часть нельзя подстроить под свои нужды. ------------------------------ В сетях и всякие AI-chat вообще рекомендуют вводить промежуточную модель, считывать в неё и дальше заниматься мапингом. Не самое изящное решение, но зато железобетонное. Плюс задача не то чтобы рядовая. Обычно фигачать конфиги "как есть" и пофиг как они там выглядят. Я бы даже сказал что различные текстовые значения скорее даже вредят, т.к. усложняют понимание что к чему в процессе сопровождения. Понятное дело что порой источник задаём не мы, а смапить нужно на внутренние модели, то в этом случае я бы тоже разделял т.к. в случае чего поправить мапинг проще, чем ковырять логику с атрибутами. Вовзращаясь к вопоросу ТСа -- написать свой поставщик отличное решение. Хотя лично я бы просто в лоб делал Read - Deserialize - Registration и забил.
2
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 13.06.2025, 11:18 | ||
|
Конвертация на этапе считывания там вида "как представить иерархию json в виде секция:секция:свойство" и "как int из json перевести в строку". А то что это значение в конце должно быть enum — тут уже, как вы подметили, понимания ноль.
1
|
||
| 13.06.2025, 11:18 | |
|
Помогаю со студенческими работами здесь
11
Ошибка при обработке Json - Cannot deserialize the current JSON array because the type requires a JSON object Разница между ASP.NET Core 2, ASP.NET Core MVC, ASP.NET MVC 5 и ASP.NET WEBAPI 2 Распарсить с помощью Json.Net приходящий ответ в виде JSON
Десериализация JSON из ВК без JSON.NET Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|
Фото: Daniel Greenwood
kumehtar 13.11.2025
|
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга,
Ты же видел моря и метели.
Как сменялись короны и стяги,
Как эпохи стрелою летели.
- Этот мир — это крылья и горы,
Снег и пламя, любовь и тревоги,
И бескрайние. . .
|