Это копия, сохраненная 18 июня 2023 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
— https://dotnet.microsoft.com/learn
— https://ru.stackoverflow.com/a/416585/422180
— https://metanit.com
— https://professorweb.ru
2. С# для веб
— https://docs.microsoft.com/ru-ru/aspnet/core
3. C# для десктопа
— https://docs.microsoft.com/ru-ru/dotnet/desktop
4. С# для игр
— https://ru.stackoverflow.com/a/609901/422180
5. С# для мобильной разработки
— https://docs.microsoft.com/ru-ru/dotnet/maui
6. Годные ютуб-каналы
— https://www.youtube.com/c/CODEBLOG
— https://www.youtube.com/c/AndreyShyrokoriadov
— https://www.youtube.com/c/DevJungles
— https://www.youtube.com/user/Shmachilin
Шапка: https://pastebin.com/HT7Hi6FD
Прошлый тред: >>2582351 (OP)
>Вообще. Я чет стал за 10 лет коммерческой разработки - каким-то хуйлом, если честно. Все чаще ловлю себя на мысли, что большая часть "правил", это какой-то карго-культ.
>
>Хороший код, это простой-понятный код, который решает задачу здесь и сейчас и который можно выкинуть нахуй, как только задача поменяется.
Я тоже спустя много лет пришёл к таким выводам.
Ну и выкинул код. Это ж просто. В этом и суть хорошего кода
xaml работает из коробки и можно заюзать прям Application.xaml, создающийся по-умолчанию. А json это больше для веб и asp.net.
Я видел как в ридер джейсона пихали класс и он как-то сам автоматом заполнялся. Это что-то из разряда сериализации?
смешались люди кони огурцы
xaml это не xml и с жсоном сравнивать нельзя
храни настройки как душе угодно.
не было никакой опечатки ибо ты упомянул Application.xaml (который на деле App.xaml)
Нельзя сравнивать потому что xaml не является форматом данных. Это как спрашивать "в чем лучше хранить конфиг - в html или в json"
XAML (eXtensible Application Markup Language) - язык разметки, используемый для инициализации объектов в технологиях на платформе .NET.
Конфиги храни в json. Используй newtonsoft json из nuget.
зачем использовать эту либу, если в дотнете уже есть искаропочное решение?
да, ньютон мощнее по фичам....но это же просто конфиг.
Хз, я привык нютон использовать. Но в целом может и дефолтный парсер использовать. Не знаю у него можно отключить регистр при парсинге полей? Можно ли для дебага вывести json в виде отформатированной строки.
конечно.
new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
WriteIndented = true
}
На SO я видел ответ типа "не заморачивайся с джейсонами, храни настройки Application.xaml", но там выглядело как словарь, и чтобы получить свойство, нужно было ввести текстовый ключ. Т.е. уже это выглядит как неудобная хрень по сравнению с десериализацией в готовенький класс.
>в чем лучше хранить конфиг - в html или в json"
Я имел ввиду контекст удобства работы. Мб какой-то парсер имеет ограничения или еще что, или что-то делается одной левой пяткой.
Так это реальный кейс как раз с завода, чел.
Подключена куча устройств по всяким модбасам, хуясам, snmp, mqtt, куча хуйни через один модем который к ком-порту подключен. В среднем на объекте - 100-200к всяких устройств, это через которые идет опрос, к ним еще могут быть куча подключены, нужно получать данные со всего этого частотой не реже 1 секунды на каждое конечное. Нужно управлять этим делом и т.д.
Так вот. Если ты ставишь "архитектуру" выше стабильности работы и этих самых секунд- ты идешь нахуй. Это просто.
Попробуй, блин, добиться этого, а потом покажи, как будешь через PLC, COM, радио - делать абстрактне запросы, к абстрактным устройствам с абстратными чтецами.
ничего этакого ты не описал, самая обычная задача где ничего не мешает архитектурить. Ну или хз что ты подразумеваешь под словом архитектура.
>делать абстрактне запросы, к абстрактным устройствам с абстратными чтецами.
Я перечитал задачу. она?
"Система опроса с очередями. Логика была простой: устройство - воркер, воркер пытается опросить устройство, сохраняет результат опроса в базу. Все изначально просто - по TCP общаемся без особых проблем.
Ок. Все норм. 10к потоков спокойно опрашивают че там надо.
Теперь - у нас есть COM-порты, через один COM-порт подключено 2к устройств.
Давай, объясняй, как твой DI поможет решить проблему того, что нельзя пытаться открыть из разных потоков один и тот же COM-порт. "
DI решает проблему "не нужно ручками фабрики писать". Для одного конкретного случая это "ну зачем", но приложение обычно куда больше и количество РАЗВЕСТИТЫХ new ЧтоТо(new "nj...) прилично так растет и если все собрать в класс SuperFactory, то там будет много строчек. И при наведении там порядка получишь то, что за тебя сгенерит DI. Правда DI еще даст менеджмент временем жизни.
А если вопрос стоит "ну и как тут сделать с абстракциями" - ну тоже просто. общий воркер, IDevice и куча реализаций для каждого девайса. из разных потоков нельзя открыть - ну а как ты решаешь этот вопрос. вот тут так же. Архитектура не решает алгоритмы - она позволяет сделать код чище (чтобы ты работал с более высокими абстракциями), упростить сопровождение (добавление нового устройства ничего не сломает и возможно даже не нужно будет переписать ни строчки старого кода)
каждый ConcreteDevice не живет в вакууме. Есть какой нибудь контекст, который с ним ассоциируется, а уж там может быть общий семафор для ограничения конкурентного доступа, и контекст синхронизации для того чтобы в одном потоке жить. Ну или запилить "точки доступа" через которые и будут опрашиваться девайсы и уж там будет вся защита от толкотни и многопотока. И про конкретную особенность работы с конкретным физ девайсом будет знать только сам класс ConcreteDevice и более никто. Как бы системе похер COM порт там или баба зина - ей хватает знания "нужно выполнять в том же потоке и плевать кто это". Воркеру тоже похер - он получает данные и передает их бд.
ничего этакого ты не описал, самая обычная задача где ничего не мешает архитектурить. Ну или хз что ты подразумеваешь под словом архитектура.
>делать абстрактне запросы, к абстрактным устройствам с абстратными чтецами.
Я перечитал задачу. она?
"Система опроса с очередями. Логика была простой: устройство - воркер, воркер пытается опросить устройство, сохраняет результат опроса в базу. Все изначально просто - по TCP общаемся без особых проблем.
Ок. Все норм. 10к потоков спокойно опрашивают че там надо.
Теперь - у нас есть COM-порты, через один COM-порт подключено 2к устройств.
Давай, объясняй, как твой DI поможет решить проблему того, что нельзя пытаться открыть из разных потоков один и тот же COM-порт. "
DI решает проблему "не нужно ручками фабрики писать". Для одного конкретного случая это "ну зачем", но приложение обычно куда больше и количество РАЗВЕСТИТЫХ new ЧтоТо(new "nj...) прилично так растет и если все собрать в класс SuperFactory, то там будет много строчек. И при наведении там порядка получишь то, что за тебя сгенерит DI. Правда DI еще даст менеджмент временем жизни.
А если вопрос стоит "ну и как тут сделать с абстракциями" - ну тоже просто. общий воркер, IDevice и куча реализаций для каждого девайса. из разных потоков нельзя открыть - ну а как ты решаешь этот вопрос. вот тут так же. Архитектура не решает алгоритмы - она позволяет сделать код чище (чтобы ты работал с более высокими абстракциями), упростить сопровождение (добавление нового устройства ничего не сломает и возможно даже не нужно будет переписать ни строчки старого кода)
каждый ConcreteDevice не живет в вакууме. Есть какой нибудь контекст, который с ним ассоциируется, а уж там может быть общий семафор для ограничения конкурентного доступа, и контекст синхронизации для того чтобы в одном потоке жить. Ну или запилить "точки доступа" через которые и будут опрашиваться девайсы и уж там будет вся защита от толкотни и многопотока. И про конкретную особенность работы с конкретным физ девайсом будет знать только сам класс ConcreteDevice и более никто. Как бы системе похер COM порт там или баба зина - ей хватает знания "нужно выполнять в том же потоке и плевать кто это". Воркеру тоже похер - он получает данные и передает их бд.
Ничего ограничений не имеет. Кому что нравится. Студия поддерживает app.config где ты в редакторе набацал и она сама за тебя классы сгенерит. Ну и на себя возьмет разделение по юзерам. формат там хмл и руками править его ну нах. В общем то это для случаев когда конфиг редактируется в самом приложении.
ини - поддержки нет, ну можно через вызов неуправляемого кода. Тут самому пилить придется все остальное
Аналогично жсоны, ямлы, томлы - есть сериализаторы, ими читай, сохраняй. чуть проще чем с ини ведь сериализатор сразу может выдать граф объектов.
Решение от мелких, то которое в новом асп - ну это классика, читаем многие файлы разных форматом, мержим их, мержим с переменными окружения и бац можем превратить в объекты а-ля десериализация жсон. для случаев когда конфиги правят именно ручками и они ридонли. ну и да - раз нет прямого чтения жсона то и не работают конвертеры (ниудобна)
Так что бери что хочешь. Ну да, кроме первого решения тебе придется ручками накодить классы (ну или сгенерить из жсона - есть такие генераторы) ну и написать много гетсет тупых чтобы поддерживала INPC, ну а свой ConfigurationManager это и в яслях напишут.
Блять блин, опять что-то сломалось. Или я как-то сломал. Попозже пересоздам проект, мб опять что-то неправильно выбрал
Xamarin - норм тема, или лучше для проги на телефоны использовать более подходящие языки (Java/Kotlin)?
Скорее удобством и возможностями
Скорее удобством и возможностями
Это я уже смотрел - всё на месте. Ещё установил EF core в другой проект, тоже консольный и тоже не работает. Чё за параша
А restore для нугетов делал? Целевой фреймворк нужной версии?
>>02945
Ну и вообще. Просто попробуй по гайду https://learn.microsoft.com/ru-ru/ef/core/get-started/overview/first-app?tabs=netcore-cli
Потом посмотри, чем у тебя отличается.
щас посомтрю. Просто на asp core всё работает, а на консолке что-то не пашет
Кажись нашёл в чем проблема. Я создаю обычное .NET, а нужно .NET Core, но у меня его нет в списке
Если ты про последние версии, котрые от 5 и выше. То теперь просто Core решили больше не писать, чтобы не путать людей.
Потому, теперь у нас есть:
.Net Framework
.Net Standard
.Net Core
И просто
.NET, который является Core просто без слова Core
Кароч у меня жопа сгорела))))) Завтра переустановлю Visual Studio. Ибо хз, что тут делать
При этом, когда пишу любую команду из EF ничего не работает. Пишет, что отсутсвует ссылка на сборку при том, что она есть
У меня так документ с кодом не видит документ с xaml, как будто второго не существует. Имеется ввиду два partial документа. Хз как это править, приходится удалять .vs и тогда пересобирается норм.
Мне бесит, что студия порой сама принимает решение и хер ты че ей объяснишь. На какой-то божьей сопле это все крепится.
А еще студия может с нихуя начать ругаться на комментарии в xaml, пишет, что содержатся запрещенные на территории РФ недопустимые символы. Фиксится пересозданием нового документа и копипастингом содержимого.
Какая версия студии у тебя?
Не заёбывайся, делай как проще.
С доменчика сделать запрос к азуре? А чтобы другие не могли щемисться заведи секретный ключ, который азура будет чекать при получении запроса.
Скрины запроса в сваггере и скрин контроллера
> Может есть у кого ссылки интересные?
Нужно побольше информации о Unity. Он сейчас очень сильно продвигает c# в геймдеве.
Ты не в ту сторону воюешь.
Юнити нахуй никому не всрался.
Даже если я устанавливаю биндинг как DynamicResource, то чтобы поменять цвет, я должен обратиться к ресурсу конкретного элемента, навроде this.Resources("MyButtonColor") = Colors.Orange;. И если у меня 100500 окон, я должен пройтись по всем окнам и у каждого отредактировать ресурсы. Потому что я не знаю как мне влезть в оригинальный файл ресурсов и поменять значение там. Все что я могу — это создать новый экземпляр ресурсов.
Даже та тема с SharedResourceDictionary проблемы не решает. Все что я нашел в сети: а нахуй тебе это нужно? Создавай еще один набор ресурсов. Что, реально в 2к23м можно оперировать только темами, но нельзя указать конкретный цвет?
Последняя моя идея заключается в том, что раз у меня MVVM, то создать экземпляр ResourceDictionary во вьюмодели, а потом биндить его на все окна. Хз как это будет работать, но есть прям отдаленные участки, куда рука вьюмодели по любому не дотягивается — придется передавать по цепочке как Owner Window.
У тебя хроническое словарно-ресурсное заболевание. Будь твоя воля - ты бы и логику и базу данных в словарь ресурсов запихал.
у тебя есть конфиг любого вида - в нем хранишь цвет, все настраивамое биндится к этому конфигу. Изменение цвета в конфиге вызовет INPC биндингов и значение изменится.
Заодно и хранить в файлике можно
С вьюмоделью не прокатит, она поступает позже инициализации элемента.
>>04826
>Будь твоя воля - ты бы и логику и базу данных в словарь ресурсов запихал.
В смысле? я делаю ровно то, для чего словари ресурсов якобы предназначены. Это то, что мне советовали применить, если есть куча стилей.
>у тебя есть конфиг любого вида - в нем хранишь цвет
Ок, у меня есть стиль кнопки. Как стиль получит цвет из конфига?
>Даже та тема с SharedResourceDictionary проблемы не решает
ну вообще то позволяет добраться до всех словарей. у словаря можно менять данные. как об изменении уведомлять всех - хз. я словари не редактирую.
>Как стиль получит цвет из конфига?
<Setter Property="Background" Value="{x:Statin Settings.UI.FooBarColor}" />
или Binding если это INPC конфиг
>>04838
Короче, для теста создал статический класс с базовыми цветами, так сказать.
Далее в ресурсах я свой список базовых кистей сбиндил по типу
<SolidColorBrush x:Key='ActiveColor' Color='{Binding Source={x:Static L:BaseColorsSource.ActiveColor}}' />
Были небольшие траблы с биндингом к статическим свойствам. Теперь достаточно изменить свойства до запуска окон, и все обновится. Над ток все это согласовать с конфигом.
Да, спасибо, так и сделал. Можно и без биндинга? Норм.
Мне надо только менять на стадии загрузки.
>Можно и без биндинга?
Вообще тут смотреть нужно. Без биндинга по идее не будет изменений трекать после создания стиля (хотя и с биндингами ну будет только стиль меняться, а будут ли элементы где стиль применен - хз). Также еще если биндинг не OneTime и не INPC, то будет утечка. Но это ж если к свойству, а тут биндинг вроде ко всему объекту сразу.
>если биндинг не OneTime
А какой тогда прок, если суть биндингов в реализации изменений в риалтайме?
У меня такая структура получилась:
- Статическое свойство хранит в себе экземпляр INPC-класса со списком всех базовых цветов.
- Далее ResourceDictionary имеет список экземпляров кистей, которые биндят цвета.
- А стили уже биндят эти экземпляры кистей. Я как-то для себя условился, что я не буду шатать экземпляры.
Кстати, у меня и без DynamicResource произошло обновление цветов.
Ну понятно, что я меняю цвет в экземпляре одной и той же кисти, но кто инициирует перерисовку? И для чего тогда нужен DynamicResource?
Чтобы оно было не обязательным - нужно указать значение по умолчанию.
>А какой тогда прок, если суть биндингов в реализации изменений в риалтайме?
если ты делаешь обновляемый биндинг не к DP или INPC, то у тебя будет утечка памяти. Вместо подписки на PropertyChanged он там творит магию с PropertyDescriptor чтобы следить за изменениями и получается жесткая ссылка
А вот так
{Binding Source={x:Static L:BaseColorsSource.ActiveColor}}
получается биндинг на сам объект и как бы свойства нет и я честно не знаю как он тут следит за обновлениями
Это ж не
{Binding ActiveColor Source={x:Static L:BaseColorsSource}}
где все понятно.
>если ты делаешь обновляемый биндинг не к DP или INPC, то у тебя будет утечка памяти. Вместо подписки на PropertyChanged он там творит магию с PropertyDescriptor чтобы следить за изменениями и получается жесткая ссылка
Ах, вот оно че? Обычно мне не дают привязать к свойству, если оно не DP или INPC, а словарь даже не задал вопросов.
>{Binding Source={x:Static L:BaseColorsSource.ActiveColor}}
>{Binding ActiveColor Source={x:Static L:BaseColorsSource}}
Отличие есть в VisualBasic. Дело в том, что там отсутствуют статические классы в принципе, можно делать только статические методы, поля и свойства.
Есть, конечно, Module, но это специфический тип.
Поэтому если статическим является ActiveColor, то правильным будет первый вариант, а второй выдаст ошибку.
Я не прошу советов. Я просто поныть хочу.
Вот чому это так сложно-то? Вообще, в такие моменты возникает мысль, что проще самому сделать. Пиздец.
Вот простая связка, гит-нексус-дрон, казалось бы. Пиздец сколько попоболи это все сделао. А ведь нужно еще чтобы масштабироваться.
Я просто хуею. Как же привык к тому, что у майков все из студии делается. Пиздец как не весело - ебаться с сертификатами, ебаться с конфигами жавовской хуйни, ебаться с безопасниками, которые втихаря подсирают, а узнаешь про это когда все перепробовал, и все вроде верно, а потом - ой, мы на тебе новую систему проверям))).
А так - вы няши. Я вас люблю. Надеюсь, вам - никогда не придется с этим ебаться самим, а прийдете на все готовое.
- IsoCurrencyCode
- А вот тут как: CurrencyAmount | PriceInCents | PriceInCurrency
У тебя в приложении юзаются какие-нибудь другие коды валют, кроме ISO? Если нет, достаточно CurrencyCode, без лишних уточнений, что ISO.
Единица какой-то валюты - это НЕ разменные денежные единицы, т.е. никаких центов, копеек и пенни, только доллары, рубли и фунты. Разменные единицы обозначаются дробной частью с точностью до двух знаков после запятой, там, понятное дело, никаких флоатов и даблов, только decimal.
Количество называй как хочешь, хоть CurrencyPrice, хоть CurrencyAmount, хоть CurrencySum.
Попытался сериализовать Color и ожидал на выходе HEX, вроде #FF34FF0C или 0xFF34FF0C (в идеале int, но и стринг сойдет)
В итоге он мне забубенил пикрилейтед, где каждый канал ARGB записывается в отдельный параметр, да еще зачем-то записал ScR и ему подобное, что является представлением того же R, к примеру.
Т.е. у макрософтовского сериализатора нет анализа своих же типов, для него Color — это какой-то нонейм. Ну и как адекватно с этим работать?
Итак, гуглим JsonConverter
Перекидывает на MSDN
Так что там?
Пишут "Выберите версию .NET"
Ага. Выбираем .Net6
Так шо там ебана? Экземпл, ну давайте скопируем
Ага, четам? Один из параметров имеет тип Utf8JsonReader
@
ОшибкаBC30668"Utf8JsonReader" является устаревшим: "Types with embedded references are not supported in this version of your compiler."
Спасибо .Net6
у тебя горячка
>где каждый канал ARGB записывается в отдельный параметр
и правильно сделал. он сериализовал поля, что в общем то сериализаторы обычно и делают. ваш кэп
>Т.е. у макрософтовского сериализатора нет анализа своих же типов
как раз анализ и позволяет сериализовать. другое дело нет встроенного конвертера для Color по очевидной причине - этот тип не встроенный, а сериализатор не должен тянуть за собой зависимость от всего на свете. (мелкие даже DataMember не поддерживают именно по этой причине)
и правильное и единственное решение - использование кастомного конвертера. Он для этого как бы и придуман и пишется за пару минут.
но ты поищи поищи
Го подтверждать скилы друг друга на ликдине
https://www.linkedin.com/in/artur-ilinyh/
Короче, все примеры касательно джейсона для бейсика юзают Newtonsoft.
>нууу тот кто выбрал визуал бейсик с его синтаксисом
При чем тут синтаксис? Просто майкрософт забили хуй.
Вот и пришли к выводу, что выбрать. Посмотрю наскольк грузная эта либа, и наверно начну рассматривать вариант с xml.
Я тут погорел с того, что CI/CD сложно настраивать. И у меня мысля возникал.
Че если я просто на гитхабе залью dokcer-compose того что получилось, чтобы 1. Потом можно самому было брать. 2. Чтобы другие меньше страдали.
Связка какая: Gitea, Nexus Repository, Drone CI, Nginx. Хотя если никому не всралось - то и тратить время не буду. На работе - конфиги-то есть.
никто не спорит чть ньютонсофт более богатый по фичам
потому и более тяжелый и более медленный и более срет в душу GC
тут уж кому что важнее - фичи или скорость.
>Просто майкрософт забили хуй.
Ну таки да. Они его развивают по инерции и по принципу, чтобы было хоть что-то. Просто народ настолько уже привык к ньютонсофту, что многие родной майковский даже никогда и не пробовали за всю жизнь.
Они просто подождут еще несколько лет, купят его себе и встроят заместо своего собственного.
Чел, майковскую либу разрабатывает автор newtonsoft.
На хабре видел обзор. У ньютнсофта и майкрософтовского примерно сопоставимые скорости. Впереди там jet.
всех по скорости и по аллокациям всех порвет SpanJson
а так потребление памяти и скорости не равны. не знаю где ты там смотрел.
А в каком месте хранится оригинал? Я вот щас полазил по вским программам и не вижу копий данных в program files
Им не обязательно храниться отдельными файлами, можно хоть логикой в коде генерировать.
>А в каком месте хранится оригинал?
В том же где хранится твоя мамка.
Извини не удержался.
На самом деле и правда - там где хочешь. Где тебе наиболее удобно их будет менять при необходимости. Я обычно храню в виде дефолтных значений полей самих settings классов.
Начал искать эту тему заново, все уперлось в DependencyInjection, начал смотреть про DI, а там нужен паттерн AbstractFactory. Все как снежный ком начинает обрастать сложностями, что навело меня на историю одного товарища, который работал слесарем в одном Мухосранске. Короче там пытаются любую проблему, любую течь решить при помощи деревянного чопика, и когда течь начинает подмывать ранее установленный чопик, в этот чопик вбивают еще один чопик поменьше.
Почему в случае простых простых работяг это называют халтурой и безответственностью, а у программистов и математиков наукой?
await _db.User.AddAsync(entity);
await _db.SaveChangesAsync();
И всё, ничего не происходит
>await _db.User.AddAsync(entity);
>await _db.SaveChangesAsync();
Оберни в try catch посмотри что за исключение.
Пофиксил всё вот этой строкой AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
Это конечно хорошо, но давай мы будем подбирать инструмент под задачи, а не выдумывать задачи под инструмент. Прямо щас мне нужно сделать плагин для десктопного софта.
Какая у тебя каша в голове просто капец. На ровном месте находишь проблемы. НЕТ никаких рамок ни в WPF (который типа легаси) ни в asp.net по логгированию и конфигу. Тебе может быть предложено решение искаропки, но это не значит что "все атас другое сложно".
Если предлагается дефолтное решение - оно не значит лучше. Тот же DI от майков убогий (ни тебе декораторов, ни тебе условий, ни перехвата - НИХРЕНА) и его встроенность только мешает использовать более крутые DI, а решение по конфигу не дает использовать сложные типы в конфиге (кто там про Color жаловался - а вот хрен что он тут сделает без ручного пердолинга), логгинг как бы тоже на любителя ибо все равно прикручивается что то типа Nlog/Serilog. А дефолтный майкологгер даже в файл писать не может (ну да да, файл типа не нужен, ага ага, типа 12 правил ну да нуда))))
Городить ему что то блин надо. WPF это просто окна и биндинги смотрящие на DataContext - и все. Городи КАК УГОДНО.
Можешь взять стандартное решение по конфигу, можешь из ASP.NET (правда оно ридонли же), можешь хоть свое сделать за полчаса там сооружается банальное Load/Save -> Settings.Default.MyProp
Сложнее разве что из за наличия самого UI если тебе нужно красиво аснхронно что то типа IHostedService, ведь нужно же что то пользователю показывать что мол "не висит оно, а штатно запускается или выгружается" при старте и выходе, но опять же WPF тут не причем как бы. UI на то и UI
>>08033
ну вот WINUI типа не легаси, Там что то другое в этом плане? ой нет ). Наверное потому что легасность WPFа в другом. Да и вообще легаси это понятие растяжимое - вон про тот же жсон типа легаси, но вот только его замена явно слабее по фичам. DI от майков тоже слабее - но "жричодали". Просто пошли другим путем, но это не значит что старые пути стали плохие. не стоит забывать про "фатальный недостаток". Как бы те же майки и кнопку пуск убирали, типа она легаси )))))))))
>а там нужен паттерн AbstractFactory
Нахуй такие сложности. Используй IOptions и не еби себе мозг.
Не, чувак, ты не пофиксил, ты просто подпер свой говнокод костылем и радуешься.
От слова Legacy ничего в твоем межушном нервном узле не зашевелилось? Ну или о том, что везде где это про этот способ пишут, приписывают, что пользоваться этим не стоит и оно нужно исключительно для того, чтобы какой-нибудь совсем старый говнокод не развалился при его обновлении.
Пиздуй читать как правильно хранить дату/время в БД, почему хранить их там в Kind:Local - это ублюдство и как правильно решать такие вопросы в EFCore и в постгресе.
1 IOptions тот который в ASP.NET - вообще крайне спорное решение. Противоречит принципу fail fast
2 Там в принципе нет сохранения настроек
>ибо все равно прикручивается что то типа Nlog/Serilog
Так они все работают по схеме DI. Мне и нужно для сохранения в файл.
>Городи КАК УГОДНО.
99% туторов по конфигурации и логгированию идут в контексте DI. Но учитывая объем сделанного, проще написать свой логгер и воркер с сеттингами, чем перелопачивать всё под DI.
В моей голове мысль, что раз все юзают через DI, то может не стоит использовать иначе? Примеров масса, с теми же подписками или биндингами, когда игнорирование правил может привести к утечке памяти.
>>08102
>Нахуй такие сложности.
Ну я начал гуглить про DI, естественно большая часть описывается для ASP.net. Я начал искать примеры для WPF, и в одном туторе чел реализует DI и запускает mainWindow. А потом добавляет, мол "если вы захотите запустить из этого окна кучу других окон, то хуй вам. Для этого вы должны реализовать AbstractFactory для всех окон."
Как я понял, при такой системе любой пук оборачивается в сервис и запрашивается у хоста этих сервисов.
> Ну я начал гуглить про DI, естественно большая часть описывается для ASP.net. Я начал искать примеры для WPF, и в одном туторе чел реализует DI и запускает mainWindow. А потом добавляет, мол "если вы захотите запустить из этого окна кучу других окон, то хуй вам. Для этого вы должны реализовать AbstractFactory для всех окон."
https://www.youtube.com/live/AkJ52O3cgi0
Шапка для чего?
Первый вариант очень сильно шатает производительность и при асинхронности не гарантирует правильную последовательность записи событий. Но второй подход может не гарантировать финальную запись, тогда является ли отлов необработанного исключения 100% гарантией записи? Может ли приложение обмякнуть без жидкого пука на последок?
А еще при втором подходе засрется память.
Этот стрим я видел, да. Я по нему MVVM учил, но весь остальной "мусор" тогда проигнорил. Ща пересмотрю.
Все логгеры которые я видел пишут в файл сразу.
Опять же сорцы nlog и serilog есть на гитхабе. Возьми и посмотри как все устроено.
>Может ли приложение обмякнуть без жидкого пука на последок?
Конечно. Свет отключили и прощай все твои логи.
>В моей голове мысль, что раз все юзают через DI, то может не стоит использовать иначе?
DI настолько стал стандартом и настолько (относительно) прост, что написание собственной реализации, даже в промышленном коде - это норм. А вот неиспользование DI - вызывает большие вопросы.
Это какое-то расширение или так в старых версиях VS было? Я имею ввиду визуализацию цвета кисти в виде полосы. У меня в студии всегда был квадрат слева.
Ты бы знал сколько итераций переписывания испытал мой проект за эти полгода — просто потому что я получаю знания по ходу его написания. Но эти переписывания уже выглядят как акт бесконечной дрочки кода. Уместнее так называемое саморазвитие оставить для других проектов.
Это, конечно, мои проблемы.
Хорошо, когда ASP тебя ставит перед фактом на этапе загрузки шаблона, в WPF все более неочевидно.
>Хорошо, когда ASP тебя ставит перед фактом на этапе загрузки шаблона, в WPF все более неочевидно.
Зачем ты учишь и то и то?
По моему найти сейчас вакансию, где бы использовались оба фреймворка тот еще квест.
Решарпер
Я учу только WPF, и профессия у меня другая.
Я вообще десигнер и пишу плагин для своего графического пакета. Формально, я могу забить хер на все эти правила — имею право, но раз начал, то хочется совсем уж не говнокодить.
А начинал я проект с Windows Forms, потом мне понадобилась графика и прозрачный фон — я перешел на WPF, потом когда говнокод разросся, пришлось переписывать на MVVM. Щас гуглю про конфиги и логгирование и упираюсь в DI, которое при гуглении тыкает носом в ASP.
Больше никакой связи с ASP, собсно, и нет.
Вот хочу попробовать сделать приложенице с помощью WPF, но есть вопросик. Вот мне нужно переключенице между вкладочками как, например, в сиклинерчике, ну или в стимчике. Это реализовывается с помощью страничек или по-другому? Просто во всех говногайдиках делают одностраничные приложеница и нихуя не понятно.
Спасибо
>приложенице
>вопросик
>вкладочками
>стимчике
Второй дизайнер в треде и один анимэшник. Куда делись программисты?
>Это реализовывается с помощью страничек или по-другому?
Тебе краткий путь или долгий?
Краткий: делай как тебе удобно. Ты можешь поместить содержимое куда угодно, хоть в Grid, и даже в кнопку — в этом суть WPF. Есть тонкости, о которых лучше узнать по ходу, чем забивать себе голову сейчас. Page это весьма специфический контрол.
Долгий: скорее всего тебе придется узнать про такие темы, как:
- Bindings, потому что на твоих страницах скорее всего будет куча элементов, которые нужно как-то связать либо между собой, либо с базой данных.
- Паттерн MVVM, чтобы не ебстись с привязкой кучи данных вручную
- XAML Styles, чтобы нарисовать няшные вкладочки.
Потому что вопросик-то у тебя простенький, но за ним спрятаны нюансики.
>Просто во всех говногайдиках делают одностраничные приложеница и нихуя не понятно.
А в гайдиках получше, гайдиков штук десять и все длинной по 4 часа.
Можешь начать https://youtu.be/uMNYu0p3MP4?list=PL-p05fYs48r-HOAA4_5qZfS0rTIka3fgc
Но сперва накидай хотя бы рыбу своего приложеньица.
>Так они все работают по схеме DI
чушь. ты должен где то сконфигурить и как то получить там где используешь
в Nlog вообще нет проблем доставить логгер на нужное место
>99% туторов по конфигурации и логгированию идут в контексте DI
элементарно пишется использование на коленке
>что раз все юзают через DI, то может не стоит использовать иначе?
DI удобен как автофабрика. так что почему бы не использовать.
и он прост как валенок. Хотя конечно сидеть на стульях "мы хотим создавать вьюмодели внутри других вьюмоделей и в то же время не иметь там контейнер" сложновато
>>08245
как сконфигуришь логгер так и будет.
>элементарно пишется использование на коленке
Но не элементарно интегрируется в существующий проект.
Наверно я пока еще не осознал до конца суть DI. Я видос досмотрю, который анон выше скинул, потмо сделаю выводы.
Суть DI ты понимаешь
Тебе сложно использовать контейнер, ведь контейнер не должен быть везде чтобы не быть сервис локатором. И тут в mvvm сложнее, ведь одни вьюмодели порождают другие, те еще свои. И там время жизни разное ведь это не асп где время жизни запрос.
А примеры сплошной примитив.
Какой ты вредный, н за совет спасибо. Переделал немного сущность user. Теперь заместо DateTime использую DateOnly, а добавляю так: DateOnly.FromDateTime(DateTime.UtcNow. Теперь работает без той заглушки
>Какой ты вредный
Но совет то дал же.
На самом деле в EF можно еще добавить кастомный ValueConverter на уровне контекста, который будет все приходящие ДатыВремя автоматом переводить в Utc перед записью в базу и/или после вытаскивания их оттуда. И тогда вообще забыть о таких заморочек и просто подразумевать, что все что у тебя в коде крутистя всегда в Utc
> рыбу
Бля, последний раз слышал это слово в таком значении от своего препода в вузе. Тоже к слову был шарпистом.
Можно просто написать скелет. Ясно и понятно.
В интернете на вскидку пока ничего не нашел по делу. Восстановление студии в инсталере не помогло. Инстанс студии загружал с админа. У кого-то подобное было?
Майки - прославленные говнокодеры.
А ты всегда как на выставку пишешь? То что тебе не нравится необязательно говнокод. Если
0. Работает
1. Читабельно
2. Поддерживается
3. Развивается
то это просто обычный код, а не для того чтобы дядя Боб похвалил или очередные хипстеры, в зависимости от того какая у тебя референтная группа.
> 0. Работает
Работает то работает, но нет базовых функций, давно реализованных в сторонних либах.
> 1. Читабельно
Мимо. Почти нет комментов, функции внутри методов и тд. Пиздос полный.
> 2. Поддерживается
Переменные с именами V, U, v, u...
> 3. Развивается
Последняя обнова в ноябре 21 года... Для малейшего изменения логики приходится все переписывать с нуля, чем я сейчас и занят.
https://www.youtube.com/watch?v=IXRGa5m-Lbo
>у студента что-то не работает
>DI оказывается дотационный
>премудрости MVVM
>разметка окна в WPF
Не перестаю проигрывать с этих животрепещущих тем. И после этого "джава хуевая, потому что медленно развивается и там сплошное легаси". Ага, то ли дело у нас, у шарпистов: ехало мввм через впф. Хорошо, хоть фанатам формочек хватает самоиронии, чтобы не скатывать тред в обсуждение премудростей биндинга лист бокса к коллекции объектов.
Разве это достойно серьезной задаче? Кстати, какие задачи решают настоящие джависты?
Все бэкендеры делают одно и то же: грузят жсоны в базу.
Так, вроде начинаю въезжать. Каждый сервис требует набор каких-то других сервисов, поэтому они начнут существовать как только это кому-то понадобится. Если окну нужны данные из файла, то он запросит сервис данных и тот инициализируется.
Короче, тут главное на стадии инициализации четко обозначать какие еще сервисы нужны конкретному сервису. Но чет мне подсказывает, что очень легко зафакапиться.
К примеру у меня пока нет никакой защиты от того, что ресурсы стилей начнут тащить данные базовых цветов из статического класса (как я упоминал раньше). А тащить он начнет как только загрузится первое окно.
Наверно этот класс надо сделать еще одним сервисом, который требует сеттинги. Легко сказать, но это статический класс, а ресурсы лезут прямо в свойства этого класса. Никакой инициализации по сути там и нет.
Разве это достойно — бисер перед свиньями метать?
Почему ты проецируешь лично мои локальные проблемы на всех шарпистов? Ты ебанутый?
Спасибо за ответ.
> MVVM
На первый взгляд выглядит как просто усложнение кода. Мб, если столкнуться с проблемами, которые решает мввм, то я передумаю. Но сейчас, те плюсы, которые дает этот паттерн, мне особо не нужны. Мне, по сути, требуется 5 вкладок в одном окне, по которым можно переходить по кнопкам из шапки. Что-то вроде tabcontrol, но его я использовать не хочу. Пока что думаю страницы впихивать во фрейм.
TabControl, где каждая вкладка View. И mvvm не забудь.
>На первый взгляд выглядит как просто усложнение кода.
Зависит от сложности контента на твоих страницах. Если там полторы кнопки, то не нужно, а если у тебя куча данных, особенно списки всякие, да еще и общие — чтобы изменив в одном месте автоматом поменялось в другом, то без MVVM будешь городить пикрилейтед.
>Пока что думаю страницы впихивать во фрейм.
Фрейм изолирует контент. Опять же, если ты не будешь юзать биндинги, а делать в лоб, то разницы вообще никакой. Тот же Grid делает ровно тоже самое, разве что там нет стрелочек навигации, которые ты первым делом и отключишь.
Не усложнение, а структуризацию
Даже без MVVM крайне глупо закатывать солнце вручную и не юзать биндинг
а уж поверх биндинга это логическая надстройка как и MVC, то есть "где что лежит"
по факту даже в мелких приложухах часто проще добавить классы с INPC, а не делать спагетти. А потом родится и класс ViewModelBase и RelayCommand что проще копирнуть в новый проект чем писать по старому
Даже если у тебя один таб контрол - даже там удобнее.
>окну не должны быть нужны из файла
Да не, у меня там менеджер окон (в новых реалиях будем называть это сервисом окон). Раньше он при инициализации обращался к сервису чтения данных и получал экземпляр вьюмодели, а потом распихивал её в датаконтексты окон.
Пикрил — схема моего проекта.
Есть три вьюмодели. Если проводить параллели с Visual Studio, то главная вюмодель — решение. Внутри решения список дочерних вьюмоделей — проектов. Внутри каждого проекта есть дочерняя вьюмодель в виде иерархии элементов.
Пока что у меня вьюмодели больше выглядят как контейнер данных, а не сервис.
>На первый взгляд выглядит как просто усложнение кода
На самом деле, упрощение поддержки за счет отсутствия прямой зависимости между моделью и вьюхой (ну и небольшой профит в предсказуемости связей).
Достаточно актуальный на сегодня кейс: представь, что тебе нужно сделать с проектом (который изначально на WPF), чтобы он заработал на Linux, потому что немалая часть заказчиков начала перекатываться. С MVVM ты заменяешь слой вьюх и, если не повезет, придется поправить биндинги в VM
главное чтобы твоя логика не была в code-behind окон
и окна напрямую не лезли в модель, а через вьюмодель
(вид не должен знать чего как - он транслирует хотелку вьюмодели и отрисовывает изменение состояния). Вот и весь MVVM
очень простая концепция.
и ты правильно описываешь параллеи
и так то вьюмодели больше и есть контейнер данных для отображения. Вообще конечно во вьюмоделях и команды есть, но по хорошему они должны быть как тонкие контроллеры. Или даже отдельно сделать контроллеры ибо вьюмодели очень любят быть жирными из-за этого
ого, удачно ошибка замазала телеграм токен
Необходимо подключить консольное приложение (как пример), к Prometheus, чтобы тот забирал метрики и выдавал, условно, "температура". Знаю, что такое можно делать с ASP.Net через подключение соответствующих библиотек, потом давать доступ в конфиг прометеусу и он уже будет сам все подсасывать. Но проблема заключается в том, что начальник хочет посылать топики в MSQTT, тот в свою очередь (как я понял) в прометеус. Я не совсем понимаю, как это реализовать, в инете говорят про умный дом, либо esp'шки всякие.
В моем же случае, это: Стенд -> запросы на сбор конкретных метрик -> MSQTT -> Prometheus.
Может кто знает толковую статью или пример проекта? Буду очень благодарен. Если что-то не ясно пояснил - извиняюсь заранее, сам с трудом понимаю, что от меня хотят и что учить.
Ты пишешь кеш в MemoryCache который создал через AddMemoryCache() и прокинул в services, а получить пытаешься из нового: считай записал в один Dictionary, а читаешь из другого.
Тебе надо либо через GetService получить этот конкретный мемори кэш там же где ты пишешь, либо в сервис эту логику вынести и автоматом получать через конструктор как на пике 1.
Установленные sdk вообще не выводились, хотя я уже руками качал .net sdk и ставил. Короче оказалось что при установке в системные переменные среды в Path оно записывает два пути к х86 и затем к x64 версии. Нужно было х64 поднять приоритетом вверх и ребутнуть пеку. Спасибо анон.
берешь идею, реализовываешь на какой-то дотнет технологии, деплоишь на хостинге, продвигаешь в поисковиках, монетизируешь, получаешь деньги
Никак, Startup.cs больше нет в 7 дотнете.
У меня была ровно та же проблема и на SO писали, что надо переопределять стиль под новосозданный класс. А у автора даже Path в свойстве Style прописался и не задал вопросов.
А, ясно это не будет работать только для применения стиля по типу, а не по ключу (хотя мне казалось, что я так пробовал).
>Фрейм изолирует контент. Опять же, если ты не будешь юзать биндинги, а делать в лоб, то разницы вообще никакой. Тот же Grid делает ровно тоже самое
А как в таком случае? Делать много гридов в одном окне и просто их скрывать? Да, я тупой, это можно не сообщать.
>Да, я тупой
Ты не тупой, просто неопытный. Все задавали ровно те же вопросы.
>Делать много гридов в одном окне и просто их скрывать?
Во-первых, в окне ты можешь создать только один элемент. Каждый UI-элемент может (должен) содержать в себе контент в виде других элементов, но есть те, которые могут содержать только один элемент, к примеру это Window, Frame, Border, Button. А есть элементы, которые могут содержать в себе коллекцию, типа Grid, StackPanel, DockPanel, Canvas, ListView.
Поэтому ты не сможешь в Window положить кучу гридов (можешь сам проверить), зато ты можешь в Window положить один грид, а внутрь грида положить хоть сотню страниц. Собсно, в стартовом шаблоне, внутри Window помещен Grid именно по этой причине.
Так же и с Frame, если тебе надо положить туда 10 страниц одновременно, то ты во Frame сперва помещаешь Grid, а уже в этот Grid свои 10 страниц.
WPF это чистейшая матрешка. Ты можешь в кнопку поместить StackPanel, а внутрь этой панели поместить кучу страниц.
Во-вторых, ты сам выбрал себе этот "легкий" путь, кек. Поэтому да, вот такие кривые вещи тебе придется делать и ломать голову.
По поводу твоей пробелмы:
1й вариант.Ты можешь опять же в грид запихнуть все свои страницы разом и потом попеременно включать видимость нужной.
2й вариант. Ты можешь хранить список страниц в коде, а потом брать страницу из этого списка и помещать ее в контейнер. Не обязательно в грид, а точнее в этом случае нахер тут не нужен. Возьми любой контейнер, поддерживающий только один элемент, к примеру Border. Тогда замена содержимого будет выглядеть как-то так:
MyBorder.Child = MyPages(2);
Ну и навалил же я кучу, только запутал. Пожалуй остановлюсь, ибо дохрена чего еще.
непонятна твоя проблема
обычно к списковому контролу биндится коллекция к ItemsSource и в DataTempate итевом автоматически попадает нужный элемент этой коллекции как DataContext
>Установленные sdk вообще не выводились, хотя я уже руками качал .net sdk и ставил.
Ты в курсе, что в инсталлере студии есть вкладка с доп. компонентами, через которые можно поставить любой нужный sdk и runtime, плюс еще дохрена всяких приблуд. Я уже лет 5 ничего руками не докачивал и не ставил, только через инсталлер.
вообще смену контента делают через ContentControl если конечно тебе не нужно хранить фокус где то внутри страницы при переходе вперед и назад.
а Frame - для мазохистов.
А еще внезапно TabControl пересоздает же вьюхи при переходе. и все фокусы летят в одно место. И нужно гуглить спец реализацию без пересоздания
А еще Popup по факту Topmost=true, хотя непонятно зачем. И опять же нужно юзать кастомные реализации
это ж мелкие - они умеют делать говно.
>А еще Popup по факту Topmost=true, хотя непонятно зачем.
Я при помощи него делал выпадающую шторку как в смартфонах и контекстное меню по ЛКМ. И там не надо морочиться с автоскрытием по клику за пределами формы, что нетривиальная задача с опцией AllowTransperency.
@
Весь день настраиваешь ему окружение
@
Всю ночь пытаешься сбилдить
@
НЕ СОБИРАЕТСААААА!!!!!!!!111
(Нугет не находит пакеты, которые хз откуда брать)
Финиш )
Вообще есть ли смысл обратно вкатываться в ынтырпрайз на Шарпе, если последние года 3 винду видел только на картинках?
Дали тестовое - все норм, код понятный, что делать - тоже понятно, но где брать сраные библиотеки, которые он требует при сборке - хз. Сижу под vscode с плагинами С# и vscode-solution-explorer. Плачу над проебанным на все это днем (((
прибежали в избу дети
второпях зовут отца
тятя! тятя! нет в нугете
и не собираетса!!!
если их нет в нюгете значит они либо рядом лежат как длл
Не было. Качал по названиям либ, подключал вручную. Вроде норм теперь. Но авторы, конечно, могли бы хоть намекнуть, где их искать.
И не будет.
> Вообще конечно во вьюмоделях и команды есть
Так и есть у меня. Всегда считал команды частью вьюмодели, но тут смотрю восьмой стрим Шмачилина и вижу пикрилейтед. Он создает команду, где внутри создает экземпляр окна. Разве так можно?
Я делал так. У меня была аналогичная задача с выводом окна настроек по команде. Что я делал? Я во вьюмодели создавал событие что-то уровня "RequestShowSettings" и все что делала команда — это вызывала событие и её вообще не волновало есть ли окно или нет. А вот само окно настроек когда принимало вьюмодель, искало данное событие и если находило, то подписывалось на него.
Ну вот как бы я так решил проблему, а тут оказывается не зашквар пихать вью во вьюмодель.
> Разве так можно?
судя по всему он использует их в xaml напрямую. То есть это особые команды. так можно.
во вьюмоделях он использует LamdaCommand что еще называют RelayCommand/DelegateCommand
А вот CollectionViewSource во вьюмоделях уже неправильно.
ведь в отличие от INPC он лежит в сборке вида System.Windows.Data
Ты провалил проверку на софтскилы. Вместо того чтобы просто спросить "где пакеты брать, бля ?", ты сидишь и дрочишь в углу, пытаясь самостоятельно решить проблему и теряя время.
ну значит автор не разбирается
А в чем проблема создать под уникальную страницу свою уникальную вьюмодель?
>А в чем проблема создать под уникальную страницу свою уникальную вьюмодель?
В целом проблем нет.
Год назад полно было вакансий со всякими раббитами, кафками и прочими в требованиях. А сейчас все это пропало. Или это просто hrы поумнели и всякое сторонее говнище в JD больше не пишут.
Ну вот, к примеру, я сейчас смотрю как Павел Шмачилин создает сервис диалогового окна. Его решение состоит у него из одного проекта и проблем вроде как нет.
В моем решении сервис окон — это отдельный проект, есть даже окна как отдельный проект и в каждом окне может быть штук 10 диалоговых окон. А вместе это целый зоопарк.
Можно при регистрации, к примеру, сервиса окно, чтобы он по ходу сам зарегистрировал n сервисов связанных с диалоговыми окнами? Или это нарушает DI?
Наверно нарушает — придется лазить по всему решению и подчищать эти сервисы, если что вдруг.
Вот не нравится мне, что все в одной куче.
Картинка для напоминания. У меня почти каждый сервис — это отдельный проект.
в реализации контейнера от майков тебе нужно сбилдить контейнер же. И после этого в этот контейнер ты не зарегаешь же ничего.
В других контейнерах возможно и потом, но лучше все регать на старте.
>чтобы он по ходу сам зарегистрировал n сервисов связанных с диалоговыми окнами? Или это нарушает DI?
ну так ведь так и делается.
когда ты пишешь services.AddFeature то там же целая куча всего регается.
Ты это можешь делать и в динамике - на старте пробежаться по сборкам (что усложнили) и попросить каждый модуль зарегать все что ему нужно.
Точняк, спасибо. Буду знать теперь.
LoginWithIosDeviceId
LoginWithIOSDeviceId
LoginWithDeviceId_iOS
Третий вариант мне нравится больше. Если есть много схожих функций, то я предпочитаю неизменный текст отделять от меняющегося — так удобнее категоризировать.
LoginWithDeviceId_iOS
LoginWithDeviceId_Win
Если только это не название класса.
Ну, все читаемо.
При указании директории для сборки показывает ошибку (я помню что это началось чуть ли не в Net Core 3). И вот уже Net7, а директорию по прежнему приходится править вручную в .vbpropj
Хочу сменить точку входа. Что за хуета на пикрил? Какой Form1? У меня WPF, Net7, по дефолту точка входа Main.
Как же заебало это некроговно, пиздец просто.
На пикрил он создает экземпляр App, который является наследником System.Windows.Application
... и его инициализирует.
А откуда, собсно взялся метод InitializeComponent?
В Application его нет. Класс App пустой.
App это наследник Application
наследственность задана через App.xaml
посмотри на окна или юзерконтролы - классы там partial
тут тот же принцип
>В App.xaml нет, в App.xaml.cs нет.
Имею ввиду, что там отсутствует код добавления InintalizeComponent.
Но если обратиться к App, то он волшебным образом присутствует.
он появится если у тебя будет App.xaml вида
<Application x:Class="MyProject.App"
что сделает App наследником Application
попутно этот хамл СГЕНЕРИТ partial СВОЮ часть класса App с методом InitializeComponent
xaml же описывает наследование и реализацию partial класса, вторая часть этого partial класса есть code-behind
Но если ты смотришь на CV19, то это бредово вообще совмещать WPF и HostBuilder
1 protected override async void OnExit(ExitEventArgs e) ждать не будет пока там хост сервисы завершит корректно
2 пока вообще стартуют завершаются сервисы и вдруг это долго - пользователь должен гадать "висит али нет"
это гуи. тут нужно сплэшскрин пока все стартует.
Ясно. У меня в бейсике произошел наверно уже классический сбой, когда code-behind не видит xaml. Соответственно, не видит InitializeComponent и я не мог понять в чем проблема. И главное это никак не пофиксить.
Вот из особенностей бейсика
В шарпе App : Application
В бейсике Application : Application
В code-behind класс не указывается как partial и что он наследует Application. Практически нет ничего, чтобы указывало на реальные дела.
Я планировал сплешскрин, но я думал, что HostBuilder нужен до старта приложения. На SO видел что у некоторых возникали проблемы.
>protected override async void OnExit(ExitEventArgs e) ждать не будет пока там хост сервисы завершит корректно
У меня до DI был свой менеджер завершения приложения, так что тут норм все. Просто сейчас я пока еще юзаю DI скорее как заклинание.
на скринах все неправильно же
вот как нужно
синей стрелкой - там еще пишут наследование и решарпер ругается что reduntant
>>12169
хост билдер ему нужен чтобы юзать его возможности - типа чтение конфига (можно напрямую и без хоста, да и для WPF такой конфиг не особо полезен), запуск остановку сервисов - опять же элементарно без него. Ну может там что то и с папками я хз. В общем лишняя приблуда, что насыпает кучу длл в проект, а польза сомнительная.
У него в App.xaml
StartupUri="Views/Windows/MainWindow.xaml">
и поэтому ему нужен ViewModelLocator
и получается async метод OnStartup() работает бесполезно параллельно
я предпочитаю другой подход. всегда удаляю StartupUri и все делаю в OnStartup где после того как сделал все нужное создаю осовную форму и вьюмодель.
попутно могу там создать и 2 окна, и невидимые окна и сплэшскрин который будет работать правильно.
... причем если начнешь лезть в это дело, то у студии крыша едет.
К примеру, у когда набирается штук 20 partial классов в связке с xaml, то начинает то тут то там возникать ошибки, мол code-behind класс не видит метод или свойство из xaml-части.
Я этот проект доделаю и срулю с бейсика. У меня уже сил нет.
>всегда удаляю StartupUri и все делаю в OnStartup где после того как сделал все нужное создаю осовную форму и вьюмодель.
Можно ставить просто Startup и тогда указывается путь к желаемому методу. А StartupUri это если у тебя одно окно и больше никаких сервисов. Хотя я смотрел в App.g и там по сути генерится подписка на событие Application.Startup.
>В общем лишняя приблуда, что насыпает кучу длл в проект, а польза сомнительная.
У меня в принципе все так приблизительно и было устроено — был общий хаб из кучи сервисов, которые я называл у себя менеджерами. Иначе бы у меня просто не заработало, когда каждый сервис — это отдельный проект.
мелгомягкие опять обосрались с оптимизацией
Бля ... а я думаю чет одной буквы не хватает.
540x960, 0:15
Вопрос 1. Есть два View, один главный, в котором находятся кнопочки и второй, в котором находится контент. Когда жмёшь кнопочку в главном, то меняется значение в глобальной переменной. В зависимости от значения отрисовывается контент во втором View. Проблема в том, что он не самообновляется и контент отрисовывается только один раз. Как сделать так, чтобы при нажатии кнопки/изменении переменной, рефрешился контент во втором View?
Вопрос 2. Во втором View в файле xaml.cs у меня написана всякая логика, которая что-то делает/отрисовывает новый контент на странице. У меня есть ещё файл с классом и логикой, из которого дёргаются дополнительные функции. Как мне в этот файл с классом передать Grid/Row/Column из View, чтобы использовать внутри классовых функций методы типа gridRowName-Children.Clear(), gridRowName.Children.Add(name) ?
Шмачилин как раз буквально месяц назад выложил ролик на эту тему.
https://youtu.be/XG2reVjcNTs
> Проблема в том, что он не самообновляется и контент отрисовывается только один раз.
Во-первых, ты реализовал биндинг? Ты же не меняешь значение напрямую?
Во-вторых, у твоего биндинга какой режим? По-умолчанию он односторонний.
Я заметил, что если у связываемых свойств разные данные, то биндинг ломается. Т.е. могу предположить, что у тебя односторонний биндинг и с той стороны, где нет обновления, ты меняешь свойство — с этого момента с другой стороны ломается биндинг. Либо у тебя биндинга вообще нет. Лиоб у тебя стоит режим биндинга OneTime
мимокрок
обычно реализации INPC проверяют на дубликаты. То есть важно как именно обновляется свойство
но у автора не MVVM, а значит пусть страдает
вот смотрите на него - наглядный пруф что в впф можно как в винформсах и нафиг те формсы нужны
Я так и начинал, лол. Я вообще в впф перешел по принципу "винформс, где можно кнопочки вращать".
>>12520
Ну смотри, с этого момента начнется Ад, все девять кругов, если не встанешь на путь истинный. С MVVM — всего лишь пару кругов. Все что ты должен уяснить, это не менять параметры напрямую, иначе будет пикрилейтед 1.
Ты должен погуглить что такое биндинги. Это связывание двух свойств, и меняя одно, автоматом меняется другое, после чего у тебя перестает болеть голова по поводу того как все это обновить. Погугли конкретно эту задачу и отработай ее на тестовом проекте.
Для этого нужны специальные свойства, точнее свойства обмазанные поверх еще кодом. Два варианта:
1. как анон пишет INPC, что расшифровывается как INotifyPropertyChanged. Суть проста: нужное событие кроме того, что сохраняет значение, еще и вызывает событие, мол "пацаны, я тут обновляюсь", и все пацаны, которые подписались на это событие, тоже автоматом обновляются. Вот как ты подписываешься на событие нажатия кнопки (наверно), тоже самое делают свойства, но делают они это автоматически.
Здесь ты должен еще уметь не только подписываться на события, но создавать и вызывать их.
2. Это DP или DependencyProperty. Этот вариант в основном нужен для элементов интерфейса. Т.е. все вот эти свойства в кнопочках, типа Background, Width, Height, Margin и т.д. — все это Dependency Properties. И вот когда ты меняешь разметку xaml и у тебя автоматом меняется данные в окне Свойств — это заслуга привязок к Dependency Properties.
Короче, гугли:
- Events. Создание, вызов и подписка.
- INotifyPropertyChanged (тут бы еще в интерфейсы вникнуть, но пока пох)
- DependencyProperty
Наверно у них есть статистика по числу пользователей. Щас бы в проприетарной студии шатать авалонию.
Ты случаем не полупокер?
А райдер не проприетарный? Чо несёт...
Благодарю
а мелкие считают что авалония обладает фатальным недостатком
Поставил, оно только подкидывает свойства контролов. Хайлайт на уровне просто xml схемы, автокомплит не видит методов в код бихайнд. Сам фреймворк выглядит круто, то что нужно моей тиме. Но если поддержка в вижаке только такая то это печальная хуйня - верстать ui в голом xml это шиза.
Вопщем написал Binding текста к тыканию кнопки. Но у меня кнопка и Лейбл с текстом на разных страницах/View/xaml файлах. Когда всё в одном файле то работает, текст изменяется, когда в разных ничего не происходит. Может там пути какие-то по особому прописать надо?
Уно тоже чекаю сейчас, мы уже работаем с WinUI 3. В авалонии просто много хороших синтаксических плюшек в xaml добавили как я успел увидеть в доке (обращение к родителю через индекс, например), а WinUI 3 чот дубовый, xaml времён wpf. Некоторые вещи делаются только через анальное сальто.
У кнопки подписка на метод CloseClick, а линия ведет к методу ClickSecondResult. Это не ошибка?
Можешь то нибудь вывести на печать в методе ClickSecondResult и что нибудь при присвоении value в Content и посмотреть в каком месте отвалилось.
Ну или точками останова.
>в xaml
Я, блин, не понимаю как вы это дерьмо вообще используете. Да еще и выбирать можете где эта куча говна менее пососная.
Мимо бэкэндер.
Через силу, потому вечно в писках.
Бэкендер проходи мимо.
Вот когда встанет у тебя вопрос необходимости гуи вот тогда и приходи померяемся... удобством
И я не понимаю, юзаю няшные винформы, описываю контролы декларативно в коде через инициализаторы.
Да, сорян, уже залипаю. Но сути особо не меняет. В консоле показывает что на кнопку всё нормально биндится и вэлью обовляется, но обновлённый текст дальше в элемент в другом View не выводится.
Я имею ввиду те метки, что юзер добавляет на сообщение в яндекс почте
>Вот когда встанет у тебя вопрос необходимости гуи вот тогда и приходи померяемся
Ну я как раз таки и ушел в чистый бэкенд, чтобы даже длинной палкой эти ваши гуи не трогать, так что не померяемся.
Какой 'хайп', ты о чем? Иди пей свой смузи зумерок и не отвлекай взрослых дяденек от работы.
Сейчас на хайпе голанг и зумеры реально схавали язык с дизайном из 1970
так не путай теплое с мягким.
сам ведь свои слова не в консоли написал, а значит гуи таки нужен. И если бы ты был фронтендер то твои слова имели бы смысл, а так ты просто пукнул в лужу.
>значит гуи таки нужен
Ты сам с собой что ли разговариваешь? Никто не говорил, что гуи не нужен. Разговор был об уебищности xaml-like синтаксиса.
А я сказал "приходи с альтернативами - померяемся"
Сам я не люблю хамл, но альтернативы какие? Описание в коде, как винформс генерит? Сразу нах.
Хтмл... ммм тот же хмл
MVU стиль... как там в мауи новое
Неплохо,но шарп беден на выразительность
И вообще то что норм для мобилы - мало для десктопа
Что осталось? А ничего
А ты с чем пришел....
Странно, тогда как место расположения кнопки может влиять на обновление данных, если проблема во вьюмодели? Ты же вьюмодель не пересоздаешь нигде, никуда не перемещаешь? Она подхватывается вообще?
>ушел в чистый бэкенд, чтобы даже длинной палкой эти ваши гуи не трогать
А мог бы предложить свой вариант решения проблемы, вместо того, чтобы убегать от нее. Но видимо ты можешь только кукарекать.
>А мог бы предложить свой вариант решения проблемы, вместо того, чтобы убегать от нее.
А еще голодающих детей в Африке накормить.
Надо было сделать язык разметки в стиле шарпкода.
У меня как минимум две претензии к хамл:
1. нет инкапсуляции
2. ебешая мусорная вложенность даже на малейший пук.
3. почему если возникает ошибка в xaml, программа не останавливается на этой ошибке, а идет дальше, где совершенно очевидно будет все очень плохо и куча исключений.
Где-где, а в стилях я бы мигом реализовал DI. Сейчас, если у меня отвалится стиль, то посыпется весь проект. Я не могу проект сделать по настоящему модульным. Я не могу вычленить проект из одного решения и вставить в другой чисто из-за стилей.
Зачем? Сконцентрируйся на одной задаче и решай ее. Ну или отойди в сторону и не бухти.
Все знают, что хуета, просто лучшего не придумали.
>Надо было сделать язык разметки в стиле шарпкода.
помню в разных языках делали разметку для хтмл типа так
h1{
p{...}
}
сильно взлетело? так это только разметка же.
а xaml это не разметка, а декларативное выражение кода. иначе будет как в (ну на жс я не пишу, поэтому для меня это андроид - xml лежат отдельно и связывает все это code-behind - и там и там гора текста). Почему хмл, а не DSL - тут хз. Но что есть то есть.
>1. нет инкапсуляции
непонятно о чем это. в code-behind все есть, а то что генерит xaml - наружу то и не просачивается так чтобы где то мешал
>2 ебешая мусорная вложенность даже на малейший пук.
по факту полный эквивалент кода на шарпе. так что вложенность она от самой природы "что хочешь изобразить"
основная претензия должна быть "нереальная простыня же"
>3 программа не останавливается на этой ошибке
ошибка в хамл не прокатит. ошибка в биндингах прокатит и другие исключения глотает. что не гуд, но это не хамл, а WPF такой.
>Я не могу проект сделать по настоящему модульным
ну с этим проблема в design-time. тут они сделали херню...как и со стилями.
>>Надо было сделать язык разметки в стиле шарпкода.
вот я буквально ссу кипятком от выразительной мощи jetpack compose. но это не шарп.... а шарп...это шарп. его new, отсутствие инлайн функций, отсуствие функций без классов и много чего другого сильно ограничивает. Даже в мауи они пошли по пути "делаем как swift combine" что лучше чем ничего, но по факту "мы сделали как могли".
Для мобилок покатит, для десктопа увы.
> что не гуд
Как раз таки гуд. Смысл крашить приложения из-за пары не прогрузившихся биндингов?
не гуд. в итоге каждый метод который привязан к команде я вынужден оборачивать в try..catch, даже если это пет проект.
>непонятно о чем это.
>по факту полный эквивалент кода на шарпе. так что вложенность она от самой природы
Почему не сделать через ту же точку.
Почему вместо вот этого дерьма
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
не писать так:
Setter Property="Template" {
Value {
ControlTemplate{
}}}
Я конечно придрочился уже, но в первые дни в глазах рябило.
Оно шарповое? Увы нет.
Что там вообще с концепцией lookless? А ничего
Xaml кажется говном пока не начнешь искать замену
▲
>Теперь Яджавадебил.
Таких дебилов-умников знаешь сколько? Они все настолько умники, что дебилы.
https://www.youtube.com/watch?v=48G_CEGXZZM
Если вкратце, то блейзер сервер сможет оправлять любой компонент в виде вебасембли в браузер пользователю и закрывать соединение. Таким образом высоконагруженные компоненты будут грузить ресурсы пользователя, а не сервера.
>Лицо ПК когда блейзер скидывает нагрузку, а ПК еще не отошел от хрома и майнеров.
Т.е. условная веб-версия фотошопа будет обычным фотошопом, но с защитой от правки файлов. Вот это многоходовочка копирастов.
А если типичный пользователь оставляет 5000 вкладок?
Да,само вью обновляется через onpropertychanged по клику на кнопку, которая в главном вью, а вот значение чего либо, текста например, внутри обновляемого вью, которое идёт через биндинг, не обновляется.
Пока просто сделаю несколько вью. И на второй свой вопрос я нашёл ответ, так что станет меньше дублируемого кода.
> пик
Зачем ты сам реализовываешь relaycommand, onpropertychanged и тд? Есть же готовые mvvm фреймворки вроде reactive ui.
Я до этого в с# не кодил и не знаю что есть, а что нет.
В любом случае использовать фреймворки-библиотеки не разобравшись в базе, это мартышкин труд.
var settingsPrefs = _sharedStorage.SettingsPreferences;
settingsPrefs.SelectedLanguage = Language.Russian;
_sharedStorage.SettingsPreferences = settingsPrefs;
_sharedStorage.SaveChanges();
Проверь DataContext страницы (где должно быть обновление) на наличие экземпляра вью. Вроде есть еще событие DataContextChanged, но это не точно.
Там же попробуй проверить свойство Content этого вью.
Еще для уверенности поставь через запятую режим привязки Mode="TwoWay"
Text="{Binding Content, Mode=TwoWay}"
Это сделает привязку двухсторонней.
Либо как нибудь по нажатию условной кнопки проверь DataContext.
Окно интерпретации ничего не пишет? Нет там Data Binding Error?
Ненормально.
SettingsPreferences у тебя должен быть классом, раз у тебя такая сложная начинка.
Соответственно, меняя свойство SettingsPreferences.SelectedLanguage у тебя автоматом внутри _sharedStorage должно все обновиться.
Либо создавай на ходу новый экземпляр SettingsPreferences и кидай его в _sharedStorage. Ели так не можешь, что структура здесь бессмысленна. Структура должна быть ровно такой, чтобы ты на ходу мог записать вот так: new point(10, 45)
Не ты случаем боишься нагружать GC в своей мобильной дрочильне?
Вангую SaveChanges перебирает все свойства на предмет совпадений со старыми SettingsPreferences. Сколько там свойств в сеттингах?
> Не ты случаем боишься нагружать GC в своей мобильной дрочильне?
Ну да.
> SaveChanges перебирает все свойства на предмет совпадений
Нет. Мой класс - это обёртка над SharedPreferences на Android и NSUserDefaults на iOS. В чём суть этих классов? Они хранят данные по ключ-значение. Вот такие у них методы:
- SetInt(ket, value)
- SetBool(ket, value)
- SetString(ket, value)
И ещё метод commit/sync, который сохраняет изменения в файл. На Android все эти значения сохраняются в XML файл, который хранится во внутренней памяти смартфона. Я решил не дрочить каждое поле делая его отдельным ключом, а использую JSON.
Плюс нужно ещё дефолтные значения держать. Если пользователь зашёл первый раз, то мне нужно подставить дефолтный SettingsPreferences/ControlsPreferences. Можно конечно захардкодить эти значения в самих структурах, но мне ещё нудно во время тестовые подставлять другие значения, поэтому их лучше всё же загружать откуда-то внутри SharedStorage.
Я наверно нюансов не знаю, но я смотрю на это и мне хочется сеттинги и преференсы сделать классами. Ну это же настройки приложения, они загрузятся раз в сессию и всё.
>Плюс нужно ещё дефолтные значения держать.
Это все из коробки есть вроде. Если в кастомных настройках что-то отсутствует, то оно берется из дефолтных.
Ты десериализуешь JSON?
> они загрузятся раз в сессию и всё.
Да, именно так.
> Это все из коробки есть вроде
Нет. Это мне самому нужно в коде сделать.
> Ты десериализуешь JSON?
При первом обращении десериализую строку. Если строка отсутствует, то возвращаю дефолтное значение структуры. Если строка присутствует, то результат десериализации сохраняю в переменную, чтобы каждый раз этого не делать, когда запрашиваются настройки.
В общем, фиг знает... Мне нужно использовать native хранилище "ключ-значение". Хранить там как-то различные настройки. И при этом иметь возможность подставлять дефолтные значения (то же расположение элементов управления на экране например)
Когда я добавил сервисы, то думал, что экземпляр требуемого сервиса будет создан как только его потребуют. По факу у меня тишина, ибо не было того самого инициатора. После IHost.Build() ни один из сервисов не запустил конструктор.
Как только я у хоста потребовал хоть один сервис, вся цепочка сервисов проинициализировалась и запустилась. Но я по прежнему не понимаю для чего нужен тогда IHost.Run()? Есть еще IHost.Start().
ааа, без этого как минимум логгирование не работает.
Тогда я что-то делаю не так со стартом сервисов. У Павла Шмачилина напрямую запускается основное окно, которое треубет сервис. У меня же запуском окна заведует другой сервис, который никогда не проинициализируется самостоятельно.
В общем я запутался для чего нужен этот Run. Почему я не могу так же пнуть логгер? Зачем ему нужен Run? Или это касается только логгирования методов, типа Microsoft?
>В общем, фиг знает... Мне нужно использовать native хранилище "ключ-значение".
У тебя такие сложности только из-за сопоставления дефолтных настроек и пользовательских. Вместо того, чтобы запихнуть в десериализацию класс\структуру целиком, ты начинаешь десериализовать поэлементно.
Ты начинаешь обращать внимание на формат "key, value", хотя это вообще не стоит внимания.
Не могу ничего пока сказать, я до IConfiguration еще не добрался, пока разбираюсь с логгированием. Но жопой клянусь было там что-то, что решает проблему сопоставления настроек. По-моему это называется "разные уровни настроек" по аналогии с разными уровнями логгирования. У тебя должен быть уровень дефолтных настроек, уровень настроек для отладки (где ты и дописываешь свои тестовые настройки), и есть уровень настроек обычных.
> IHost.Build() ни один из сервисов не запустил конструктор
а должен? ты там регистрируешь чего то добавляешь конфигуришь. и когда уже все, то билд все это дело обработает.
как и DI контейнер от майков
>>14257
>IHost.Run()? Есть еще IHost.Start().
потому что без этого у тебя просто сконфигурированный хост и ничего более.
чтобы сконфигурированный хост наконец запустить. тогда он под капотом запустит хостед сервисы как минимум.
и вообще эти рун/старт = обертки над асинк версиями с помощью GetAwaiter().GetResult()
а разница между ними такая же как в винформсах/впф разница между Show/ShowDialog - то есть "когда метод вернет управление"
>а должен?
Я пытаюсь осмыслить принцип, и предполагал, что при билде сервисов будет создан хотя бы один экземпляр, по крайней мере для синглтонов.
Хотя наверно это логично. Зачем плодить сущности, если их никто не требует?
>тогда он под капотом запустит хостед сервисы как минимум.
Он запустит только свои внутренние сервисы, но не добавленные мною?
Просто я могу сконфигурировать сервисы и запусть самостоятельно нужный, и у меня будет все работать без Run. Как бы, отряд не заметит потерь.
принцип простой - билдер позволяет удобно сконфигурировать и создать какой то объект. в этом смысл паттерна билдер.
>при билде сервисов будет создан хотя бы один экземпляр, по крайней мере для синглтонов.
они будут созданы по мере надобности. Незачем их создавать заранее. Даже в подходе MyClass,Instance инстанс не создается до первого обращения. Так и тут - нет нужды, вот и не создается.
Билдер сконфигурирует конфиги, сбилдит DI контейнер, установит хендлеры на события консоли (и то не факт, может это после старта) и так далее
>Он запустит только свои внутренние сервисы, но не добавленные мною?
Вряд ли унего есть что то свое. А значит он выдерет из контейнера все IHostedService и запустит их
>Просто я могу сконфигурировать сервисы и запусть самостоятельно нужный
Конечно можешь. Это ж просто дается унифицированный вариант. ОДИН из вариантов просто от вендора. Чтобы ты в каждом консольном проекте не писал свой велосипед заново.
Но это не является убер фичей. Просто ОДИН из готовых вариантов.
Если тебе нравится их подход то это позволяет тебе не бойлерплейтить лишний раз. Мне вот не нравится - слишком засирает дллками, да и IOptions не люблю и логгер Nlog использую
Иначе ты можешь писать свой хост. А потом заметив что ты пишешь одно и то же от проекта к проекту - соберешь все в либу и будет у тебя свой такой же. Этот от майков не первый же - их много.
https://devblogs.microsoft.com/dotnet/winforms-cross-platform-dotnet-maui-command-binding/
Формочки научат MVVM. Лица впф макак представили?
>Мне вот не нравится - слишком засирает дллками
Эх, и зачем я смотрел в bin?
>Иначе ты можешь писать свой хост.
Так я уже пытался обойтись, но понял что начинаю изобретать тоже самое и вернулся к готовому.
> и логгер Nlog использую
Я видел там, что можно самому указать паттерн вывода сообщения.
Хотел читать логи с подсветкой синатксиса.
нужно смотреть в publish.
создайть контейнер, запихать в него все, тупо из него достать IHostedService - запустить их и выгрузить потом, прочитать конфиг из жсона, прикрутить логгер - все это очень простые вещи
просто являются бойрелплейтом, но все же простым.
по логгеру - везде можно указать много чего. Nlog мне нравится подходом к конфигурированию - отдельно логгеры, отдельно таргеты, и все это связывается отдельными правилами "вот эти логгеры вот туда пусть пишут".
Очень удобно если логи в файлах.
>Формочки научат MVVM. Лица впф макак представили?
Я тебе расскажу про свое лицо: ему абсолютно поебать.
Там будет поддержка уровня поддержки бейсика. Формально прикрутят, но в целом всем насрать. Исправление каждой хуеты будешь по 5 лет ждать или не дождешься вообще.
Я понял, что ты вбросил ради рофла
Ну, это не совсем настройки. У меня уже есть система внутренних конфигов. Здесь же "предпочтения пользователя".
Обмозговал твои слова. Может так сделать?
https://pastebin.com/08LNagUa
CommonPreferences, SettingsPreferences, ControlsPreferences - станут классами. UserPreferencesDefaults будет подставляться в рантайме в зависимости от типа билда.
Плюс внутри PreferencesContainer ещё буду хранить версию настроек. Бывает что-нибудь изменяется и нужно грамотно мигрировать настройки пользователя, иначе их придется сбросить и тогда игрок бомбанёт от того, что ему по новой всё настраивать.
А че ты их просто в БД не хранишь?
Тогда у тебя не будет проблем ни с хранением, ни с извлечением, ни с изменением настроек.
Наверно, я пока ничего не могу сказать.
А с классами, думаю, будет рациональнее.
>нужно грамотно мигрировать настройки пользователя
А это хранение предыдущих настроек предполагается в пределах одной сессии?
Может легче просто сохранять конфиги в новый файл, а затем удалять предущий? Во многих приложениях так бэкапы устроены.
1. Есть некий TempFile, который удаляется после сессии.
2. Либо всегда есть два файла — один рабочий, а другой Backup-версия.
Собсно пример на пикриле. Текущий файл переименовывается с префиксом "Backup_", а новая версия сохраняется под обычным названием.
И реализация этого не требует каки-то больших сил. Не надо городить внутри PreferencesContainer копии настроек, это мусор.
>2. Либо всегда есть два файла
Чую, что когда буду изучать конфиги, там такой оции из коробки не будет.
Дефолтный логгер выводил логи по
Microsoft.Hosting.Lifetime и подобному.
Решил подключить Serilog, решил начать с простого. После чего перестало выводиться все, кроме того, что я укажу, хотя в джейсоне прописал пикрил 1.
"Override": {
"Microsoft": "Information",
"System": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
Могу еще код показать, но он на бейсике, хотя там в принципе все тоже самое. Отваливается из-за host_Builder.UseSerilog, но если эту строку не писать, то работает и дефолтный логгер и серилог (каждый печатает свое).
> We enable WPF apps to run on macOS and Linux with our Fork of WPF, which allows us to maintain API compatibility. Avalonia XPF replaces the low-level WPF code (MilCore) with Avalonia UI.
Это же many-to-many? Чет я запутался. Попробую спросить проще и на более простом примере.
Есть студенты и есть курсы. Студент может посещать много курсов, на каждый курс ходит много студентов. Как реализовать это отношение с помощью EF Core, чтобы ничего не удалялось каскадно? То есть, если все студенты отписываются от курса, то курс все равно остается. Или если курс удаляется, то студенты тоже не удаляются.
Да я вкурсе, я все изначально поставил в инсталере, перечитай мой пост - обосрались майки.
Тож подумал, что на дилдак какой-то похоже, а потом прочитал название и в принципе всё так и есть.
И в какие моменты используется Log.CloseAndFlush()?
Либо серилог ебанутый, либо я что-то делаю не так.
Один и тот же паттерн конфигурации вывода.
Если написан в json, то распознает табуляцию "\t", а через код не распознает.
Как удалять лог-файл при каждой сессии хрен знает. Типа удали напрямую, а если в имени лога автоматом генерируется дата? А для этого конфигурируй при помощи кода, а при помощи кода мы не можем конфигурировать, потому что идет по пизде разметка.
Боюсь имаджинировать как рабоатет Nlog.
>>16012
Я определенно делаю не так.
Дело в том, что конфигурация логгера Serilog.LoggerConfiguration идет до метода .ConfigureAppConfiguration, в котором я конфигурирую сервисы. Там создается новый экземпляр ILogger и конфигурируется он там автоматически.
В итоге у меня создалось два логгера, которые еще и друг другу мешали, и что я пытался исправить при помощи Log.CloseAndFlush()
Только проблема осталась неясна. А как в список сервисов добавить готовый экземпляр логгера?
Итак,
Вот я конфигурирую логгер
Log.Logger = New Serilog.LoggerConfiguration().CreateLogger
Log — статический
в Log.Logger помещается новый экземпляр ILogger
В конфигураторе сервисов я пишу
services.AddSingleton(Log.Logger)
Разве сюда не должен помещаться мой экземпляр логгера?
Почему по факту при попытке от хоста поулчить сервис ILogger возвращается другой экземпляр?
Короче, все зависит от порядка конфигураций.
- Сначала конфигурируется и создается логгер
- Затем добавляется в статическое поле Log.Logger
- Затем конфигурируются сервисы, где добавляется в коллекцию как синглтон этот самый экземпляр Log.Logger
- И только потом волшебное заклинание
host_Builder.ConfigureLogging(log_builder => log_builder.AddSerilog)
Но тут вечная проблема с dependency injection, я короче, решил сделать чет похожее на mvp паттерн, но чтобы нормально внедрять зависимости создал фабрику для презентеров и получать форму через презентер, эт нормальный подход?
Никто не запрещает, я делают подобное в своих хеллоуворлдах.
Есть ли где-то "туториал" как поставить драйвера на деревья?
>Боюсь имаджинировать как рабоатет Nlog.
Нормально работает. Чуть проблемнее если нужна интеграция. Например асп.нет. Можно положить болт на местный ILogger и просто забыть про его существование (юзать NLog напрямую как его и юзают), а можно хотеть юзать ILogger и тогда нужно выхлоп этого логгера загонять в Nlog/Serilog) что тоже просто ведь это давно сделано и потому сворачивается в простое типа services.Add
app.Use
>На собесах на джуна
Сейчас не существует собесов на джуна.
>>16395
>дают крутить в голове деревья?
Обычно нет. Обычно дают задачки на async/await или многопоточность. В стиле "Если мы вот ебанем несколько асинхронных методов, то что выполнится в первую очередь, что во вторую, а что вообще не успеет. И как исправить, чтобы было правильно"
Еще популярны задачки на linq. Причем с подковырками lazy вычислений.
Так же популярны задачи на рефакторинг. Дадут какой-нибудь дерьмовый класс и спросят что тебе в нем не нравится, как бы ты его переписал, какие бы паттерны применил и т.д.
А как на любом уровне приложения грамотно завершить его?
Ну вот возникла у меня фатальная ошибка, что делать-то? До основания Application путь не близкий.
Или поэтому не плодят Try Catch?
Меня больше смущают причуды этого логгера.
Например в конфиге json распознаются \n, \t, а в конфиге кодом — нет.
Ограничил Microsoft.Hosting.Lifetime до уровня Error, а оттуда все равно выводятся логи, хотя лично мои логи ограничены. Почему? Хрен знает.
Причем пакеты Serilog.Sinks.Debug и Serilog.Sinks.File работают по разному при тех же конфигах. Почему-то Microsoft.Hosting.Lifetime не лезет срать в файл, если ограничить.
Я два дня ебусь с этим серилогом, и мог бы уже свой написать, наверно, со всеми нужными плюшками (которых не получил). Ну теперь уж время потеряно.
>юзать NLog напрямую как его и юзают
Необязательно пихать в сервисы? А как же хваленая DI замена сервисов на лету? Опять меня наебали сказками.
Делаем сервис IApplictaion
А в чём прикол размещать свойства и события уже после конструктора???
>А как же хваленая DI замена сервисов на лету?
ну типа если у тебя логгер получаешь через DI то ты типа можешь его поменять на другой. Вот только зачем. Логгер это просто именованный источник событий и если тебе нужно чтобы он писал в другое место - ну так в другом месте и перенаправляешь вывод. А потому нет смысла его замены и логгеры можно создавать на месте.
я не приемлю логгер через конструктор. это засирание параметров, хз что делать если нужно вложенный логгер, нельзя дать нормальное имя.
единственная причина мне смотреть на ILogger - если я хочу получить события которыми сам фреймворк в него какает. Тогда нужно заворачивать. Иначе нафиг он не нужен.
А как? Мне не дает это сделать.
Я взял и добавил в класс статическое свойство с ссылкой на рабочий экземпляр. Но AddSingleton не дает мне обратиться ни к одному свойству класса ApplicationManger. Вот так правильно:
services.AddSingleton(Of IApplicationService, ApplicationManger)
А так ошибка:
services.AddSingleton(Of IApplicationService, ApplicationManger.ActiveManager)
Не дает даже точку поставить — сразу ошибка
С языком обосрался. Короче у меня эквивалент вот этого.
Работает:
services.AddSingleton<IApplicationService, ApplicationManger>();
Не работает:
services.AddSingleton<IApplicationService, ApplicationManger.ActiveManager>();
опять ты что то мудришь
это же экземпляр. его передают как параметр
services.AddSingleton(obj);
services.AddSingleton<IMyInterface>(obj);
Ах тыж, точно.
Вот думаю может использовать ассиметричное шифрование? В дебаг-моде данные будут логироваться в открытом виде. Если мне нужно будет чекнуть на сервере логи и определить ошибку связанную с конкретным аккаунтом, то я их расшифрую закрытым ключом.
этого мало. шифруй все и еще скрывай сам сам факт логгирования. подмешивай /dev/random рэндомно, чтобы никто не смог расшифровать если у тебя ключ украдут.
А если серьезно, то в логах не должно быть чувствительной информации и айди к ним точно не относится - тем более если он внутренний с внешним не связать (хотя и это уже паранойя)
> тем более если он внутренний с внешним не связать (хотя и это уже паранойя)
А если пользователь зарегистрировался на сайте через Facebook и я хочу залогировать этот момент вместе с Facebook ID? Или фейсбук айди лучше убрать нафиг?
У этого пользователя должен быть какой-то внутренний Id в твоём приложении. Вот его в логи и пиши. А фейсбучный Id связывай с ним и храни где-то внутри программы в БД (если он тебе конечно нужен)
Так вот есть в Microsoft.Extensions.DependencyInjection
метод ActivatorUtilities.CreateInstance, который делает определенный сервис активатором.
Непонятно чем это отличается от обычного вызова нужного сервиса. Видимо для сомневающихся, типа меня.
... ах да, и тип вызываемого сервиса не должен быть интерфейсом, как на пикрил, а оригинальным классом. Это классическая ошибка.
Так, что использование данного подхода накладывает свои ограничения.
проблема в том что сайт отдает html страницу сразу, и через пару секунд только подгружает в неё данные, видимо скриптами
Как можно решить эту проблему в webClient? или куда копать?
Докатился до хромдрайвера вместо WebClient, судя по всему проблема решена
>Непонятно чем это отличается от обычного вызова нужного сервиса
Обычный вызов сервиса не позволяет передать свои параметры. Это специальный утилитный метод для одноразового использования.
ты передаешь ей параметры и она заполняет конструктор параметрами из контейнера и твоими параметрами.
Для многоразового нужно использовать методы рядом вида ActivatorUtilities.CreateFactory
Бляяяя, какая же это ебань.
Т.е. существует два ILogger — один от Serilog, другой Microsoft.Extensions.Logging.
Именно поэтому мне в дебаг срал майрософт, игнорировав ограничения уровней. Я использовал Serilog.ILogger затем .ForContext(typeof (T)), а дефолтный может на ходу получить ILogger<T>.
Дефолтный даже в сервисах прописывать не надо, хост его все равно выдаст, как и конфиги.
Понял, интересно.
Когда я вызываю IServiceProvider.Dispose, должен ли он автоматом диспозить сервисы?
Каст к IDisposable вызывает Dispose автоматом
Короче при IServiceProvider.Dispose автоматом диспозятся все сервисы, кроме одного. Это я уже проверил, даже если это синглтон.
Суть моей проблемы:
Мне нужно закрыть приложение из любого сервиса. У меня есть условный базовый сервис ApplicationService у которого есть метод async Shutdown, который закрывает приложение, завершает соединение с именованным каналом + диспозит сервисы.
Я предполагал, что любой сервис, если ему надо закрыть приложение, обращается к IApplicationService.Shutdown, но сам сервис, вызывающий сей метод отказывается диспозиться. Хз как это разруливать. Так-то при закрытии приложения всё равно всё уничтожится, но что если мне надо задиспозить без закрытия приложения?
Сперва у меня было реализовано при помощи событий и все работало, но сама система подписок очень геморная. Это надо делать подписку на каждый сервис.
Небось дрочеш используешь string?
А ты разве не знал, что любая операция со строками создает новый экземпляр строки?
Если ты PDF составляешь стрингами через всякие циклы, то я боюсь имаджинировать ебало твоего ПК.
больше проблем от всяких MemoryStream, а не от строк.
Я это и хочу выяснить.
Сервис не диспозился, поэтому я решил задиспозить его вручную перед строкой IServiceProvider.Dispose.
Я вызывал проблемный сервис и через каст IDisposable, вызывал метод Dispose. При этом сервис пытается диспозиться дважды. Я убираю вызов Dispose и использую каст к IDisposable — в итоге диспозится один раз. Тогда я решил просто получить от хоста сервис и у меня тоже вызывается диспоз.
Я не знаю что не дает ему диспозиться.
Основная загвоздка в отображении параметров:
[Payment] Initiate transaction with product 'coins_1500'. Order '435345345345'
[Payment] Initiate transaction. Product 'coins_1500'. Order '435345345345'
[Payment] Initiate transaction: product='coins_1500', order='435345345345'
Сервис который просит выгрузки приложения ничем не отличается от других сервисов. Ведь IApplicationService.Shutdown не является блокирующим
Мой стиль
String использую один раз, он отжирает в районе 500 мб, дальше всякие методы из фреймворка XamlReader.Load, SaveAsXaml - что там у них в коде хуй знает
>String использую один раз, он отжирает в районе 500 мб
Есть еще понятие страниц в памяти и прочего. Т.е. твой стринг может зарезервировать больше места.
Может тебе нужен массив? Или конвертировать как-то частями.
У меня и нет лохов, иначе их сборщик подчистил бы, скорее всего куча всякого мелкого говна
С чего бы сборщику чистить LOH
LOH такая структура что выделишь ты объект на 100 мегабайт, потом его удалишь, объект исчезнет, а выделенная память останется.
GC не сжимает LOH самостоятельно. Его нужно об этом просить явно.
Потому и приходится использовать разные ChunkedList/ChunkedMemoryStream и Marshal.AllocHGlobal чтобы не быть лохом с LOH
Раз уж я настроил логгирование. Вот отчет с комментариями.
Синим подсвечено то, что пишет лог в пределах одного метода.
Т.е. видно, что метод ожидает завершения ShutdownAsync, хотя я не прописывал await.
Ща буду разбираться почему.
Я просто напомнил про LOH
Смотри же профайлером кто чего память, а не гадай
Если это LOH то Dispose не поможет, нуюны доп усилия
Но сначала профайлер
>а dll нативная
Которая string возвращает это хуита из dot.liquid, остальные охуевшие методы из фреймворка
>может она не стринг возвращает?
Ну сигнатуру-то я вижу
Хм, почему-то метод ShutdownAsync из другого сервиса не воспринимается асинхронным.
Для примера, WindowServiceCounter - асинхронный
какой еще ShutdownAsync
зачем сервису ждать окончания Shutdown
любой код должен вызывать Shutdown() и забыть. Семантика как и у CancellationtokenSource.Cancel()
>зачем сервису ждать окончания Shutdown
Так я специально писал так, чтобы он не ждал. Метод асинхронный, но вызывается без await.
А как еще? Вызывать синхронно?
>Семантика как и у CancellationtokenSource.Cancel()
Т.е. Async? Из ачем не токен, если я ничего не собираюсь отменять.
Буду смотреть, хули остаётся
ты же понимаешь что сервис который дергает Shutdown() НЕ ОТЛИЧАЕТСЯ от других сервисов? вообще ничем. А значит ты что то накосячил.
про семантику CancellationtokenSource.Cancel() я упомянул что у
Shutdown() должна быть такая же семантика - вызвал и ПОШЕЛ ДАЛЬШЕ.
>Метод асинхронный, но вызывается без await.
без реализации это ни о чем не говорит. До первого await в асинхронном методе он вызывается синхронно.
Впрочем даже тогда ничего не мешает вызвать Dispose.
А значит
а) сделай нормальную семантику. убери Async и пусть будет Shudown() (или любое другое типа стартшутдаун и тому подобное)
б) вызови Shudown из другого класса и смотри поведение.
Писать свою либку. Нам в команде, к примеру, пришлось запилить свою внутреннюю либку для потокового парсинга/генерации Excel, так так все имеющиеся решения жрали ОЗУ как не в себя и отваливались по OOM на 10k строк. А у нас, бывает, пользователи и по 100-150k грузят. Нынешнее же решение вполне себя живет в подах с лимитом ОЗУ в 1Gb.
>ты же понимаешь что сервис который дергает Shutdown() НЕ ОТЛИЧАЕТСЯ от других сервисов?
Отличается хотя бы апартаментным состоянием потока. Виндовс менеджер запускает окна и имеет STAThread. Соответственно остальные сервисы находятся в MTAThread и между собой проблем не имеют.
[DBG 17:13:29:877 WindowsManagement.WindowService] Apartment State Thread: STA
[DBG 17:13:30:025 Outliner.ApplicationManager] Apartment State Thread: MTA
При этом я напрямую запускал метод из другого потока и пох, за исключением игнора факта, что метод асинхронный. Вскрылось когда запустил Shutdown() через Task.Run() и прилетело исключение. Я нигде не указывал явно аргумент STAThread, оно как-то само.
Так щито теперь делать? не делать же все остальные сервисы под STA?
>апартаментным состоянием потока.
хз имеет к вызову Dispose?
но надеюсь метод Shutdown() НЕ делает сам работу по выгрузке приложения и Dispose, а является всего лишь что то типа
_cancellationTokenSource.Cancel()
_complettionTaskSource.TrySetResult()
_resetEvent.Set()
и так далее.
Становись сразу мидлом.
Думаю, что понял откуда последние пару лет в шарпе аномальное количество вкатунов 18-22 лет
Этот чел владеет геймдев студией. На пике их самые лучшие проекты (из 150-ти штук).
Я думаю качество материала в видео примерно такое же.
ССССССССУУУУУУУУУУУУУУУУУУККККККККККККККАААААААААААААААА
Целый день, блять. Целый ебаный день убил на ХУЙНЮ.
Все из-за одной строчки
ActivatorUtilities.CreateInstance<WindowService>(ServiceHost.Services)
вместо должного
ServiceHost.Services.GetService<IWindowService>
Я такой, значит, повторно пытаюсь получить у хоста WindowService, который на минуточку СИНГЛТОН, а он мне возвращает еще один экземпляр.
И все, кстати, у меня там в STAThread. Это Task.Run() запустил метод в MTA
>complettionTaskSource
Я так делал. Но я же могу тогда уж сразу юзать complettionTaskSource.TrySetResult(), вместо Shutdown()?
>что думает тред об этом высере?
Скрыл из рекомендованного по двум причинам (даже не смотря ни секунды).
1. В названии написано "слив"
2. В названии написано "лучшего"
Я не домохозяйка, чтобы вестись на подобный байт инфоцыгана.
А если в названии нет кричащих слов, то не интересно?
Ты хочешь 10 часов воды навернуть? Почему ты не хочешь загуглить что-то проще и попытаться хотя бы создать проект?
Ну да. Откуда контейнеру знать про создание сервиса с помощью утилитного метода. Смысл утилитного метода - тупая фабрика, цель которой рокинуть параметры из контейнера в создаваемый объект и он знать не знает про время жизни создаваемого объекта
Я про то что цель метода applicationservice.shutdown всего лишь послать событие "тут попросили выгрузки " любым способом
А уже в нужном месте кто то ждет этого события и выгрузит в правильном контексте даже если это в том же классе
То есть дополнительный уровень косвенности похволит избежать возможных трудноуловимых проблем
Хз, чел. Я вообще начинал со скриптов, я просто писал мелочи и постепенно продвигался дальше. Только потом начал писать самостоятельные программы.
SimpleCode смотрел?
https://youtu.be/KyFWqbRfWIA?list=PLQOaTSbfxUtD6kMmAYc8Fooqya3pjLs1N
Кстати, подписка мне здесь больше нарвится именно в таком исполнении. Спасибо.
100 роликов...
Путем экспериментов с финализатором понял, что вью модель удаляется только после повторного захода на страницу и ухода с нее. Видимо где-то есть буфер, вмещающий одну страницу. Вопрос где.
Frame для мазохистов
Мало информации. Ты же высвобождаешь нужные ресурсы?
Ты контент старницы контролируешь? Можешь добраться до каждого итема? Или это какой-то хромиум?
> Ты же высвобождаешь нужные ресурсы?
Что ты под этим подразумеваешь? При нажатии на кнопку я вызываю Frame.NavigateTo(targettype) и всё.
> Ты контент старницы контролируешь? Можешь добраться до каждого итема?
Да, да.
>Что ты под этим подразумеваешь?
Реализация IDisposable и метод Dispose. В этом методе ты проходишься по всем вещам твоей страницы, которые GC не удаляет, потому что они по тем или иными причинам продолжают существовать. Например:
- Подписки на события (за исключением слабосвязанных — тех что создаются в XAML)
- Свойства с делегатами
- Bitmap-ы
- Скорее всего твой медиаконтент
Ты должен напрямую обратиться к плееру, и как минимум остановить его, отсоединить медиконтент, который он проигрывает.
У меня был случай, когда я активировал таймер, который срал в консоль. И я решил тупо очистить переменную, в которой находился экземпляр класса с запущенным таймером, присвоив null. А таймер продолжал срать в консоль, и пока он срет, CG не может удалить класс.
Или когда я подписки не чистил и при каждом создании окна у меня приложение начинало все больше и больше тормозить.
Умные люди используют лайфтаймы, чтобы меньше головной боли было с контролем всего этого, но это уже другой уровень.
Предупреждение CA2017 Количество параметров, указанных в шаблоне сообщения о ведении журнала, не соответствует количеству именованных заполнителей
Я добавлял dispose, обнулял source у медиаконтента, всё одно. Более того, я сейчас просто убрал медиаконтент, и это никак не повлияло на общую ситуацию. То есть проблема явно где-то вне класса.
Сомневаюсь, что я в одно ебало высру конвертер в xps и pdf, такие решения вполне себе за деньги продают
Целую неделю ебусь, не могу понять как эту хуйню сделать.
Дали WSDL, добавил референс в проект, вроде заполнил все нужные данные, запускаю -- он мне на Security Header ругается.
В примерах запроса которые мне отправили заголовок вообще подписывается как я понял с помощью Х509 сертификата.
Все перегуглил, но все равно нихуя не понятно. Есть инфа как добавить сам заголовок, но как добавлять ПОДПИСАННЫЙ заголовок, так еще и с помощью сертификата (у меня он есть, я еще подписываю тело с его помощью)
Типа, если отдельно подписать и добавлять в заголовок то что подписывать то? Тело? Так оно уже подписано отдельно
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Development")
Куда это сохраняется? Запускаю окно переменных среды: в пользовательских ничего нет, в системных тоже.
Что будет, если другое приложение напишет
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Production")
пасибо
Есть энтити User и UserInterest. У них отношения many-to-many, то есть в User лежит ICollection<UserInterest>, а в UserInterest ICollection<User>. В UserInterest есть проперти string UserInterestName. Также есть дтошка UserDto, где я обрезаю ненужные проперти. Но в нее добавлена новая: List<string> UserInterestNames.
Дальше делаю маппиннг с помощью автомаппера.
CreateMap<User, UserDto>()
.ForMember(dest => dest.UserInterestNames,
opt => opt.MapFrom(
И вот дальше я не понимаю, как написать запрос, чтобы вытащить все UserInterestName из ICollection<UserInterest> в виде List<string>, чтобы маппер их загнал в проперти в UserDto.
Поддерживает
ALTER TABLE <TABLENAME> DROP COLUMN <COLUMNNAME>;
ALTER TABLE <TABLENAME> RENAME COLUMN <COLUMNNAME> TO <NEWCOLUMNNAME>;
мне всегда было интересно. почему люди мазохисты?
ну ладно переход с 4.8 на кор может быть проблемным, но с 3.1 до 7 поднять - просто сменить версию дотнета. (ну кроме WPF, там чуть чуть намутили, но кто пишет на WPF....кроме меня)
Значит делаешь миграцию как диды:
1) Create new table
2) Copy data
3) Drop old table
4) Rename new into old
Охуенно, ставить SQL Server ради десктопной утилиты.
есть еще firebird как ембедед. Сильно лучше чем склайт, но файрберд.
ну так то базы разные. первое - огрызок для "надо самый минимум", а второе - полноценная версионная база данных.
При закрытии sqlite журнал вливается в базу данных
Сделай в sqlite WAL mode (и не вливай журнал в базу) и размер то другим будет.
вот пик у меня прямо щас. после закрытия бд журнал конечно исчезнет потому что sqlite так задуман, а файрберд оптимизацией занимается по мере необходимости ибо как бы настоящая бд.
Этим методом устанавливается путь к директории, из которой будут читаться сеттинги, куда будут сохраняться логи и т.д. Почему во всех туториалах прописывают Environment.CurrentDirectory — место откуда запускается приложение, ведь хранить данные в ProgramFiles не рекомендуется.
Разве это не должна быть какая нибудь AppData? Следом возникает второй вопрос. Есть appsettings.json с дефолтными настройками, а есть appsettings.Prodaction.json, appsettings.Development.json. Первый файл должен храниться в папке с приложением, два последних в AppData. Но с SetBasePath подразумевается, что все три файла должны находиться в одном месте.
Как это вообще происходит? При первом запуске приложения папка с юзердатой копируется в AppData и уже она ставится в качестве BasePath? Я никогда не видел нескольких файлов appsettings — этот файл всегда один, но в разных местах.
Он пытался, но: "Missing map from System.Char to System.String. Create using CreateMap<Char, String>. Офк, создание такой мапы не помогает и ругается, что у string нет дефолтного конструктора. В SelectMany почему-то прилетает IEnumerable<char>, а не стринг.
портабельное приложение - папку ищем относительно ехешника
системное приложение - у нас есть папка /etc или ProgramData под виндой
пользовательское приложение - у нас есть профиль пользователя
сервис какой (тот же асп.нет приложуха) - пользователь решает где рабочая папка. А как он нам ее сообщит? через переменную окружения - вот и есть такая переменная. Если мы пишем батник какой то там ее прописываем эту папку, иначе она будет смотреть на system32 что ли. При запуске ручками она будет равна текущей папке где находится пользователь, что приводит к "не могу найти файл", но это проблемы пользователя.
так что где чего - зависит от типа приложения
и конечно никто не запрещает тебе задать путь к конфигам относительно ехешника и попутно использовать заданную рабочую папку для рабочих файлов
Это я всё понимаю. Вот если бы я не смотрел туторы по IConfiguration, все было бы проще.
Объясни мне логику пикрил. Почему у автора appsettings.json appsettings.Production.json находятся в одной куче? Это какой-то каргокульт ASP? Если что, это WPF-приложение и вряд ли оно портабельное.
Пользователь открывает условную CurrentDirectory, а там два файла
appsettings.json
appsettings.Production.json
Я такого нигде не видел. Мне предлагают вот это воспринимать как что-то естественное? А если CurrentDirectory удалится? Что делать?
Мне бомбит, что все туторы сделаны по одному шаблону. Допустим это пользовательское приложение.
В моем понимании appsettings.json должен быть изолирован от изменений. Он должен находиться в папке с приложением.
В то время как appsettings.Production.json должен находиться в ProgramData или AppData. И не иметь ебанутой подписи Production
Кроме того. Мне сообщают, что если IConfiguration не находит файл appsettings.Production.json, он читает данные из appsettings.json.
Хорошо, а как быть с сохранением? appsettings.Production.json по прежнему отсутствует. Куда будет запись? В дефолтный файл? <сарказм> Охуенно! </сарказм>
И ответы на эти, казалось бы, базовые вопросы ни один тутор не дает.
не понимаю вопроса
все эти development/production/(иногда staging) - самая что ни на есть норма. есть основной конфиг, а сверху мержится доп конфиг который зависит от окружения.
>А если CurrentDirectory удалится? Что делать?
а если удалить c:\windows? значит упадет с сообщением что файл не найден.
А то что у автора WPF - ничего не значит. значит он так решил. Это не по гайдам, но такая его хотелка. Чай не публичный софт делает. А значит делает как ему удобно.
>>19876
обычно это сервисы/вебсайты и тому подобное - там такое разделение норма. чел просто не хочет делать по другому. И нет никакого смысла файлы кидать куда то далеко чтобы потом ходить искать? зачем.
>Хорошо, а как быть с сохранением
НИКАК. эта конфигурация не умеет сохранять. Конфиги правятся в блокнотике.
Допустим, я хочу сделать так, как я сам себе это изначальн опредставлял.
В папке с приложением у меня хранятся дефолтные конфиги. При первом запуске я их копирую в AppData и устанавливаю эту папку как CurrentDirectory.
Дальше, если нужно сбросить конфиги, то я копирую из папки с приложением оригинал.
Тогда вопрос а НАХУЯ эта возня с appsettings.Production.json? В чем хитрый план?
>самая что ни на есть норма
В вебе? Возможно, но я перелопатил все установленыне приложения у себя и не нашел подобного подхода.
>а если удалить c:\windows?
CurrentDirectory в данном случае это данные из AppData. Нафиг тогда бэкапы конфигов делают?
>А значит делает как ему удобно.
Это не единственный автор.
Умеет?
>если нужно сбросить конфиги, то я копирую из папки с приложением оригинал.
да как угодно. фломастеры то разные.
> appsettings.Production.json? В чем хитрый план?
позволяет переопределять ключи из основного конфига в зависимости от окружения
https://learn.microsoft.com/ru-ru/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0#appsettingsjson
нужно для удобства разработки.
Конечно можно просто один файл, но каждый раз править конфиг муторно
Пример - я разработчик у меня есть стейжинг сервер. на моей машине у меня локальная бд, на сервере своя - мне что каждый раз при заливке на стейжинг конфиг править? ну ок я могу добавить в игнор этот файл - значит мне при каждом его изменении ходить везде менять. Проще сделать переопределение.
Туда же и Production - без него выкатил я на сервер боевой, вбил пароли к бд и все - первый же апдейт легко может снести мои правки.
А так защита от дурака.
>CurrentDirectory в данном случае это данные из AppData
CurrentDirectory это рабочая папка и никакого отношения к AppData не имеет. AppData это специальная папка относится к профилю. CurrentDirectory это переменная окружения и позволяет пользователю ее переопределить. Нужно ли это каждый решает сам. Меня вот лично бесит когда софт засирает профиль - у меня десятки гигабайт кешей инсталлеров и прочей херни потому что "ну так решили".
Даже студия срет мама не горюй - в ней хоть можно выключить кеш пакетов и освободить несколько гигов на диске ц
>Нафиг тогда бэкапы конфигов делают?
бэкапы делают потому что бэкапы нужны ). это перпендикулярно
>Это не единственный автор.
да неважно сколько их. они ваяют свое и как считают нужным. Они считают что нафиг не нужен гуи для правки конфига и "юзеру нужно - блокноте подправит и никакой мультипользовательсковсти". Софт он ведь разный бывает.
Чел, так делается в промышленном коде, который нужно постоянно разворачивать на разных стендах. Есть локальные стенды, есть тестовые, есть интеграционные, прелайв, продакшен и дохуя еще всяких. И для всех нужны разные конфиги. Поэтому проще создать пачку для всех и закидывать их либо скопом, либо каждому свой. Потому что никто не будет ебаться и каждый раз на своем стенде сидеть и править конфиг под него.
Ты говришь с позиции веба, сложно это воспринимть.
>Туда же и Production - без него выкатил я на сервер боевой, вбил пароли к бд и все - первый же апдейт легко может снести мои правки.
Это характерно для веба? Хорошо. Если это спроецировать на десктоп, то у меня должно быть так:
appsettings.Backup.json (ну или вариации неминга)
appsettings.json
>Меня вот лично бесит когда софт засирает профиль
У меня не будет там тяжелых данных. Все тяжелое у меня временное и я буду срать этим в Temp. Где еще хранить сеттинги? В ProgramFiles? Как минимуму пользователя не будет уверенности, что там можно что-то править.
>CurrentDirectory это рабочая папка и никакого отношения к AppData не имеет.
Так если у меня в AppData хранятся и сеттинги и логи, то это же можно назвать рабочей папкой? Для чего она предназначена? Или это что-то из разряда, когда пользователь запускает FileDialog, который смотрит\меняет CurrentDirectory?
Понял
>Меня вот лично бесит когда софт засирает профиль
Иначе придется ебаться с правами доступа. Срать в мои документы — те же яйца (если они не переопределены).
>Это характерно для веба?
это характерно если у тебя есть разные окружения где нужно запускать и не хочется пердолится с конфигами.
> Где еще хранить сеттинги?
где хочешь. смотри же на свой софт. Если он у тебя должен становиться в ProgramFiles то значит нужно класть туда где есть права на запись, а это профиль.
Иначе же - ну пусть рядом лежат, проще искать, легко снести все просто стерев папку.
каждому свое.
>>20021
и что с того. вон жетбрианс хранит инсталлеры в профиле. НАХРЕНА спрашивается. Есть же инсталлер что с веба скачали - зачем плодить дубли. И при этом удалить нельзя - сломается.
идиотизм. (а та же андроид студия - портабельная при этом)
Нужны права? так это ж инсталлеры блин. он все равно для их использования поднятие прав запросит и сорит ими при поднятых правах.
рабочая папка это просто одна из переменных окружения. обычно указывает на текущую папку в шелле или же на какую то системную папку. ну и может быть переопределена ведь это переменная окружения.
И хорошо когда приложение не прибивается гвоздями, а позволяет настроить себя переменными окружения (особенно если это не десктопный софт)
а ты ждешь ответа что "работать можно" или ожидаешь пожесчте (ибо маковод)?
всегда удивляет когда люди создают себе сложности сами
>Почему народ массово пускают слюну на дискриминирующие объединения
Кто пускает? Кто 'массово'? Сам себе хуйню придумал и других ей доебываешь.
Все эти Net7, NetCore и т.п. крайне отвратно работают с виндой по сравнению с нет фреймворком. Работа с COM-объектами стала в разы медленней, при этом постоянно возникает проблема корявого подсчёта ссылок и массовых утечек памяти, и приходится ещё и всё это руками делать, хуже чем на крестах писать.
Почему майки не смогли сделать сор таким же виндовс-френдли, как фреймворк, для меня загадка.
Если бы не новые фишки языка, не совместимые со старыми рантаймами, ни один разработчик по винду не полез бы в эту новомодную помойку.
Слы, бумерок консервированный, ты интернет вообще читаешь? Посмотри популярных блогеров и сишарп-инфлуенсеров. Это самая ожидамая приблуда грядущего дотнета.
одно с другим вообще не связано.
1280x720, 0:08
Я, как ОП шапки, готов выслушать предложения и добавить их в свой личный пастбин. Можно добавить перформанс EFCore из .NET 7 vs .NET 6 (если кому не впадлу измерить), например вот такое для LINQ и Reflection есть. Если есть фотошоперы - фотошопьте аниме, иначе никакого переката.
1920x1080, 0:09
>1. Перекат будет после 1000 постов.
Но тогда тред утонет! Все нормальные треды перекатываются после 500. А мы чем хуже.
>2. В шапке обязательно должно быть аниме
Это можно будет устроить.
>>21892
> иначе никакого переката
Так ты и так уже 2 треда не перекатывал, ленивец! Мне пришлось вытаскивать тред из помойки.
По дефолту - в /etc/appname/appname.conf кладу
Сразу миллиард проблем решил.
Во-первых, намного удобнее монтировать и если надо менять конфигурацию не залазя в контейнер, при этом мы не хотим все кишки наружу(да, это не проблема, но сам подход того что по дефолту майки считают что надо прямо с приложением держать - мне не нравился никогда)
Во-вторых, соблюдаем линуксовские договоренности и уважаем среду
В-третьих, сам json - уебищный формат для пользователя. Вот реально, как я заебался объяснять куда админ должен вписать какую хуйню, чтобы то что ему надо получилось. С ini-лайк форматами и возможностью закоментить-раскоментить - они как-то проще это все понимают
Короче. Ошибкой было использовать json как основной способ конфигурирования в .net core и тянется до сих пор.
>Так ты и так уже 2 треда не перекатывал, ленивец
Да, есть такое, извиняюсь. Заработался-залиткодился. Можно еще пик добавить в шапку чтобы все ахуели с моих возможностей!
Хз, мне нравится нынешняя заглавная пикча треда. Я бы её сохранил для последующих тредов. Так C# тред сразу узнаётся среди других. А на твоей пикче слишком много деталей, суть теряется.
Да, есть такое, мне кажется просто "C#" можно побольше сделать и выделить синим/фиолетовым, а нипонский текст вырезать.
> Все нормальные треды перекатываются после 500. А мы чем хуже.
В том-то и дело, что лучше. Петухон и JS перекатывают после 500, потому что там тысячи вкатунов, и надо, чтобы каждый, кто видит первую страницу /pr/, видел эти треды и пытался вкатиться туда, не создавать шарпобогам конкуренцию. В шарпобоги знают про навигатор, откуда по тегу можно перейти в нужный тред.
С конкуренцией успешно справляются колледжи и вузы. Потому что преподы сидят на шарпах еще со времен фреймворка
Сойдёт.
После колледжей и вузов вкатываются от силы 10% студентов, и то те, кто учился самостоятельно. Остальные наивно надеялись, что в вузе их научат программировать.
А как научиться то? Что нужно делать?
JS так как быстрее выучишься и пойти на работу сразу, ну и потом изучать c# потому что хочу работать в инди компании что разрабатывает игры на unity
какие водводные?
>курсы JS
Не нужно. Твердо и четко.
>игры на unity
Выбери что-то одно Если хочешь веб. то лучше к джаваскрипту выучить что-то серверное, например php.
Если хочешь игры, то учи сразу сисярп.
Это копия, сохраненная 18 июня 2023 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.