Автотесты - первый помощник тимлида
Для битвы пет проектов я решил попробовать относительно новый для себя подход - ATDD, о котором я уже рассказывал. И, к удивлению для себя самого, я ни разу об этом не пожалел.
Начну, внезапно, с минусов. Это время. Да, на реализацию фичи через автотесты уходит время. Где-то в каком-то исследовании даже видел конкретную цифру, фича занимает в среднем на 16% больше времени, если разработка идет через тестирование или если на фичу тесты пишутся после реализации. По прошествии полутора недель активной работы, это действительно ощущается так. Возможно, мы тратим на это даже больше.
Но самое интересное, что... больше минусов нет.
Вот серьезно, после реализации фичи вы получаете гарантированно работающий пользовательский сценарий (а то и несколько), который точно несет полезность для конечного потребителя продукта. Нужно больше уверенности? Просто добавляйте больше сценариев, покрывайте узкие, нестандартные кейсы и ошибки в рамках фичи.
Наш процесс приемки задач состоит из одного шага - код-ревью. Код решает задачу наших пользователей потому что мы начинаем разработку с пользовательского сценария. А в том что он точно работает я убеждаюсь благодаря автотестам.
Вы только посмотрите на наш Code Coverage (скрин в шапке). Помимо очевидного покрытия кода тестами эти цифры также показывают нам, что мы не делаем лишних вещей. Все о чем говорится в сценарии должно быть покрыто тестами. И оно покрыто.
Благодаря такому подходу я, как лид команды, в рамках ревью фокусируюсь на качестве кода, на его архитектуре, на взаимодействиях между модулями, и совершенно не беру на себя ответственность контролировать качество работы написанного кода, его соответствие требуемой бизнес-логике, так как эти вещи в нашем подходе автоматизированы благодаря ATDD.
Да, мы тратим больше времени на разработку, но мы получаем невероятную экономию буквально всех ресурсов команды на тестировании и контроле качества.
Пушка-бомба, лидам настоятельно рекомендую, особенно на новых проектах🦀
👾 PICO
Для битвы пет проектов я решил попробовать относительно новый для себя подход - ATDD, о котором я уже рассказывал. И, к удивлению для себя самого, я ни разу об этом не пожалел.
Начну, внезапно, с минусов. Это время. Да, на реализацию фичи через автотесты уходит время. Где-то в каком-то исследовании даже видел конкретную цифру, фича занимает в среднем на 16% больше времени, если разработка идет через тестирование или если на фичу тесты пишутся после реализации. По прошествии полутора недель активной работы, это действительно ощущается так. Возможно, мы тратим на это даже больше.
Но самое интересное, что... больше минусов нет.
Вот серьезно, после реализации фичи вы получаете гарантированно работающий пользовательский сценарий (а то и несколько), который точно несет полезность для конечного потребителя продукта. Нужно больше уверенности? Просто добавляйте больше сценариев, покрывайте узкие, нестандартные кейсы и ошибки в рамках фичи.
Наш процесс приемки задач состоит из одного шага - код-ревью. Код решает задачу наших пользователей потому что мы начинаем разработку с пользовательского сценария. А в том что он точно работает я убеждаюсь благодаря автотестам.
Вы только посмотрите на наш Code Coverage (скрин в шапке). Помимо очевидного покрытия кода тестами эти цифры также показывают нам, что мы не делаем лишних вещей. Все о чем говорится в сценарии должно быть покрыто тестами. И оно покрыто.
Благодаря такому подходу я, как лид команды, в рамках ревью фокусируюсь на качестве кода, на его архитектуре, на взаимодействиях между модулями, и совершенно не беру на себя ответственность контролировать качество работы написанного кода, его соответствие требуемой бизнес-логике, так как эти вещи в нашем подходе автоматизированы благодаря ATDD.
Да, мы тратим больше времени на разработку, но мы получаем невероятную экономию буквально всех ресурсов команды на тестировании и контроле качества.
Пушка-бомба, лидам настоятельно рекомендую, особенно на новых проектах
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🤡1
Monolith over Microservices
Да-да, я снова про битву пет-проектов. На этот раз поговорим об архитектуре.
В кругу разработчиков часто популярен холивар в отношении программных архитектур для web-сервисов, мол, что выбрать, монолит или микросервисы, а для каких задач что подходит лучше и т.д. Есть строгие приверженцы одного из подходов, есть балансирующие между, но суть споров чаще всего одна - плюсы и минусы которые тот или иной подход в себе несет. Как-то я написал развернутый ответ на SO об отличиях монолитов и микросервисов и как плавно переходить от одного к другому.
Перед стартом битвы пет-проектов я тоже столкнулся с этой дилемой. С одной стороны есть монолит - простое и верное решение с минимальными затратами, но высокими рисками "завязывания" кода. С другой - микросервисы, хайповый и популярный путь с минимумом зависимостей, но сложностью развертывания и взаимодействия между сервисами.
А что если мы постараемся взять плюсы обоих подходов?
Допустим, у нас есть веб-сервис, единый (монолитный) исполняемый файл, под которым прячутся 2-4 микросервиса.
Какие плюсы:
- Простота развертывания. Один докерфайл и больше ничего. В отличие от классических микросервисов.
- Слабая связанность. Микросервисы внутри строго отделены друг от друга. От монолита требуется только запустить их всех вместе.
- Очень быстрый переход на микросервисные рельсы, в случаях, когда это необходимо. Мы просто выносим микросервис из монолита и разворачиваем отдельно по щелчку пальца.
Минусы:
- Нужно очень хорошо продумать архитектуру решения. Так чтобы можно было и быстро микросервис отделить и обеспечивалась достаточная обобщенность настройки.
- Не все внешние библиотеки можно настроить для исполнения под такой архитектурой. Я бы даже сказал, что их достаточно мало.
Можно сказать, что это переизобретенный SOA, но ключевое отличие тут в том, что микросервис - это не модуль ПО, а полноценное приложение со своими точками входа для пользователей.
Пример подобной архитектуры можно посмотреть в нашем репозитории для битвы
👾 PICO
Да-да, я снова про битву пет-проектов. На этот раз поговорим об архитектуре.
В кругу разработчиков часто популярен холивар в отношении программных архитектур для web-сервисов, мол, что выбрать, монолит или микросервисы, а для каких задач что подходит лучше и т.д. Есть строгие приверженцы одного из подходов, есть балансирующие между, но суть споров чаще всего одна - плюсы и минусы которые тот или иной подход в себе несет. Как-то я написал развернутый ответ на SO об отличиях монолитов и микросервисов и как плавно переходить от одного к другому.
Перед стартом битвы пет-проектов я тоже столкнулся с этой дилемой. С одной стороны есть монолит - простое и верное решение с минимальными затратами, но высокими рисками "завязывания" кода. С другой - микросервисы, хайповый и популярный путь с минимумом зависимостей, но сложностью развертывания и взаимодействия между сервисами.
А что если мы постараемся взять плюсы обоих подходов?
Допустим, у нас есть веб-сервис, единый (монолитный) исполняемый файл, под которым прячутся 2-4 микросервиса.
Какие плюсы:
- Простота развертывания. Один докерфайл и больше ничего. В отличие от классических микросервисов.
- Слабая связанность. Микросервисы внутри строго отделены друг от друга. От монолита требуется только запустить их всех вместе.
- Очень быстрый переход на микросервисные рельсы, в случаях, когда это необходимо. Мы просто выносим микросервис из монолита и разворачиваем отдельно по щелчку пальца.
Минусы:
- Нужно очень хорошо продумать архитектуру решения. Так чтобы можно было и быстро микросервис отделить и обеспечивалась достаточная обобщенность настройки.
- Не все внешние библиотеки можно настроить для исполнения под такой архитектурой. Я бы даже сказал, что их достаточно мало.
Можно сказать, что это переизобретенный SOA, но ключевое отличие тут в том, что микросервис - это не модуль ПО, а полноценное приложение со своими точками входа для пользователей.
Пример подобной архитектуры можно посмотреть в нашем репозитории для битвы
👾 PICO
Developer Experience
Недавно состоялся вебинар в моей любимой школе сильных программистов на тему так называемого developer experience. Не сказать, что он прошел прям увлекательно, но и не бесполезно🏃♀️
Если кратко, то DevEx - это про удобство разработчика. А суть развития DevEx - это привнесение в свою профессиональную деятельность больше удовольствия (читай: эффективности) и, соответственно, меньше ерунды.
В разработке обычно как, вот есть у тебя кодовая база, сиди работай. Горит дедлайн? Нужно успеть в срок. Огромный техдолг? Терпи, братиш, мы - бизнес, мы рубим деньги. Мы работаем на пределе возможностей, но нужен результат лучше? Просто наймем новых программистов! Или ничего не будем делать, если денег нет :C
Крайне мало кто задумывается о том, а насколько программистам в удовольствие работать в компании? Сравнивать максимализируя лучше всего.
Вот есть программист Паша, работает с легаси кодовой базой, огромным техдолгом и 1-2 встречами в день по часу каждая. Будет ли он доволен? Будет ли эффективен? Да конечно нет, ему захочется скорее закрыть IDE с этим ужасом и пойти домой пилить свои пет-проекты. Повседневная деятельность Паши в тягость
А есть разработчик Юля, работает в репозитории с чистой архитектурой, с автотестами и автодеплоем. Будет ли она довольна? Будет ли эффективна? Ну конечно да! Ведь на выполнение задач уходит в разы меньше времени, а количество багов измеряется единицами. Повседневная деятельность Юли в радость
В DevEx легко разглядеть реально полезный для всех сторон (win-win) мотиватор. Делай своим разработчикам хорошо и получай эффективный результат. В слепой погоне за целями часто можно упустить простейшие инструменты повышения эффективности, этот, на мой взгляд, один из таких. Что-то из серии "нормально делай - нормально будет".
Ну а если вы не управляете людьми - вы можете инвестировать в свой собственный DevEx. Просто спросите себя: А что я могу сделать, чтобы получать больше удовольствия от повседневной разработки?
Возможно, ответ вас удивит🐸 🐸 🐸
👾 PICO
Недавно состоялся вебинар в моей любимой школе сильных программистов на тему так называемого developer experience. Не сказать, что он прошел прям увлекательно, но и не бесполезно
Если кратко, то DevEx - это про удобство разработчика. А суть развития DevEx - это привнесение в свою профессиональную деятельность больше удовольствия (читай: эффективности) и, соответственно, меньше ерунды.
В разработке обычно как, вот есть у тебя кодовая база, сиди работай. Горит дедлайн? Нужно успеть в срок. Огромный техдолг? Терпи, братиш, мы - бизнес, мы рубим деньги. Мы работаем на пределе возможностей, но нужен результат лучше? Просто наймем новых программистов! Или ничего не будем делать, если денег нет :C
Крайне мало кто задумывается о том, а насколько программистам в удовольствие работать в компании? Сравнивать максимализируя лучше всего.
Вот есть программист Паша, работает с легаси кодовой базой, огромным техдолгом и 1-2 встречами в день по часу каждая. Будет ли он доволен? Будет ли эффективен? Да конечно нет, ему захочется скорее закрыть IDE с этим ужасом и пойти домой пилить свои пет-проекты. Повседневная деятельность Паши в тягость
А есть разработчик Юля, работает в репозитории с чистой архитектурой, с автотестами и автодеплоем. Будет ли она довольна? Будет ли эффективна? Ну конечно да! Ведь на выполнение задач уходит в разы меньше времени, а количество багов измеряется единицами. Повседневная деятельность Юли в радость
В DevEx легко разглядеть реально полезный для всех сторон (win-win) мотиватор. Делай своим разработчикам хорошо и получай эффективный результат. В слепой погоне за целями часто можно упустить простейшие инструменты повышения эффективности, этот, на мой взгляд, один из таких. Что-то из серии "нормально делай - нормально будет".
Ну а если вы не управляете людьми - вы можете инвестировать в свой собственный DevEx. Просто спросите себя: А что я могу сделать, чтобы получать больше удовольствия от повседневной разработки?
Возможно, ответ вас удивит
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
💩2
Каша в репозитории
В недавнем прямом эфире на хабр.карьере я рассказывал про SpecFlow и вскользь упомянул о "каше", которая появляется, если разработчики перестают следить за структурой и жёсткими рамками архитектуры проекта.
Казалось бы, проблема не нова, но до сих пор встречаю репозитории с этой проблемой, где просто нет внятных решений, которые бы направляли и подсказывали мне "а как тут принято".
Отсутствие подобных решений приводит к тому, что новый код, который напишется в рамках работы над репозиторием, будет лишён "направления". И получается, что каждый программист привносит в структуру репозитория свое собственное видение, которое ничем не ограничено, что и влечет за собой появление "каши". Достаточно неприятный фактор, контроль которого ложится на плечи роли, отвечающей за архитектуру решения. Но чаще всего на проблему просто забивают.
Методик избавления от этой каши много, но их все объединяет один принцип - это выстраивание архитектурных ограничений.
В последнее время я применяю для этого несколько подходов:
- Гексагональная архитектура. Стандартный способ разделения приложения на слои. Глубину ее применения можно очень удобно регулировать, например, объединив слои Application и Domain, если доменная область достаточно проста. Это позволяет контролировать гибкость внедряемых архитектурой ограничений.
- Feature Sliced Design (FSD). Суть его в том, что сначала кодовая база разделяется на слои, затем на фичи (слайсы), и лишь только в конце на компоненты (репозитории, команды, хелперы и тд.). Не смотря на то, что подход считается основой для фронтендеров - ничего не мешает применять схожий подход и на бекенде. Его внедрение в конечном итоге очень сильно помогает быстрее искать место необходимости внесения изменений и кратно снижает когнитивную нагрузку.
- SpecFlow и ATDD. Написание нового функционала через автотесты автоматически добавляет ограничение "тестируемости", что хорошо сказывается как на архитектуре, так и на качестве итогового продукта, его готовности к последующим изменениям.
👾 PICO
В недавнем прямом эфире на хабр.карьере я рассказывал про SpecFlow и вскользь упомянул о "каше", которая появляется, если разработчики перестают следить за структурой и жёсткими рамками архитектуры проекта.
Казалось бы, проблема не нова, но до сих пор встречаю репозитории с этой проблемой, где просто нет внятных решений, которые бы направляли и подсказывали мне "а как тут принято".
Отсутствие подобных решений приводит к тому, что новый код, который напишется в рамках работы над репозиторием, будет лишён "направления". И получается, что каждый программист привносит в структуру репозитория свое собственное видение, которое ничем не ограничено, что и влечет за собой появление "каши". Достаточно неприятный фактор, контроль которого ложится на плечи роли, отвечающей за архитектуру решения. Но чаще всего на проблему просто забивают.
Методик избавления от этой каши много, но их все объединяет один принцип - это выстраивание архитектурных ограничений.
В последнее время я применяю для этого несколько подходов:
- Гексагональная архитектура. Стандартный способ разделения приложения на слои. Глубину ее применения можно очень удобно регулировать, например, объединив слои Application и Domain, если доменная область достаточно проста. Это позволяет контролировать гибкость внедряемых архитектурой ограничений.
- Feature Sliced Design (FSD). Суть его в том, что сначала кодовая база разделяется на слои, затем на фичи (слайсы), и лишь только в конце на компоненты (репозитории, команды, хелперы и тд.). Не смотря на то, что подход считается основой для фронтендеров - ничего не мешает применять схожий подход и на бекенде. Его внедрение в конечном итоге очень сильно помогает быстрее искать место необходимости внесения изменений и кратно снижает когнитивную нагрузку.
- SpecFlow и ATDD. Написание нового функционала через автотесты автоматически добавляет ограничение "тестируемости", что хорошо сказывается как на архитектуре, так и на качестве итогового продукта, его готовности к последующим изменениям.
👾 PICO
❤3
GraphQL + CQRS
Решил наконец ознакомиться с графом и был приятно удивлен его возможностями.
Представим, что нам необходимо сделать функционал отображения двух списков. Первый - подробный, с названием, картинками, длинным описанием и комментариями. Второй - упрощенный, отображающий только название входящих в него элементов
В REST мы бы подготовили два эндпоинта. Один для получения полного списка, второй для упрощённого. При этом на бекенде необходимо будет для каждого эндпоинта реализовать свой маппинг.
А в графе все очень просто. Мы описываем максимально полную модель подробного списка. А уже на фронтенде определяем где нам нужно выгрузить подробную информацию по списку, а где нужна минимальная, просто передавая на бекенд поля, которые ожидаем получить.
Плюс ко всему, в рамках одного запроса к одному эндпоинту графа мы можем получить сразу несколько сущностей, обращаясь как будто бы к разным эндпоинтам REST'а.
Это даёт огромную гибкость, атомарность в разработке фронтенда и упрощает архитектуру бекенда.
Правда точки зрения скорости не все гладко, на каждый запрос нам приходится так и так доставать из базы максимально полную модель требуемых данных, а затем резать их перед отдачей на фронт. Ну, или придумывать довольно непростые хаки, чтобы оптимизировать чтение.
На GraphQL очень хорошо ложится CQRS паттерн. Поскольку на фронте мы получаем атомарность, можно экстраполировать ее и на наш бекенд. В рамках запроса могут выполниться, например, одновременно несколько queries или commands, отрабатывая по очереди на уровне бекенда.
Таким образом мы получаем четкое разделение ответственности на бекенде, избавляемся от каши в репозитории и соблюдаем единообразие кодовой базы.
Я определенно точно познал не весь дзен использования графа. Продолжаю наблюдение👀
- GraphQL для C#: HotChocolate
👾 PICO
Решил наконец ознакомиться с графом и был приятно удивлен его возможностями.
Кто не в теме, очень кратко:
GraphQL - это прямая противоположность REST. Единая точка входа. Принимает набор команд, отдает результат их исполнения. При этом в самом запросе определяются возвращаемые данные.
Представим, что нам необходимо сделать функционал отображения двух списков. Первый - подробный, с названием, картинками, длинным описанием и комментариями. Второй - упрощенный, отображающий только название входящих в него элементов
В REST мы бы подготовили два эндпоинта. Один для получения полного списка, второй для упрощённого. При этом на бекенде необходимо будет для каждого эндпоинта реализовать свой маппинг.
А в графе все очень просто. Мы описываем максимально полную модель подробного списка. А уже на фронтенде определяем где нам нужно выгрузить подробную информацию по списку, а где нужна минимальная, просто передавая на бекенд поля, которые ожидаем получить.
Плюс ко всему, в рамках одного запроса к одному эндпоинту графа мы можем получить сразу несколько сущностей, обращаясь как будто бы к разным эндпоинтам REST'а.
Это даёт огромную гибкость, атомарность в разработке фронтенда и упрощает архитектуру бекенда.
Правда точки зрения скорости не все гладко, на каждый запрос нам приходится так и так доставать из базы максимально полную модель требуемых данных, а затем резать их перед отдачей на фронт. Ну, или придумывать довольно непростые хаки, чтобы оптимизировать чтение.
На GraphQL очень хорошо ложится CQRS паттерн. Поскольку на фронте мы получаем атомарность, можно экстраполировать ее и на наш бекенд. В рамках запроса могут выполниться, например, одновременно несколько queries или commands, отрабатывая по очереди на уровне бекенда.
Таким образом мы получаем четкое разделение ответственности на бекенде, избавляемся от каши в репозитории и соблюдаем единообразие кодовой базы.
Я определенно точно познал не весь дзен использования графа. Продолжаю наблюдение
- GraphQL для C#: HotChocolate
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Галя, отмена!
Современный веб сделан так, что на открытие одной странички на сервер летит с десяток запросов за данными. Если юзер быстро навигируется по сайту\приложению - мы можем получить ситуацию, что большая часть запросов ему просто не нужна. А сервер продолжает на эти запросы пахать. Чтобы чуток помочь нашему серверу мы можем реализовать функционал отмены запросов.
В C# (
ASP.NET) есть встроенный механизм, который позволяет получить сигнал о том, что пользователь отменил запрос. Из этого механизма мы можем получить CancellationToken, взаимодействуя с которым проверять, ждет ли еще пользователь нашего запроса, или мы можем его отменить?В общем случае
CancellationToken прокидывают в параметрах методов (из-за опасности возникновения captive dependencies - про это расскажу как-нибудь позже). Но если вдруг у вас в приложении все классы, которым нужен токен (в основном репозитории, адаптеры к файловой системе, адаптеры к другим API), регистрируются как Scoped - то вы можете себе позволить заинжектить его через DI и немножко облегчить себе жизнь.Создаем провайдер токена из контекста запроса:
public class CancellationTokenProvider
{
public CancellationTokenProvider(
IHttpContextAccessor httpContextAccessor
)
{
Token =
httpContextAccessor.HttpContext
?.RequestAborted
?? CancellationToken.None;
}
public CancellationToken Token { get; }
}
Подключаем в DI:
services.AddHttpContextAccessor();
services.AddScoped<CancellationTokenProvider>();
Юзаем:
private readonly CancellationToken _ct;
public Repository(CancellationTokenProvider ctp)
{
_ct = ctp.Token;
}
P.S. Никита, спасибо, что напомнил про эту штуку!
Please open Telegram to view this post
VIEW IN TELEGRAM
👾6🤔1
Excalidraw
Лучший тул для изложения мыслей на экран.
Если вы рисуете схемки, диаграммы или небольшие макеты в каком-нибудь draw.io или visio, то наверняка вы сталкивались с ощущением, что для вашей задачи инструмент выбран черезчур уж громоздкий.
Постоянно жил с этим чувством, всегда хотелось, чтобы "как на бумаге", пока поиск инструмента попроще не привел меня к замечательному продукту excalidraw.
Не буду петь про него дифирамбы - просто посмотрите сами, как там все лаконично и просто. С4 архитектурную диаграмму крупного предприятия, конечно, в нем строить не стоит, но вот для изложения своих мыслей на экран и быстрых "зарисовок" - самое то.
Не пользуюсь планшетами, но по инфе с реддита - отлично работает и на них.
Синхронизация между девайсами доступна только по подписке, но такому инструменту я точно бы забашлял, пользуюсь какой год. В любом случае, о широких возможностях импорта\экспорта разработчики не забыли и в бесплатной версии.
Попробовать можно тут
#tools
👾 PICO
Лучший тул для изложения мыслей на экран.
Если вы рисуете схемки, диаграммы или небольшие макеты в каком-нибудь draw.io или visio, то наверняка вы сталкивались с ощущением, что для вашей задачи инструмент выбран черезчур уж громоздкий.
Постоянно жил с этим чувством, всегда хотелось, чтобы "как на бумаге", пока поиск инструмента попроще не привел меня к замечательному продукту excalidraw.
Не буду петь про него дифирамбы - просто посмотрите сами, как там все лаконично и просто. С4 архитектурную диаграмму крупного предприятия, конечно, в нем строить не стоит, но вот для изложения своих мыслей на экран и быстрых "зарисовок" - самое то.
Не пользуюсь планшетами, но по инфе с реддита - отлично работает и на них.
Синхронизация между девайсами доступна только по подписке, но такому инструменту я точно бы забашлял, пользуюсь какой год. В любом случае, о широких возможностях импорта\экспорта разработчики не забыли и в бесплатной версии.
Попробовать можно тут
#tools
Please open Telegram to view this post
VIEW IN TELEGRAM
✍4🔥4👍1👾1
Не могу не поделиться, очень приятно ощущать в том числе и свой вклад в эту победу!
Команда максимально крутых профессионалов с ультра-интересными задачами и здоровой корпоративной культурой.
Заслуженно!
Но над узнаваемостью нужно еще потрудиться, работаем!
Если интересна тема кибербезопасности - натыкайте лайков, мб расскажу че-нить годное из этой сферы
https://habr.com/ru/specials/773642/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9💩1
Ory
Достаточно интересная линейка продуктов для Identity Management - всего, что связано с аутентификацией и авторизацией пользователей.
С этой линейкой можно:
Поорать с греческой мифологии в Ory Kratos
Кратос - это сердце identity системы. Он управляет пользователями и пользовательскими сессиями. Ставите postgres, поднимаете Кратос, прогоняете миграции, вуаля, айдентити система готова, эндпоинты для регистрации, авторизации и вот этого всего можно найти в документации.
Принести клятву верности в Ory Oathkeeper
шКипер - это прокси со встроенной проверкой на доступ к ресурсам. Ставите Кратос, ставите ваш продукт рядом, ставите Кипер над всем этим добром, настраиваете маршрутизацию. Теперь только авторизованные (через Кратос) пользователи могут получить доступ к вашему продукту. Удобно. Также можно поставить его под какой-то из существующих проксей, типа traefik или nginx.
Побороться с древними существами в Ory Hydra
Гидра позволяет подключить авторизацию и аутентификацию по OAuth2 и OIDC к существующей iam системе, чтобы обеспечить бесшовную авторизацию между различными системами и продуктами.
Не знаю, придумайте аналогию сами - Ory Keto
Кето - это про пользовательские роли и привилегии. Он поможет отвечать на вопрос "а может ли этот пользователь обращаться к этому ресурсу?". Гибкая система конфигурации и правил, подробности, опять же, в документации.
Вывод
Открытый исходный код, последние стандарты безопасности, быстрое развертывание в пару команд, поддержка различных веб-хуков и гибкая конфигурация.
В целом продуктами доволен, работают стабильно и достаточно быстро.
Из небольших минусов могу отметить жесткую привязку к postgres в качестве хранилища данных. Поднять продукты Ory, например, на Mongo, не получится.
Также не очень зашла документация, достаточно сложна для восприятия, но при желании и методом "тыка" разобраться можно.
Если нужно готовое решение для полного флоу аутентификации пользователей - заценить линейку точно стоит.
Официальный сайт Ory
👾 PICO
Ахах, ору
Достаточно интересная линейка продуктов для Identity Management - всего, что связано с аутентификацией и авторизацией пользователей.
С этой линейкой можно:
Поорать с греческой мифологии в Ory Kratos
Кратос - это сердце identity системы. Он управляет пользователями и пользовательскими сессиями. Ставите postgres, поднимаете Кратос, прогоняете миграции, вуаля, айдентити система готова, эндпоинты для регистрации, авторизации и вот этого всего можно найти в документации.
Принести клятву верности в Ory Oathkeeper
Побороться с древними существами в Ory Hydra
Гидра позволяет подключить авторизацию и аутентификацию по OAuth2 и OIDC к существующей iam системе, чтобы обеспечить бесшовную авторизацию между различными системами и продуктами.
Не знаю, придумайте аналогию сами - Ory Keto
Кето - это про пользовательские роли и привилегии. Он поможет отвечать на вопрос "а может ли этот пользователь обращаться к этому ресурсу?". Гибкая система конфигурации и правил, подробности, опять же, в документации.
Вывод
Открытый исходный код, последние стандарты безопасности, быстрое развертывание в пару команд, поддержка различных веб-хуков и гибкая конфигурация.
В целом продуктами доволен, работают стабильно и достаточно быстро.
Из небольших минусов могу отметить жесткую привязку к postgres в качестве хранилища данных. Поднять продукты Ory, например, на Mongo, не получится.
Также не очень зашла документация, достаточно сложна для восприятия, но при желании и методом "тыка" разобраться можно.
Если нужно готовое решение для полного флоу аутентификации пользователей - заценить линейку точно стоит.
Официальный сайт Ory
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Captive Dependencies
В недавнем посте про Cancellation Token я вскользь упоминал про эту проблему. Пришло время рассказать о ней поподробнее.
Captive Dependency - это ситуация, когда объект с быстрым жизненным циклом является зависимостью для объекта с медленным жизненным циклом. В контексте ASP.NET такая ситуация возникает тогда, когда вы регистрируете класс как Singleton, а в его зависимостях присутствуют классы, зарегистрированные как Scoped.
В отношении CancellationToken ситуация аналогичная. CancellationToken - это токен отмены текущего запроса, он зарегистрирован как Scoped и имеет короткий жизненный цикл. И если мы загружаем CancellationToken в конструктор Singleton-объекта, то вот и получается Captive Dependency. Именно по этой причине самым безопасным путем будет прокидывать CancellationToken параметром метода, потому что вызов метода (даже у singleton-объекта) гарантированно происходит в рамках scope-а.
Конфигурация с имеющимися в ней Captive Dependencies по факту является ошибочной, но различные DI-фреймворки позволяют настраивать отношение к такого рода конфигурациям.
Например, стандартный Microsoft DI имеет встроенный механизм валидации, который за вас пройдется по всему дереву собираемых зависимостей и определит наличие captive dependencies, а затемдаст леща выбросит эксепшн с указанием, мол "ай-ай-ай, так делать нельзя", но его нужно не забыть включить при сборке скоупа. Красиво, Майки, спасибо!
А вот популярная библиотека для зависимостей Autofaс прямым текстом говорит:
Заставляя бедных разработчиков вручную просматривать дерево зависимостей, сформированное autofac и искать проблемные места (самому злейшему врагу не пожелаю столкнуться с этим в большом проекте).
Избегать этой проблемы нужно начиная с самых ранних этапов зарождения проекта, а самый дельный совет при этом стар как сам фортран - избегайте singleton'ов, а если они и необходимы, то делайте их максимально независимыми от других объектов.
👾 PICO
В недавнем посте про Cancellation Token я вскользь упоминал про эту проблему. Пришло время рассказать о ней поподробнее.
Captive Dependency - это ситуация, когда объект с быстрым жизненным циклом является зависимостью для объекта с медленным жизненным циклом. В контексте ASP.NET такая ситуация возникает тогда, когда вы регистрируете класс как Singleton, а в его зависимостях присутствуют классы, зарегистрированные как Scoped.
В отношении CancellationToken ситуация аналогичная. CancellationToken - это токен отмены текущего запроса, он зарегистрирован как Scoped и имеет короткий жизненный цикл. И если мы загружаем CancellationToken в конструктор Singleton-объекта, то вот и получается Captive Dependency. Именно по этой причине самым безопасным путем будет прокидывать CancellationToken параметром метода, потому что вызов метода (даже у singleton-объекта) гарантированно происходит в рамках scope-а.
Конфигурация с имеющимися в ней Captive Dependencies по факту является ошибочной, но различные DI-фреймворки позволяют настраивать отношение к такого рода конфигурациям.
Например, стандартный Microsoft DI имеет встроенный механизм валидации, который за вас пройдется по всему дереву собираемых зависимостей и определит наличие captive dependencies, а затем
А вот популярная библиотека для зависимостей Autofaс прямым текстом говорит:
Stopping captive dependencies is the responsibility of the developer.
Заставляя бедных разработчиков вручную просматривать дерево зависимостей, сформированное autofac и искать проблемные места (самому злейшему врагу не пожелаю столкнуться с этим в большом проекте).
Избегать этой проблемы нужно начиная с самых ранних этапов зарождения проекта, а самый дельный совет при этом стар как сам фортран - избегайте singleton'ов, а если они и необходимы, то делайте их максимально независимыми от других объектов.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3
NuGet Central Package Management
Каждому шарписту приходится сталкиваться с обновлением внешних зависимостей. Обычно, это достаточно болезненная операция, а если вы перескакиваете сразу несколько мажорных версий у зависимости - вам потребуется минимум месяц реабилитации на Сейшелах (передаю привет Selenium-у).
В последнее время Майки хорошо подтянули инструментарий по управлению зависимостями и постепенно перенимают лучшие практики у новых пакетных менеджеров. Так появился функционал Central Package Management в нашем NuGet Package Manager'е.
Если раньше в каждом проекте (.csproj) нужно было указывать зависимый внешний пакет и его версию, то теперь есть четкое разделение: в проектах указываются только наименования зависимых пакетов (без версии), а версия указывается централизованно в отдельном файле для всего решения (.sln).
Это закрывает сразу несколько проблем:
1. Когда в одном проекте используется внешний пакет версии X, а в соседнем используется тот же пакет версии Y. С применением CPM такая ситуация более невозможна. Обходим стороной целый пласт потенциальных проблем.
2. Отслеживать и управлять зависимостями стало гораздо проще и быстрее. Надо обновить минорную зависимость? Изменяем только 1 строчку во всем репозитории - готово.
Как подключить?
Необходимый минимум - это .NET 6.0
Добрые люди написали утилиту миграции. Работает, проверено. Если нужно мигрироваться на новый формат работы с зависимостями - очень полезная штука.
Но если ваш проект небольшой, можно сделать ручками по инструкции.
По умолчанию при создании новых проектов эта система выключена. Наверное поэтому мало кто знает о том, что в шарпах присутствует централизованное управление зависимостями (уже полтора года как, кстати)
👾 PICO
Каждому шарписту приходится сталкиваться с обновлением внешних зависимостей. Обычно, это достаточно болезненная операция, а если вы перескакиваете сразу несколько мажорных версий у зависимости - вам потребуется минимум месяц реабилитации на Сейшелах (передаю привет Selenium-у).
В последнее время Майки хорошо подтянули инструментарий по управлению зависимостями и постепенно перенимают лучшие практики у новых пакетных менеджеров. Так появился функционал Central Package Management в нашем NuGet Package Manager'е.
Если раньше в каждом проекте (.csproj) нужно было указывать зависимый внешний пакет и его версию, то теперь есть четкое разделение: в проектах указываются только наименования зависимых пакетов (без версии), а версия указывается централизованно в отдельном файле для всего решения (.sln).
Это закрывает сразу несколько проблем:
1. Когда в одном проекте используется внешний пакет версии X, а в соседнем используется тот же пакет версии Y. С применением CPM такая ситуация более невозможна. Обходим стороной целый пласт потенциальных проблем.
2. Отслеживать и управлять зависимостями стало гораздо проще и быстрее. Надо обновить минорную зависимость? Изменяем только 1 строчку во всем репозитории - готово.
Как подключить?
Необходимый минимум - это .NET 6.0
Добрые люди написали утилиту миграции. Работает, проверено. Если нужно мигрироваться на новый формат работы с зависимостями - очень полезная штука.
Но если ваш проект небольшой, можно сделать ручками по инструкции.
По умолчанию при создании новых проектов эта система выключена. Наверное поэтому мало кто знает о том, что в шарпах присутствует централизованное управление зависимостями (уже полтора года как, кстати)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Четкие миграции
Так уж вышло, что последнее время я стал отгружать на канал свои best practices в разработке по самым разным направлениям. Сегодня поговорим о миграциях.
Под миграцией я буду иметь в виду накатку на базу данных различного рода скриптов, содержащих изменения схемы, наборы данных, определения функций, триггеров и т.п.
За свою практику я встречал 2 подхода к выкатке миграций и просто невероятное количество их костыльных реализаций.
Первый подход - идемпотентный (важно прочитать это слово правильно). Есть набор скриптов в котором описано конечное состояние базы данных. Накатываем скрипты - получаем готовую к использованию бд. При этом важно, чтобы повторная накатка скриптов не приводила к изменению состояния бд и не дублировала сущности (это и есть свойство идемпотентности). Нужно поменять схему? Меняй этот скрипт и накатывай повторно.
Второй подход - инкрементальный. Есть набор скриптов, у каждого скрипта есть версия. Все скрипты выполняются последовательно, в соответствии своих версий. Нужно поменять схему? Пиши новый скрипт.
Оба подхода живут в современных продакшенах, но для своих решений я всегда стараюсь совмещать их вместе.
Очень хорошим инструментом (но, к сожалению, не идеальным) для совмещения обоих подходов в .NET экосистеме является библиотека Evolve.
В концепцию гибридного подхода положено четкое разделение типов миграций: версионные и повторяемые.
Версионные миграции выполняются инкрементальным подходом, имеют версию и жёсткий порядок выполнения.
Повторяемые миграции ориентированы на идемпотентный подход. При каждом выполнении миграций все повторяемые миграции безусловно накатываются на БД.
Гибридный подход очень гибок, вы можете, например, описать набор хранимых процедур (функций) в повторяемых миграциях, а изменения схемы в версионных и это очень удобно. Ваши миграции перестают засорять кодовую базу, при этом вы пользуетесь преимуществами обоих подходов.
Используйте гибридный формат описания миграций, это развяжет вам руки при выполнении бизнесовых задач.
👾 PICO
Так уж вышло, что последнее время я стал отгружать на канал свои best practices в разработке по самым разным направлениям. Сегодня поговорим о миграциях.
Под миграцией я буду иметь в виду накатку на базу данных различного рода скриптов, содержащих изменения схемы, наборы данных, определения функций, триггеров и т.п.
За свою практику я встречал 2 подхода к выкатке миграций и просто невероятное количество их костыльных реализаций.
Первый подход - идемпотентный (важно прочитать это слово правильно). Есть набор скриптов в котором описано конечное состояние базы данных. Накатываем скрипты - получаем готовую к использованию бд. При этом важно, чтобы повторная накатка скриптов не приводила к изменению состояния бд и не дублировала сущности (это и есть свойство идемпотентности). Нужно поменять схему? Меняй этот скрипт и накатывай повторно.
Второй подход - инкрементальный. Есть набор скриптов, у каждого скрипта есть версия. Все скрипты выполняются последовательно, в соответствии своих версий. Нужно поменять схему? Пиши новый скрипт.
Оба подхода живут в современных продакшенах, но для своих решений я всегда стараюсь совмещать их вместе.
Очень хорошим инструментом (но, к сожалению, не идеальным) для совмещения обоих подходов в .NET экосистеме является библиотека Evolve.
В концепцию гибридного подхода положено четкое разделение типов миграций: версионные и повторяемые.
Версионные миграции выполняются инкрементальным подходом, имеют версию и жёсткий порядок выполнения.
Повторяемые миграции ориентированы на идемпотентный подход. При каждом выполнении миграций все повторяемые миграции безусловно накатываются на БД.
Гибридный подход очень гибок, вы можете, например, описать набор хранимых процедур (функций) в повторяемых миграциях, а изменения схемы в версионных и это очень удобно. Ваши миграции перестают засорять кодовую базу, при этом вы пользуетесь преимуществами обоих подходов.
Используйте гибридный формат описания миграций, это развяжет вам руки при выполнении бизнесовых задач.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍3👍1
Chocolatey
В новом году, пожалуй, начнем разгон с чего-то попроще, скажем, с популярного пакетного менеджера для установки ПО на Windows.
Мой опыт переустановки винды сопряжён с болью, когда после каждой инсталляции необходимо заново ручками бегать по интернету и качать программулины. Примерно 30% от нужного софта вообще забываю поставить. Знакомо?
С пакетным менеджером Chocolatey этой проблемы больше нет. По сути тулза представляет собой централизованное место, откуда можно установить (почти) любой софт с помощью одной консольной команды.
Достаточно провести инвентаризацию софта на текущей машине, собрать небольшой скрипт-установщик и после переустановки винды запустить его. На выходе получаете укомплектованное рабочее место, осталось только заавторизоваться во всем этом софте🫠
Помимо установки, Чоко поможет вам и с обновлением приложений, весь софт, установленный с помощью пакетного менеджера можно обновить одной командой, как в маке или линуксе (если приложение имеет функцию автообновления, его можно исключить из обновлений Чоко)
Вообще этот менеджер обладает большими возможностями и способен помочь, например, при администрировании виндовой инфраструктуры или поднятии виртуалок с предустановленным ПО. Ну и каждый может добавлять в него недостающий софт для последующей установки.
Пользуюсь шоколадкой уже какой год и вам советую)
Chocolatey: Getting Started
#tools
👾 PICO
В новом году, пожалуй, начнем разгон с чего-то попроще, скажем, с популярного пакетного менеджера для установки ПО на Windows.
Мой опыт переустановки винды сопряжён с болью, когда после каждой инсталляции необходимо заново ручками бегать по интернету и качать программулины. Примерно 30% от нужного софта вообще забываю поставить. Знакомо?
С пакетным менеджером Chocolatey этой проблемы больше нет. По сути тулза представляет собой централизованное место, откуда можно установить (почти) любой софт с помощью одной консольной команды.
Достаточно провести инвентаризацию софта на текущей машине, собрать небольшой скрипт-установщик и после переустановки винды запустить его. На выходе получаете укомплектованное рабочее место, осталось только заавторизоваться во всем этом софте
Помимо установки, Чоко поможет вам и с обновлением приложений, весь софт, установленный с помощью пакетного менеджера можно обновить одной командой, как в маке или линуксе (если приложение имеет функцию автообновления, его можно исключить из обновлений Чоко)
Вообще этот менеджер обладает большими возможностями и способен помочь, например, при администрировании виндовой инфраструктуры или поднятии виртуалок с предустановленным ПО. Ну и каждый может добавлять в него недостающий софт для последующей установки.
Пользуюсь шоколадкой уже какой год и вам советую)
Chocolatey: Getting Started
#tools
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1
Source Generators in C#
Спустя несколько лет после релиза, наконец, добрался до этих знаменитых сорс генераторов, и теперь могу записать себя в ряды метапрограммистов.
Интересно, а постметапрограммисты будут?
Поделюсь своими впечатлениями от использования.
В первую очередь, что бросается в глаза - действительно хорошая гибкость инструмента. Он развязывает руки настолько, что кажется любой компонент разрабатываемого проекта можно так или иначе сделать модульным и расширять на основе внешних понятных конфигов или ещё чего покруче.
Поскольку эта штука compile-time, а все генерируемые файлы можно посмотреть прямиком в solution explorer - инструмент крайне прозрачен. Он делает все явно и без "магии", любой сгенерированный файлик можно увидеть и применить к нему IntelliSense вашей IDE.
Hot Reload. Ну это вообще бомба. Любой файл, связанный с сорс генератором, подвергнувшись изменению, оповещает сорс генератор и можно в реальном времени увидеть новый сгенерированный код без перекомпиляции. Супер удобно.
Из минусов отмечу отсутствие встроенного инструментария для написания кода. Ну могли бы какой-то fluent-интерфейс сделать за столько-то лет. А то как в мезозое, пишем код через StringBuilder. Вот с этого прям негодую. Не смотрел в сторону готовых библиотек, но уверен, что open-source умельцы уже наделали с десяток таких.
Также, в какой-то момент поймал себя на мысли, что с помощью сорс генераторов можно делать динамические провайдеры типов как в F#, но поспешил с выводами. Не-а, так сделать не получится (только может совсем чуть чуть), на это Майкрософт фокус не брали, а жаль.
Итого, крайне полезный инструмент, когда нужно написать миллиард строчек boilerplate-кода, быстрый и надежный. Единственное, что нужно - это чуть пристальнее контролировать сложность и чистоту генераторов, чтобы облегчить себе будущую поддержку. Рекомендую!
C# Source Generators
👾 PICO
Программистов, хорошо пишущих код, мало, а программистов, хорошо пишущих код, который пишет код, и подавно.
Спустя несколько лет после релиза, наконец, добрался до этих знаменитых сорс генераторов, и теперь могу записать себя в ряды метапрограммистов.
Интересно, а постметапрограммисты будут?
Поделюсь своими впечатлениями от использования.
В первую очередь, что бросается в глаза - действительно хорошая гибкость инструмента. Он развязывает руки настолько, что кажется любой компонент разрабатываемого проекта можно так или иначе сделать модульным и расширять на основе внешних понятных конфигов или ещё чего покруче.
Поскольку эта штука compile-time, а все генерируемые файлы можно посмотреть прямиком в solution explorer - инструмент крайне прозрачен. Он делает все явно и без "магии", любой сгенерированный файлик можно увидеть и применить к нему IntelliSense вашей IDE.
Hot Reload. Ну это вообще бомба. Любой файл, связанный с сорс генератором, подвергнувшись изменению, оповещает сорс генератор и можно в реальном времени увидеть новый сгенерированный код без перекомпиляции. Супер удобно.
Из минусов отмечу отсутствие встроенного инструментария для написания кода. Ну могли бы какой-то fluent-интерфейс сделать за столько-то лет. А то как в мезозое, пишем код через StringBuilder. Вот с этого прям негодую. Не смотрел в сторону готовых библиотек, но уверен, что open-source умельцы уже наделали с десяток таких.
Также, в какой-то момент поймал себя на мысли, что с помощью сорс генераторов можно делать динамические провайдеры типов как в F#, но поспешил с выводами. Не-а, так сделать не получится (только может совсем чуть чуть), на это Майкрософт фокус не брали, а жаль.
Итого, крайне полезный инструмент, когда нужно написать миллиард строчек boilerplate-кода, быстрый и надежный. Единственное, что нужно - это чуть пристальнее контролировать сложность и чистоту генераторов, чтобы облегчить себе будущую поддержку. Рекомендую!
C# Source Generators
👾 PICO
👍5👾1
GigaCode - AI Assistant
JetBrains выкатили своего AI ассистента, который под капотом ломится вЧАТДЖИПИТИ. У Microsoft есть Copilot. Чтобы данные AI ассистенты успешно завелись - нужен или постоянно включенный польский VPN либо польский VPN + хитрая маршрутизация (нет, спасибо). А пощупать то хочется, посмотреть, каково это, иметь в паре постоянного недоджуна.
И вот недавно я получил доступ к AI-ассистенту от Сбера - GigaCode.
Этот парень ещё в преальфе, доступ по вайт листу, но зато бесплатный и НАШ, СИБИРСКИЙ, без впнов и танцев с бубном. И так, на что же он способен...
Первое, что бросается в глаза - список поддерживаемых IDE: продукты JB и VSCode в списке, похвально, ребята нацелены серьезно.
Гигакод пока что может только в дополнение кода, поболтать про ужасную архитектуру или "а вот бы все с нуля переписать" прямо в IDE не получится.
Но когда ты вводишь свою первую строчку кода... Тут то и начинается веселье. Автодополнение до конца строки, написание методов по комментариям, и даже... даже... ничего больше.
Вот такой вот скромняга гигакод, больше ничего не умеет. Ну, зато личный ассистент, статусно. Ладно, что на счет качества? Помогает при разработке?
Знаете, в целом да. Функциональность автодополнения до конца строки помогает в написании повторяющегося boiletplate-кода. Анализирует контекст текущего открытого файла (или всех открытых файлов, есть настройка) и дописывает твой код. Получается красиво и быстро. Кстати скорость генерации кода практически моментальная.
Бывает я трачу больше времени на анализ кода, который он предлагает мне написать, чем на код, который написал бы сам, но на первый взгляд кажется, что это просто дело привычки. Написание функций по комментариям вообще бомба (когда контекста хватило)
Резюмировать могу так, с помощью ассистента я стал писать код быстрее на 10-20%, это достаточно непривычно, требует времени на освоение,а также есть вероятность что вы сливаете код ребятам из сбера, но попробовать определенно точно стоит!
👾 PICO
JetBrains выкатили своего AI ассистента, который под капотом ломится в
И вот недавно я получил доступ к AI-ассистенту от Сбера - GigaCode.
Этот парень ещё в преальфе, доступ по вайт листу, но зато бесплатный и НАШ, СИБИРСКИЙ, без впнов и танцев с бубном. И так, на что же он способен...
Первое, что бросается в глаза - список поддерживаемых IDE: продукты JB и VSCode в списке, похвально, ребята нацелены серьезно.
Гигакод пока что может только в дополнение кода, поболтать про ужасную архитектуру или "а вот бы все с нуля переписать" прямо в IDE не получится.
Но когда ты вводишь свою первую строчку кода... Тут то и начинается веселье. Автодополнение до конца строки, написание методов по комментариям, и даже... даже... ничего больше.
Вот такой вот скромняга гигакод, больше ничего не умеет. Ну, зато личный ассистент, статусно. Ладно, что на счет качества? Помогает при разработке?
Знаете, в целом да. Функциональность автодополнения до конца строки помогает в написании повторяющегося boiletplate-кода. Анализирует контекст текущего открытого файла (или всех открытых файлов, есть настройка) и дописывает твой код. Получается красиво и быстро. Кстати скорость генерации кода практически моментальная.
Бывает я трачу больше времени на анализ кода, который он предлагает мне написать, чем на код, который написал бы сам, но на первый взгляд кажется, что это просто дело привычки. Написание функций по комментариям вообще бомба (когда контекста хватило)
Резюмировать могу так, с помощью ассистента я стал писать код быстрее на 10-20%, это достаточно непривычно, требует времени на освоение,
👾 PICO
🔥6👍2❤1🤡1
Последние несколько лет не вылезаю из бекенд разработки, поднадоело.
Решил освежить в памяти и заодно узнать, какого это, пилить приложухи под виндовый десктоп в 2к24.
Из технологий у нас все так же есть WinForms и WPF - (не) стареющая классика. К ним добавились UWP (который за 3 года успел устареть и откиснуть) и MAUI (позиционирующий себя как эволюция Xamarin.Forms)
Трогать новые технологии от Майкрософта себе дороже, поэтому решил взять старый добрый WPF и проверить, а как же дела сейчас у старичка. Спойлер: все у него круто!
Во-первых, наконец, прислушались к сообществу и вместо необходимости использовать тысячи тысяч сторонних MVVM фреймворков нас встречает дружелюбный CommunityToolkit.Mvvm - официальный фреймворк от Майков.
Его снабдили полноценной документацией, большим количеством примеров и, что самое приятное, в него также встроили современные фичи языка, а именно Source Generators. Теперь писать ViewModel для XAML разметки стало на порядки быстрее и проще.
Пару слов про IDE. Я пользуюсь JetBrains Rider, и по сравнению с тем, какая поддержка WPF была в нем 5 лет назад - ощущение от разработки сейчас - это небо и земля.
Джеты подтянули XAML дизайнер, оптимизировали навигацию между разметкой и code-behind, надо проверить, есть ли hot-reload, а то руки не дошли посмотреть.
Делаю вывод, что инструментарий разработки под десктоп развивается, причем достаточно стремительно. Писать приложения стало проще, хотя и отсутствуют некоторые давно желанные мною фичи, но легко подключаются сторонними либами.
Может, стоит попробовать MAUI?..
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2❤1