Оператор конкатенации ANSI SQL (
Он предлагает «более читаемую и соответствующую стандарту альтернативу существующим способам вроде
А ты как считаешь?🧀
👉 @KodBlog
||) теперь поддерживается в базе данных Azure SQLОн предлагает «более читаемую и соответствующую стандарту альтернативу существующим способам вроде
+ и CONCAT()».А ты как считаешь?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤3🤨2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2
Когда-нибудь нужно было открыть эндпоинт для внешней системы, но не хотелось поднимать полноценную систему аутентификации?
Аутентификация по API-ключу — простой и эффективный вариант.
В
Он встраивается в pipeline запроса и может быть внедрён через Dependency Injection
Хорошо подходит для:
- внутренних тулов
- вебхуков
- плановых задач
- интеграций с внешними сервисами
Ты сам определяешь:
- как передаётся ключ
- как он валидируется
- какие эндпоинты его требуют
Гайд с рабочим примером, который можно просто скопировать и адаптировать: здесь
👉 @KodBlog
Аутентификация по API-ключу — простой и эффективный вариант.
В
ASP.NET Core для этого можно использовать IAuthorizationFilter.Он встраивается в pipeline запроса и может быть внедрён через Dependency Injection
Хорошо подходит для:
- внутренних тулов
- вебхуков
- плановых задач
- интеграций с внешними сервисами
Ты сам определяешь:
- как передаётся ключ
- как он валидируется
- какие эндпоинты его требуют
Гайд с рабочим примером, который можно просто скопировать и адаптировать: здесь
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍1
Большинство .NET разработчиков никогда с этим не сталкиваются.
Но это делает отладку в 10 раз проще.
Стандартный вид при отладке:
Никакого контекста. Много путаницы.
Но всего одной строкой кода?
Теперь окно наблюдения показывает:
В чём фишка?
Используйте
Добавляете этот атрибут в начало класса, чтобы контролировать, как будет отображаться информация о классе при отладке.
В следующий раз, когда будете смотреть на
👉 @KodBlog
Но это делает отладку в 10 раз проще.
Стандартный вид при отладке:
{Namespace.ObjectName}Никакого контекста. Много путаницы.
Но всего одной строкой кода?
Теперь окно наблюдения показывает:
Order ORD-2025-001: Alice Smith - 249.99
Order ORD-2025-002: Bob Evans - 89.50
Order ORD-2025-003: Maria Lee - 1200.00
В чём фишка?
Используйте
DebuggerDisplay.Добавляете этот атрибут в начало класса, чтобы контролировать, как будет отображаться информация о классе при отладке.
В следующий раз, когда будете смотреть на
{Namespace.ObjectName}, помните: так не обязательно должно быть.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥30❤5👍4🤔2🌚1
Новая библиотека для планирования задач, которая превосходит Quartz и Hangfire
3 недели назад вышла новая библиотека под названием TickerQ.
Что такое TickerQ?
TickerQ — высокопроизводительный планировщик, разработанный специально для .NET. Он фокусируется на простоте, масштабируемости и минимальном потреблении ресурсов.
Почему она лучше?
Традиционные библиотеки, такие как Quartz и Hangfire, имеют известные недостатки:
↳ Quartz:
• Сложный API, тяжело для новичков
• Отсутствие типобезопасности при передаче параметров в Job
• Потери в производительности из-за использования рефлексии
↳ Hangfire:
• Ограниченная поддержка DI и async-операций
• Простейшая логика повторных попыток (retry)
• Потери в производительности из-за использования рефлексии
Как TickerQ решает эти проблемы:
1️⃣ Легковесный и интуитивно понятный API
2️⃣ Без рефлексии, использует source generators
3️⃣ Нативная поддержка распределённого планирования без дополнительной сложности
4️⃣ Встроенная логика повторных попыток и упрощённая обработка ошибок
Quartz и Hangfire долгое время были стандартом, но теперь есть лучший вариант.
Что думаете про эту новую библиотеку для планирования? Попробуете TickerQ или останетесь на Quartz или Hangfire?
👉 @KodBlog
3 недели назад вышла новая библиотека под названием TickerQ.
Что такое TickerQ?
TickerQ — высокопроизводительный планировщик, разработанный специально для .NET. Он фокусируется на простоте, масштабируемости и минимальном потреблении ресурсов.
Почему она лучше?
Традиционные библиотеки, такие как Quartz и Hangfire, имеют известные недостатки:
↳ Quartz:
• Сложный API, тяжело для новичков
• Отсутствие типобезопасности при передаче параметров в Job
• Потери в производительности из-за использования рефлексии
↳ Hangfire:
• Ограниченная поддержка DI и async-операций
• Простейшая логика повторных попыток (retry)
• Потери в производительности из-за использования рефлексии
Как TickerQ решает эти проблемы:
Quartz и Hangfire долгое время были стандартом, но теперь есть лучший вариант.
Что думаете про эту новую библиотеку для планирования? Попробуете TickerQ или останетесь на Quartz или Hangfire?
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤6
До сих пор часто вижу такой паттерн:
Это неэффективно.
Почему?
🔸
🔸 Если тебе просто нужно проверить, есть ли элементы — используй
В SQL это переводится в
Основные выводы:
🔸 Используй
🔸 Используй
Такие небольшие оптимизации имеют значение особенно когда приложение растёт и работает с большими объёмами данных.
👉 @KodBlog
if (items.Count() > 0)
{
// ...
}
Это неэффективно.
Почему?
Count() проходит по всей коллекции или делает COUNT(*) в базе данных.Any().Any() останавливается на первом найденном элементе.В SQL это переводится в
EXISTS, что значительно легче, чем COUNT(*).Основные выводы:
Any() для проверки на наличие элементов.Count() только если реально нужен точный размер коллекции.Такие небольшие оптимизации имеют значение особенно когда приложение растёт и работает с большими объёмами данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍27❤3
Горячее мнение:
🔸 Напиши конструктор
🔸 Вызови конструктор
🔸 Готово
Это может быть и статический метод, или что тебе больше нравится.
В своих проектах я редко использую больше одного уровня маппинга.
И ещё реже какие-либо библиотеки для маппинга.
👉 @KodBlog
ВАМ НЕ НУЖНЫ библиотеки для маппинга.
Это может быть и статический метод, или что тебе больше нравится.
В своих проектах я редко использую больше одного уровня маппинга.
И ещё реже какие-либо библиотеки для маппинга.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🤔3❤2
.NET Aspire теперь поддерживает создание баз данных MySQL
И настройка занимает всего одну строку
С момента релиза в статусе General Availability, .NET Aspire изменил подход к созданию облачных приложений на .NET.
Менее чем в 30 строках кода вы можете настроить:
- API
- Базы данных
- Кэш
Плюс, сразу из коробки получаете дашборд, сервис-дискавери и телеметрию.
Что лично для меня круто — возможность добавить и создать целую базу данных одним методом.
Метод
Ранее эта функция поддерживала:
- SQL Server
- PostgreSQL
Но теперь, начиная с версии 9.3, добавлена поддержка MySQL.
Вам не нужно ничего дополнительно делать — ваш существующий вызов
👉 @KodBlog
И настройка занимает всего одну строку
С момента релиза в статусе General Availability, .NET Aspire изменил подход к созданию облачных приложений на .NET.
Менее чем в 30 строках кода вы можете настроить:
- API
- Базы данных
- Кэш
Плюс, сразу из коробки получаете дашборд, сервис-дискавери и телеметрию.
Что лично для меня круто — возможность добавить и создать целую базу данных одним методом.
Метод
AddDatabase выполняет SQL-команду CREATE DATABASE с заданным именем на работающем контейнере или сервере.Ранее эта функция поддерживала:
- SQL Server
- PostgreSQL
Но теперь, начиная с версии 9.3, добавлена поддержка MySQL.
Вам не нужно ничего дополнительно делать — ваш существующий вызов
AddDatabase теперь автоматически создаёт базу данных.Please open Telegram to view this post
VIEW IN TELEGRAM
❤10😁2👍1
Пример Task.WhenEach в .NET 9
В .NET 9 появилась новая API —
В простом примере выше выполняется несколько запросов через
Ты уже пробовал эту новую фичу?🔥
👉 @KodBlog
В .NET 9 появилась новая API —
Task.WhenEach, которая позволяет обрабатывать асинхронные задачи по мере их завершения.В простом примере выше выполняется несколько запросов через
HttpClient, и их результаты обрабатываются по мере готовности, а не после завершения всех задач.Ты уже пробовал эту новую фичу?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥32👍8❤5
Перестань совершать ЭТУ критическую ошибку при запуске нового software проекта:
Пытаться выстроить идеальную архитектуру с первого дня.
Мой главный инсайт про архитектуру ПО?
Речь не о том, чтобы с самого начала зарываться в избыточную сложность.
Но и не о том, чтобы надолго оставлять архитектуру чересчур примитивной.
В этом и суть эволюционной архитектуры:
Эта концепция особенно хорошо укладывается, когда видишь её в действии. Вот 4 отличных репозитория на GitHub с реальными приложениями:
🔸 Evolutionary Architecture
→ Один проект на GitHub, в котором показано, как начать с простой .NET-архитектуры, а затем эволюционно перейти к модульному монолиту и микросервисам по мере роста требований и кодовой базы.
→ Ссылка: https://github.com/evolutionary-architecture/evolutionary-architecture-by-example
🔸 Booking to Cloud Architecture
→ Приложение для бронирования, реализованное тремя способами: монолит, модульный монолит и микросервисы.
→ Монолит: https://github.com/meysamhadeli/booking-monolith
→ Модульный монолит: https://github.com/meysamhadeli/booking-modular-monolith
→ Микросервисы: https://github.com/meysamhadeli/booking-microservices
Когда ты перестаёшь воспринимать архитектуру как то, что нужно «угадать» с первого дня, ты даёшь себе право на ошибку.
Право учиться.
Право адаптироваться.
И расти вместе с системой.
👉 @KodBlog
Пытаться выстроить идеальную архитектуру с первого дня.
Мой главный инсайт про архитектуру ПО?
«Хорошая архитектура не статична. Она развивается.»
Речь не о том, чтобы с самого начала зарываться в избыточную сложность.
Но и не о том, чтобы надолго оставлять архитектуру чересчур примитивной.
В этом и суть эволюционной архитектуры:
Вместо того чтобы сразу делать ставку на «правильную» абстракцию, собери минимально работающее решение и перестраивай его осознанно по мере изменения требований.
Эта концепция особенно хорошо укладывается, когда видишь её в действии. Вот 4 отличных репозитория на GitHub с реальными приложениями:
→ Один проект на GitHub, в котором показано, как начать с простой .NET-архитектуры, а затем эволюционно перейти к модульному монолиту и микросервисам по мере роста требований и кодовой базы.
→ Ссылка: https://github.com/evolutionary-architecture/evolutionary-architecture-by-example
→ Приложение для бронирования, реализованное тремя способами: монолит, модульный монолит и микросервисы.
→ Монолит: https://github.com/meysamhadeli/booking-monolith
→ Модульный монолит: https://github.com/meysamhadeli/booking-modular-monolith
→ Микросервисы: https://github.com/meysamhadeli/booking-microservices
Когда ты перестаёшь воспринимать архитектуру как то, что нужно «угадать» с первого дня, ты даёшь себе право на ошибку.
Право учиться.
Право адаптироваться.
И расти вместе с системой.
Потому что хорошая архитектура рождается не из предсказаний будущего —
она рождается из эволюции в будущем.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤3👍1
10 скрытых фич EF Core, которые используют сеньоры
1️⃣ Shadow Properties
EF Core позволяет добавлять свойства, которых нет в классе, но которые присутствуют в базе данных.
Идеально подходят, например, для хранения данных аудита, не засоряя сущности лишними полями.
2️⃣ Query Tags
Можно легко добавлять комментарии к SQL-запросам, которые генерирует EF Core.
Удобно при профилировании - в логах SQL сразу видно, откуда пришёл тот или иной медленный запрос.
3️⃣ Compiled Queries
Часто используемые запросы можно скомпилировать заранее, чтобы не тратить ресурсы на парсинг каждый раз.
Повышает производительность при большом числе однотипных запросов.
4️⃣ DbContext Pooling
Вместо того чтобы каждый раз создавать новый
Существенно снижает потребление памяти и повышает производительность.
5️⃣ Value Converters
Позволяют автоматически преобразовывать значения между .NET и базой данных.
Полезно для хранения кастомных типов, enum'ов и Value Object'ов.
6️⃣ Temporal Tables
Позволяют отслеживать историю изменений данных прямо в базе.
Удобно для аудита, отката изменений и анализа исторических данных.
7️⃣ Database Seeding
EF Core 9 добавил новые методы
8️⃣ Split Queries for Includes
Позволяет разбивать сложные запросы с Include на несколько простых.
Избегает проблем с громоздкими JOIN’ами и повышает производительность.
9️⃣ Raw SQL Queries
Можно выполнять чистый SQL прямо из EF Core.
Полезно, когда нужно выжать максимум производительности или использовать специфичный функционал конкретной СУБД.
1️⃣ 0️⃣ Миграции для нескольких баз данных
Можно легко управлять миграциями и схемами сразу для разных провайдеров.
Подходит для приложений, которые должны работать с несколькими СУБД (например, SQL Server, PostgreSQL, MySQL).
👉 @KodBlog
EF Core позволяет добавлять свойства, которых нет в классе, но которые присутствуют в базе данных.
Идеально подходят, например, для хранения данных аудита, не засоряя сущности лишними полями.
Можно легко добавлять комментарии к SQL-запросам, которые генерирует EF Core.
Удобно при профилировании - в логах SQL сразу видно, откуда пришёл тот или иной медленный запрос.
Часто используемые запросы можно скомпилировать заранее, чтобы не тратить ресурсы на парсинг каждый раз.
Повышает производительность при большом числе однотипных запросов.
Вместо того чтобы каждый раз создавать новый
DbContext, можно переиспользовать уже созданные.Существенно снижает потребление памяти и повышает производительность.
Позволяют автоматически преобразовывать значения между .NET и базой данных.
Полезно для хранения кастомных типов, enum'ов и Value Object'ов.
Позволяют отслеживать историю изменений данных прямо в базе.
Удобно для аудита, отката изменений и анализа исторических данных.
EF Core 9 добавил новые методы
UseSeeding, UseAsyncSeeding для удобного наполнения базы начальными данными.Позволяет разбивать сложные запросы с Include на несколько простых.
Избегает проблем с громоздкими JOIN’ами и повышает производительность.
Можно выполнять чистый SQL прямо из EF Core.
Полезно, когда нужно выжать максимум производительности или использовать специфичный функционал конкретной СУБД.
Можно легко управлять миграциями и схемами сразу для разных провайдеров.
Подходит для приложений, которые должны работать с несколькими СУБД (например, SQL Server, PostgreSQL, MySQL).
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤1
Proxy Design Pattern
Что такое паттерн Proxy?
Proxy предоставляет объект-заместитель, который контролирует доступ к другому объекту.
Это как пользоваться банковской картой вместо наличных — те же возможности, но с большим контролем.
Это один из паттернов структурной группы, которая фокусируется на том, как классы и объекты объединяются в более крупные и гибкие архитектуры.
🔸 Когда стоит использовать
Используйте Proxy, когда нужно:
- реализовать ленивую инициализацию тяжёлых объектов;
- контролировать доступ к объекту (например, авторизация);
- логировать входящие запросы;
- кэшировать результаты;
- управлять удалёнными ресурсами (например, через сеть).
Proxy идеально подходит, когда нужно добавить поведение к объекту, не изменяя его исходный код — например, добавить проверки безопасности или метрики производительности.
🔸 Как реализовать
1. Создайте класс Proxy, реализующий тот же интерфейс, что и основной сервис.
2. Proxy хранит ссылку на реальный объект и перехватывает все обращения к нему.
3. В зависимости от логики, прокси может:
🔸 Распространённые типы Proxy:
- Virtual Proxy — отложенное создание объекта;
- Protection Proxy — контроль прав доступа;
- Remote Proxy — работа с удалёнными объектами;
- Caching Proxy — кэширование результатов вызова.
> Proxy может выполнять свои действия до или после делегирования запроса реальному объекту.
🔸 Почему это работает
- клиент работает с Proxy, не зная о реальной реализации сервиса.
- Proxy продолжает работать даже если объект-сервис ещё не создан или временно недоступен.
- можно добавлять новые прокси, не меняя код клиента или сервиса.
🔸 Недостатки
- Возможны задержки в ответах из-за дополнительной логики.
- Увеличивается сложность кода — появляются дополнительные классы и уровни абстракции.
- Непродуманная реализация Proxy может стать узким местом и источником багов (например, в многопоточности).
👉 @KodBlog
Что такое паттерн Proxy?
Proxy предоставляет объект-заместитель, который контролирует доступ к другому объекту.
Это как пользоваться банковской картой вместо наличных — те же возможности, но с большим контролем.
Это один из паттернов структурной группы, которая фокусируется на том, как классы и объекты объединяются в более крупные и гибкие архитектуры.
Используйте Proxy, когда нужно:
- реализовать ленивую инициализацию тяжёлых объектов;
- контролировать доступ к объекту (например, авторизация);
- логировать входящие запросы;
- кэшировать результаты;
- управлять удалёнными ресурсами (например, через сеть).
Proxy идеально подходит, когда нужно добавить поведение к объекту, не изменяя его исходный код — например, добавить проверки безопасности или метрики производительности.
1. Создайте класс Proxy, реализующий тот же интерфейс, что и основной сервис.
2. Proxy хранит ссылку на реальный объект и перехватывает все обращения к нему.
3. В зависимости от логики, прокси может:
- разрешить/запретить доступ;
- отложить создание объекта;
- закэшировать результат;
- добавить побочные эффекты (лог, метрики и т.д.).
- Virtual Proxy — отложенное создание объекта;
- Protection Proxy — контроль прав доступа;
- Remote Proxy — работа с удалёнными объектами;
- Caching Proxy — кэширование результатов вызова.
> Proxy может выполнять свои действия до или после делегирования запроса реальному объекту.
- клиент работает с Proxy, не зная о реальной реализации сервиса.
- Proxy продолжает работать даже если объект-сервис ещё не создан или временно недоступен.
- можно добавлять новые прокси, не меняя код клиента или сервиса.
- Возможны задержки в ответах из-за дополнительной логики.
- Увеличивается сложность кода — появляются дополнительные классы и уровни абстракции.
- Непродуманная реализация Proxy может стать узким местом и источником багов (например, в многопоточности).
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🔥3👍1
Секретная фишка в C#, о которой никто не знает
Она позволяет создавать высокопроизводительные .NET-приложения.
Разработка надёжных, масштабируемых и быстрых .NET-приложений во многом зависит от того, как вы организуете конкуренцию и обработку данных.
Во время разработки .NET-приложений часто возникает необходимость передавать данные из одной части кода в другую.
Ранее для этого использовали такие конструкции, как
Эти очереди оборачивали в классы и применяли для управления потоками данных.
Однако у таких решений есть существенный минус — сильная связанность кода.💊
Channels в C# это малоизвестная, но мощная фишка, которая предлагает современный способ построения безопасных, асинхронных и высоконагруженных .NET-приложений.
Они реализуют паттерн "производитель-потребитель": один класс создаёт данные, другой их потребляет - при этом оба ничего не знают друг о друге.
Ключевым архитектурным моментом при работе с каналами является выбор между ограниченными и неограниченными каналами.
Вот гайд, где узнаете:
➡️ Что такое C# Channels?
➡️ Ограниченные vs. неограниченные каналы
➡️ Фоновая обработка через Channels
➡️ Применение каналов в боевом
➡️ Лучшие практики и советы по работе с Channels
👉 @KodBlog
Она позволяет создавать высокопроизводительные .NET-приложения.
Разработка надёжных, масштабируемых и быстрых .NET-приложений во многом зависит от того, как вы организуете конкуренцию и обработку данных.
Во время разработки .NET-приложений часто возникает необходимость передавать данные из одной части кода в другую.
Ранее для этого использовали такие конструкции, как
Queue<T>, ConcurrentQueue<T> или BlockingCollection<T>.Эти очереди оборачивали в классы и применяли для управления потоками данных.
Однако у таких решений есть существенный минус — сильная связанность кода.
Channels в C# это малоизвестная, но мощная фишка, которая предлагает современный способ построения безопасных, асинхронных и высоконагруженных .NET-приложений.
Они реализуют паттерн "производитель-потребитель": один класс создаёт данные, другой их потребляет - при этом оба ничего не знают друг о друге.
Ключевым архитектурным моментом при работе с каналами является выбор между ограниченными и неограниченными каналами.
Вот гайд, где узнаете:
ASP.NET Core-приложенииPlease open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥7❤5😁1
В модульной монолитной архитектуре каждый модуль должен полноценно владеть своими данными. Для каждого модуля в PostgreSQL следует использовать отдельную схему и роль, а в EF Core — отдельный
👉 @KodBlog
DbContext и строку подключения. Чтение данных между модулями должно выполняться через read model или представление , а не с помощью неконтролируемых join-овPlease open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥5🥴1😐1
Числовой
Он позволяет сравнивать числа по их числовому значению, а не в лексикографическом порядке.
👉 @KodBlog
StringComparer появится в dotnet 10Он позволяет сравнивать числа по их числовому значению, а не в лексикографическом порядке.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18🔥11
LINQ-метод
LINQ уже включает API для изменения порядка элементов, такие как
Однако на данный момент нет стандартного API для перемешивания
(Существует
На StackOverflow часто можно встретить примеры перемешивания с использованием кода вроде
Однако такой подход неэффективен, и есть более оптимальные способы перемешивания.
Поэтому предлагается реализовать
🔸 API Proposal — Предложение API
🔸 API Usage — Пример использования
👉 @KodBlog
Shuffle() появится в .NET 10Shuffle — это универсальная операция, используемая, например, в играх и при предварительной обработке данных для машинного обучения.LINQ уже включает API для изменения порядка элементов, такие как
OrderBy() и Reverse().Однако на данный момент нет стандартного API для перемешивания
IEnumerable<T>.(Существует
System.Random.Shuffle() для Span<T>, но если нужно перемешать произвольную последовательность IEnumerable<T>, скорее всего, придётся писать собственную реализацию.)На StackOverflow часто можно встретить примеры перемешивания с использованием кода вроде
.OrderBy(_ => Guid.NewGuid()).Однако такой подход неэффективен, и есть более оптимальные способы перемешивания.
Поэтому предлагается реализовать
System.Linq.Shuffle().namespace System.Linq
{
public static class Enumerable
{
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source) { }
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random randomSource) { }
}
}
var songs = ["Lorem", "ipsum", "dolor", "sit", "amet"];
foreach (var song in songs.Shuffle())
{
Play(song);
}
// выбрать 3 уникальные песни
var threeSongs = songs.Shuffle().Take(3).ToArray();
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥27😁19❤3