Вышел предварительный релиз .NET 11, версия 4
- асинхронный путь через JIT во время выполнения
- асинхронные пути без выделений памяти
- API сжатия на основе
- OpenTelemetry для CLI-инструментов
- автодополнение для Fish shell
- векторный поиск в Entity Framework Core
-
Читать блог
👉 @KodBlog
- асинхронный путь через JIT во время выполнения
- асинхронные пути без выделений памяти
- API сжатия на основе
Span- OpenTelemetry для CLI-инструментов
- автодополнение для Fish shell
- векторный поиск в Entity Framework Core
-
dotnet watch для MAUI на мобильных устройствахЧитать блог
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤2🍾1
В каком-то всеми забытом углу Qt внезапно зарелизили поддержку C#: https://www.qt.io/blog/qt-bridges-public-beta-for-csharp
👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣16🤯4❤3🍾2👍1
Размер веб-страницы должен укладываться в 14кБ
Меньше размер – быстрее загрузка, это понятно. Удивительно, что страница в 14кБ может загружаться гораздо быстрее, чем в 15кБ, а разница между 15 и 16кБ незначительна. Дело в алгоритме медленного старта TCP.
TCP
Протокол управления передачей (TCP) — это способ использования интернет-протокола (IP) для надёжной отправки пакетов данных. Сервер отправляет несколько пакетов, затем ждёт ответа от браузера о получении (ACK), затем отправляет ещё — или, если не получил ACK, может отправить пакеты снова.
Алгоритм медленного старта TCP используется серверами для определения количества пакетов, которые они могут отправить за один раз. Сервер не знает, какой объём данных может обработать соединение, поэтому начинает с отправки небольшого и безопасного количества данных — обычно 10 TCP-пакетов. Если на это получен ACK, сервер отправляет больше данных, удваивая количество пакетов. Так до тех пор, пока пакеты не будут потеряны и сервер не получит ACK. (Тогда он продолжает отправлять пакеты, но с меньшей скоростью). В реальности реализация алгоритма может отличаться, но суть та же.
Откуда 14кБ?
Максимальный размер TCP-пакета составляет 1500 байт: 40 байт заголовка (16 – IP, 24 – TCP). Т.е., 10 пакетов по 1460 = 14600 байт или примерно 14кБ!
Таким образом, если страницы (хотя бы важные) вашего сайта умещаются в 14кБ, вы можете сэкономить посетителям много времени. Люди очень нетерпеливы, и даже один обмен данными может быть удивительно долгим, особенно в нестабильных сетях.
Что делать?
Очевидно – делать сайт как можно меньше. Хорошая цель – уместить каждую страницу в 14кБ. Эти 14кБ включают сжатие — так что на самом деле это может быть около 50кБ несжатых данных, что довольно много.
Так что, если избавиться от лишнего CSS и JS, автовоспроизводимых видео, использовать минимизацию кода и т.п., вы, вероятно, легко достигнете цели. Но, даже если этого не получится, из правила 14кБ всё ещё можно извлечь пользу. Первые 14кБ данных, отправляемых посетителям, могут быть использованы для отображения чего-то полезного — например, важных первых нескольких абзацев текста, объясняющих, как использовать ваше приложение.
Примечание: 14кБ включают в себя HTTP-заголовки — которые не сжимаются (даже в HTTP/2 при первом ответе), а также изображения, поэтому выдавайте только то, что находится в видимой области экрана, делайте их очень маленькими, или используйте заполнители, чтобы посетители знали, что на этом месте будет что-то полезное.
Некоторые оговорки:
- Правило 14кБ больше эмпирическое правило, чем фундаментальный закон вычислительной техники. Некоторые серверы увеличили начальное окно медленного старта TCP до 30 пакетов вместо 10.
- Иногда сервер знает, что может начать с большего количества пакетов, потому что он использовал TLS-рукопожатие для установления большего лимита.
- Серверы могут кэшировать количество пакетов, которые может обработать маршрут, и отправлять больше при следующем подключении.
👉 @KodBlog
Меньше размер – быстрее загрузка, это понятно. Удивительно, что страница в 14кБ может загружаться гораздо быстрее, чем в 15кБ, а разница между 15 и 16кБ незначительна. Дело в алгоритме медленного старта TCP.
TCP
Протокол управления передачей (TCP) — это способ использования интернет-протокола (IP) для надёжной отправки пакетов данных. Сервер отправляет несколько пакетов, затем ждёт ответа от браузера о получении (ACK), затем отправляет ещё — или, если не получил ACK, может отправить пакеты снова.
Алгоритм медленного старта TCP используется серверами для определения количества пакетов, которые они могут отправить за один раз. Сервер не знает, какой объём данных может обработать соединение, поэтому начинает с отправки небольшого и безопасного количества данных — обычно 10 TCP-пакетов. Если на это получен ACK, сервер отправляет больше данных, удваивая количество пакетов. Так до тех пор, пока пакеты не будут потеряны и сервер не получит ACK. (Тогда он продолжает отправлять пакеты, но с меньшей скоростью). В реальности реализация алгоритма может отличаться, но суть та же.
Откуда 14кБ?
Максимальный размер TCP-пакета составляет 1500 байт: 40 байт заголовка (16 – IP, 24 – TCP). Т.е., 10 пакетов по 1460 = 14600 байт или примерно 14кБ!
Таким образом, если страницы (хотя бы важные) вашего сайта умещаются в 14кБ, вы можете сэкономить посетителям много времени. Люди очень нетерпеливы, и даже один обмен данными может быть удивительно долгим, особенно в нестабильных сетях.
Что делать?
Очевидно – делать сайт как можно меньше. Хорошая цель – уместить каждую страницу в 14кБ. Эти 14кБ включают сжатие — так что на самом деле это может быть около 50кБ несжатых данных, что довольно много.
Так что, если избавиться от лишнего CSS и JS, автовоспроизводимых видео, использовать минимизацию кода и т.п., вы, вероятно, легко достигнете цели. Но, даже если этого не получится, из правила 14кБ всё ещё можно извлечь пользу. Первые 14кБ данных, отправляемых посетителям, могут быть использованы для отображения чего-то полезного — например, важных первых нескольких абзацев текста, объясняющих, как использовать ваше приложение.
Примечание: 14кБ включают в себя HTTP-заголовки — которые не сжимаются (даже в HTTP/2 при первом ответе), а также изображения, поэтому выдавайте только то, что находится в видимой области экрана, делайте их очень маленькими, или используйте заполнители, чтобы посетители знали, что на этом месте будет что-то полезное.
Некоторые оговорки:
- Правило 14кБ больше эмпирическое правило, чем фундаментальный закон вычислительной техники. Некоторые серверы увеличили начальное окно медленного старта TCP до 30 пакетов вместо 10.
- Иногда сервер знает, что может начать с большего количества пакетов, потому что он использовал TLS-рукопожатие для установления большего лимита.
- Серверы могут кэшировать количество пакетов, которые может обработать маршрут, и отправлять больше при следующем подключении.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4😁1🍾1
ВЫШЕЛ CodeAlta — один из первых эффективных AI-кодинг-агентов с TUI, полностью написанный на C#/.NET
CodeAlta предлагает вам красивый цветной интерфейс-таймлайн, несколько потоков в одном workspace, полноценный опыт редактора промптов, быстрое просмотр/редактирование файлов с подсветкой синтаксиса, встроенную настройку провайдеров моделей, среду, готовую для multi-agent, и многое другое
Website: https://codealta.github.io/
GitHub: https://github.com/CodeAlta/CodeAlta
Установка:
Для установки достаточно установленного .NET 10 и команды:
👉 @KodBlog
CodeAlta предлагает вам красивый цветной интерфейс-таймлайн, несколько потоков в одном workspace, полноценный опыт редактора промптов, быстрое просмотр/редактирование файлов с подсветкой синтаксиса, встроенную настройку провайдеров моделей, среду, готовую для multi-agent, и многое другое
Website: https://codealta.github.io/
GitHub: https://github.com/CodeAlta/CodeAlta
Установка:
Для установки достаточно установленного .NET 10 и команды:
dotnet tool install -g CodeAlta
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🍾3
Чувак использовал ExecuteDelete на таблице с soft delete. 2000 промо-товаров были навсегда удалены.
Джоба очистки работала месяцами без проблем. Потом он добавил soft delete — SaveChangesInterceptor, который вместо настоящего DELETE просто выставляет IsDeleted.
ExecuteDelete полностью обходит весь пайплайн.
ExecuteDelete генерирует «сырой» SQL DELETE. Он не вызывает SaveChanges. Interceptor не срабатывает. Change Tracker не видит сущность. Строки удаляются, флаг IsDeleted не устанавливается, и audit trail не записывается.
Фикс — одна строка: использовать ExecuteUpdate, чтобы переключать IsDeleted вместо этого.
Правило: если сущность участвует в soft delete или любом паттерне через SaveChangesInterceptor, никогда не используйте ExecuteDelete для неё. Переходите на ExecuteUpdate с SetProperty(IsDeleted, true), либо загружайте сущности и используйте RemoveRange + SaveChanges, чтобы interceptor отработал.
👉 @KodBlog
Джоба очистки работала месяцами без проблем. Потом он добавил soft delete — SaveChangesInterceptor, который вместо настоящего DELETE просто выставляет IsDeleted.
ExecuteDelete полностью обходит весь пайплайн.
ExecuteDelete генерирует «сырой» SQL DELETE. Он не вызывает SaveChanges. Interceptor не срабатывает. Change Tracker не видит сущность. Строки удаляются, флаг IsDeleted не устанавливается, и audit trail не записывается.
Фикс — одна строка: использовать ExecuteUpdate, чтобы переключать IsDeleted вместо этого.
Правило: если сущность участвует в soft delete или любом паттерне через SaveChangesInterceptor, никогда не используйте ExecuteDelete для неё. Переходите на ExecuteUpdate с SetProperty(IsDeleted, true), либо загружайте сущности и используйте RemoveRange + SaveChanges, чтобы interceptor отработал.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2😁1🍾1
6 трендов в .NET, которые убивают ваши проекты
Каждый .NET-туториал преподносит их как «лучшие практики».
После 12+ лет разработки реальных систем Антон отказался от всех шести.
Вот что он использует вместо них.
1. Clean Architecture везде
Проблема:
- 4 проекта и 5 слоёв, через которые приходится проходить, чтобы добавить один эндпоинт.
Что использовать вместо этого:
- Vertical Slice Architecture.
- Весь код одной фичи находится в одной папке.
Принципы Clean Architecture стоит добавлять только тогда, когда сложность проекта действительно этого требует: например, при богатой доменной модели или необходимости чёткого разделения инфраструктурных зависимостей.
Небольшие сфокусированные классы экономят токены при работе с AI. Кроме того, AI-агентам гораздо проще находить код нужной фичи, когда он расположен в одном месте.
2. Микросервисы с первого дня
Проблема:
- Распределённые транзакции.
- Сложная отладка.
- Хаос с развёртыванием.
Что использовать вместо этого:
- Начинать с модульного монолита (Modular Monolith).
- Выделять микросервисы только после появления реальных проблем масштабирования.
Большинство приложений не доходят до миллиона пользователей. Гораздо чаще они прекращают развитие ещё на первых сотнях пользователей.
Лучшие микросервисы обычно вырастают из модульного монолита.
3. Библиотеки для маппинга
Проблема:
- AutoMapper, Mapster и Mapperly скрывают логику маппинга.
- Теряется прямая навигация по коду.
- Приходится тратить время на разбор особенностей библиотек.
Что использовать вместо этого:
- Ручной маппинг.
Преимущества:
- Полный контроль над кодом.
- Прямая навигация.
- Простая отладка.
С появлением AI-агентов код для маппинга создаётся за считаные секунды, поэтому библиотеки маппинга уже не дают заметной экономии времени.
4. MediatR везде
Проблема:
- Нет прямой навигации от эндпоинта к обработчику.
- Появляются дополнительные команды, интерфейсы и шаблонный код только ради соблюдения паттерна.
Что использовать вместо этого:
- Обычные классы обработчиков без интерфейсов.
- Внедрение через DI и прямой вызов из эндпоинтов.
Результат:
- То же разделение ответственности.
- Меньше кода.
- Полноценная навигация в IDE в один клик.
5. EF Core через репозитории
Проблема:
- EF Core уже реализует паттерны Repository и Unit of Work.
- Дополнительные репозитории создают лишний уровень абстракции.
Что использовать вместо этого:
- DbContext напрямую в обработчиках приложения.
Не стоит создавать обёртки поверх уже существующих обёрток.
Иначе скрываются основные возможности EF Core:
- LINQ.
- Change Tracking.
- Проекции.
6. Unit-тесты по умолчанию
Проблема:
- Unit-тесты с большим количеством моков создают ложное чувство уверенности.
- Тесты проходят успешно, а приложение всё равно падает в продакшене.
Что использовать вместо этого:
- Интеграционные тесты как основной вид тестирования.
Используйте WebApplicationFactory и TestContainers для проверки полного сценария работы:
Такой подход также проверяет:
- конфигурацию приложения;
- контейнер зависимостей (DI);
- middleware;
- миграции базы данных.
Главное правило: Не добавляйте сложность, если проект в ней не нуждается.
Большинство «лучших практик» — это решение конкретных проблем в конкретных проектах, а не универсальные правила для любого приложения.
👉 @KodBlog
Каждый .NET-туториал преподносит их как «лучшие практики».
После 12+ лет разработки реальных систем Антон отказался от всех шести.
Вот что он использует вместо них.
1. Clean Architecture везде
Проблема:
- 4 проекта и 5 слоёв, через которые приходится проходить, чтобы добавить один эндпоинт.
Что использовать вместо этого:
- Vertical Slice Architecture.
- Весь код одной фичи находится в одной папке.
Принципы Clean Architecture стоит добавлять только тогда, когда сложность проекта действительно этого требует: например, при богатой доменной модели или необходимости чёткого разделения инфраструктурных зависимостей.
Небольшие сфокусированные классы экономят токены при работе с AI. Кроме того, AI-агентам гораздо проще находить код нужной фичи, когда он расположен в одном месте.
2. Микросервисы с первого дня
Проблема:
- Распределённые транзакции.
- Сложная отладка.
- Хаос с развёртыванием.
Что использовать вместо этого:
- Начинать с модульного монолита (Modular Monolith).
- Выделять микросервисы только после появления реальных проблем масштабирования.
Большинство приложений не доходят до миллиона пользователей. Гораздо чаще они прекращают развитие ещё на первых сотнях пользователей.
Лучшие микросервисы обычно вырастают из модульного монолита.
3. Библиотеки для маппинга
Проблема:
- AutoMapper, Mapster и Mapperly скрывают логику маппинга.
- Теряется прямая навигация по коду.
- Приходится тратить время на разбор особенностей библиотек.
Что использовать вместо этого:
- Ручной маппинг.
Преимущества:
- Полный контроль над кодом.
- Прямая навигация.
- Простая отладка.
С появлением AI-агентов код для маппинга создаётся за считаные секунды, поэтому библиотеки маппинга уже не дают заметной экономии времени.
4. MediatR везде
Проблема:
- Нет прямой навигации от эндпоинта к обработчику.
- Появляются дополнительные команды, интерфейсы и шаблонный код только ради соблюдения паттерна.
Что использовать вместо этого:
- Обычные классы обработчиков без интерфейсов.
- Внедрение через DI и прямой вызов из эндпоинтов.
Результат:
- То же разделение ответственности.
- Меньше кода.
- Полноценная навигация в IDE в один клик.
5. EF Core через репозитории
Проблема:
- EF Core уже реализует паттерны Repository и Unit of Work.
- Дополнительные репозитории создают лишний уровень абстракции.
Что использовать вместо этого:
- DbContext напрямую в обработчиках приложения.
Не стоит создавать обёртки поверх уже существующих обёрток.
Иначе скрываются основные возможности EF Core:
- LINQ.
- Change Tracking.
- Проекции.
6. Unit-тесты по умолчанию
Проблема:
- Unit-тесты с большим количеством моков создают ложное чувство уверенности.
- Тесты проходят успешно, а приложение всё равно падает в продакшене.
Что использовать вместо этого:
- Интеграционные тесты как основной вид тестирования.
Используйте WebApplicationFactory и TestContainers для проверки полного сценария работы:
реальный эндпоинт → реальная база данныхТакой подход также проверяет:
- конфигурацию приложения;
- контейнер зависимостей (DI);
- middleware;
- миграции базы данных.
Главное правило: Не добавляйте сложность, если проект в ней не нуждается.
Большинство «лучших практик» — это решение конкретных проблем в конкретных проектах, а не универсальные правила для любого приложения.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18🔥6🍾1
В том году я заменил 20 Python-скриптов на C#
Годами каждый раз, когда нужен был 20-строчный скрипт, я создавал solution, добавлял csproj и ждал завершения генерации шаблона.
Именно поэтому я переключился на Python для таких задач.
.NET 10 изменил ситуацию, а .NET 11 Preview 3 довёл её до логического завершения.
Теперь можно запускать один C#-файл напрямую:
Без solution.
Без проекта.
Только код.
4 директивы, которые меняют всё:
Они превращают один файл в полноценное .NET-приложение.
1.
Позволяет подключить любой NuGet-пакет одной строкой.
2.
Позволяет сменить SDK и получить доступ к ASP.NET Core.
3.
Позволяет сослаться на существующую библиотеку классов.
4.
Позволяет разбивать код на несколько файлов.
Именно эта директива стала настоящим прорывом.
В .NET 10 file-based приложения были ограничены одним файлом.
Теперь можно организовать структуру настоящего приложения: модели в одном файле, сервисы — в другом, точка входа — в
Первые 5 Python-скриптов, которые я\ заменил:
- Преобразование JSON и CSV.
- Smoke-тесты внутренних API после деплоя.
- Парсинг логов для поиска и анализа ошибок.
- Сидирование базы данных для локальной разработки.
- HTTP health-check утилиты для staging-окружений.
Выгода оказалась огромной.
Получаем:
- строгую типизацию;
- IntelliSense;
- async/await из коробки.
Кроме того, можно использовать общий код из основных .NET-проектов без переписывания ни одной строки.
А когда скрипт перерастает свой первоначальный формат, его можно превратить в полноценный проект одной командой:
👉 @KodBlog
Годами каждый раз, когда нужен был 20-строчный скрипт, я создавал solution, добавлял csproj и ждал завершения генерации шаблона.
Именно поэтому я переключился на Python для таких задач.
.NET 10 изменил ситуацию, а .NET 11 Preview 3 довёл её до логического завершения.
Теперь можно запускать один C#-файл напрямую:
dotnet run hello.cs
Без solution.
Без проекта.
Только код.
4 директивы, которые меняют всё:
Они превращают один файл в полноценное .NET-приложение.
1.
#:packageПозволяет подключить любой NuGet-пакет одной строкой.
#:package Newtonsoft.Json@13.0.3
2.
#:sdkПозволяет сменить SDK и получить доступ к ASP.NET Core.
#:sdk Microsoft.NET.Sdk.Web
3.
#:projectПозволяет сослаться на существующую библиотеку классов.
#:project ../MyLibrary/MyLibrary.csproj
4.
#:include (новинка в .NET 11 Preview 3)Позволяет разбивать код на несколько файлов.
#:include models.cs
Именно эта директива стала настоящим прорывом.
В .NET 10 file-based приложения были ограничены одним файлом.
Теперь можно организовать структуру настоящего приложения: модели в одном файле, сервисы — в другом, точка входа — в
main.cs.Первые 5 Python-скриптов, которые я\ заменил:
- Преобразование JSON и CSV.
- Smoke-тесты внутренних API после деплоя.
- Парсинг логов для поиска и анализа ошибок.
- Сидирование базы данных для локальной разработки.
- HTTP health-check утилиты для staging-окружений.
Выгода оказалась огромной.
Получаем:
- строгую типизацию;
- IntelliSense;
- async/await из коробки.
Кроме того, можно использовать общий код из основных .NET-проектов без переписывания ни одной строки.
А когда скрипт перерастает свой первоначальный формат, его можно превратить в полноценный проект одной командой:
dotnet project convert main.cs
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤9🔥4🍾1
NuGet Package Pruning в .NET 10 = дзен в управлении зависимостями
Во время восстановления пакетов он удаляет зависимости, которые уже предоставляются платформой, устраняя ложноположительные CVE и сокращая граф зависимостей.
Команды получают:
- на 70% меньше отчётов об уязвимостях;
- более быстрое восстановление пакетов (ускорение до 50%).
Подробнее: https://devblogs.microsoft.com/dotnet/nuget-package-pruning-in-dotnet-10/
👉 @KodBlog
Во время восстановления пакетов он удаляет зависимости, которые уже предоставляются платформой, устраняя ложноположительные CVE и сокращая граф зависимостей.
Команды получают:
- на 70% меньше отчётов об уязвимостях;
- более быстрое восстановление пакетов (ускорение до 50%).
Подробнее: https://devblogs.microsoft.com/dotnet/nuget-package-pruning-in-dotnet-10/
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Каждый .NET-проект на микросервисах рано или поздно сталкивается с одними и теми же 5 проблемами.
Большинство команд подключают для их решения 5 разных библиотек.
Но есть способ проще.
На прошлой неделе я заново реализовал систему бронирования отелей с четырьмя микросервисами.
В типичной архитектуре мне понадобились бы:
→ MassTransit для обмена сообщениями
→ Polly для повторных попыток (retries)
→ Refit + HttpClient для вызовов сервисов
→ клиент для Vault для работы с секретами
→ Redis SDK для кеширования и распределённых блокировок
Пять SDK.
Пять способов конфигурации.
Пять разных ментальных моделей.
Вместо этого я использовал Dapr — один runtime, один клиент и единый API для всего.
Вот эти 5 проблем и то, как Dapr их решает.
1. Вызовы между сервисами
Вы обращаетесь к сервисам по App ID, а не по URL.
Dapr берёт на себя:
- service discovery;
- retries;
- трассировку запросов (tracing).
Никаких захардкоженных URL в коде.
2. Асинхронные события
Публикация события занимает одну строку:
Подписчики обрабатывают события через атрибут
Больше не нужен шаблонный код с
3. Состояние приложения и кеширование
Хранилище типа key-value с подключаемыми backend'ами:
Дополнительно:
↳ нужен TTL — передайте metadata;
↳ нужна оптимистичная блокировка — используйте ETag;
↳ backend может быть Redis, PostgreSQL или Cosmos DB.
4. Управление секретами
Больше не нужно хранить учётные данные в
В качестве backend можно использовать:
- Azure Key Vault;
- AWS Secrets Manager;
- HashiCorp Vault.
Код приложения остаётся одинаковым для всех окружений.
5. Распределённые блокировки
Взаимное исключение между экземплярами сервисов:
Например, это позволяет безопасно забронировать номер, даже если за него одновременно конкурируют три экземпляра сервиса.
Но главное преимущество Dapr — это то, что объединяет все эти возможности.
Каждое имя (
Хотите заменить RabbitMQ на Kafka?
Достаточно изменить один YAML-файл.
Код приложения при этом остаётся без изменений.
👉 @KodBlog
Большинство команд подключают для их решения 5 разных библиотек.
Но есть способ проще.
На прошлой неделе я заново реализовал систему бронирования отелей с четырьмя микросервисами.
В типичной архитектуре мне понадобились бы:
→ MassTransit для обмена сообщениями
→ Polly для повторных попыток (retries)
→ Refit + HttpClient для вызовов сервисов
→ клиент для Vault для работы с секретами
→ Redis SDK для кеширования и распределённых блокировок
Пять SDK.
Пять способов конфигурации.
Пять разных ментальных моделей.
Вместо этого я использовал Dapr — один runtime, один клиент и единый API для всего.
Вот эти 5 проблем и то, как Dapr их решает.
1. Вызовы между сервисами
Вы обращаетесь к сервисам по App ID, а не по URL.
await daprClient.InvokeMethodAsync(
"hotels-api",
"rooms/available");
Dapr берёт на себя:
- service discovery;
- retries;
- трассировку запросов (tracing).
Никаких захардкоженных URL в коде.
2. Асинхронные события
Публикация события занимает одну строку:
await daprClient.PublishEventAsync(
"pubsub",
"booking-created",
evt);
Подписчики обрабатывают события через атрибут
[Topic].Больше не нужен шаблонный код с
BackgroundService.3. Состояние приложения и кеширование
Хранилище типа key-value с подключаемыми backend'ами:
await daprClient.SaveStateAsync(
"statestore",
key,
value);
Дополнительно:
↳ нужен TTL — передайте metadata;
↳ нужна оптимистичная блокировка — используйте ETag;
↳ backend может быть Redis, PostgreSQL или Cosmos DB.
4. Управление секретами
Больше не нужно хранить учётные данные в
appsettings.var secrets = await daprClient.GetSecretAsync(
"secretstore",
"payment-gateway");
В качестве backend можно использовать:
- Azure Key Vault;
- AWS Secrets Manager;
- HashiCorp Vault.
Код приложения остаётся одинаковым для всех окружений.
5. Распределённые блокировки
Взаимное исключение между экземплярами сервисов:
var lockResponse = await daprClient.Lock(
"statestore",
"room-101",
"owner",
30);
Например, это позволяет безопасно забронировать номер, даже если за него одновременно конкурируют три экземпляра сервиса.
Но главное преимущество Dapr — это то, что объединяет все эти возможности.
Каждое имя (
pubsub, statestore, secretstore) привязано к YAML-компоненту.Хотите заменить RabbitMQ на Kafka?
Достаточно изменить один YAML-файл.
Код приложения при этом остаётся без изменений.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3👎1🍾1
Я до сих пор вижу эту ошибку в большинстве .NET API.
Эндпоинт принимает query-параметр, выполняет асинхронный запрос к БД и возвращает результат. На первый взгляд всё нормально. Но нигде нет
Пользователь закрыл вкладку. Мобильный клиент словил таймаут. Load balancer разорвал соединение. А серверу всё равно. Он продолжает выполнять запрос, держит соединение, аллоцирует память и упорно считает результат, который уже никому не нужен.
Хотя .NET умеет это обрабатывать. Любой эндпоинт может принимать параметр
Два сценария, где это буквально разница между «система здорова» и «всё горит»:
Поток пользователей долбит медленный search-endpoint. Половина в ярости перекликивает UI и бросает запросы. Без токена сервер честно доводит каждый запрос до конца. С токеном брошенные запросы отменяются за миллисекунды, а pool остаётся доступен для тех, кто всё ещё ждёт ответ.
Долгий export падает на середине. Клиент делает retry уже с новыми параметрами. Без токена старый export продолжает молотить ещё две минуты, пока новый стоит в очереди за ним. С токеном разрыв соединения сразу освобождает worker.
Изменение — это всего два параметра: один в эндпоинте и один в методе доступа к данным. Всё.
Обычно в ответ слышу: «а что насчёт бэкграунд-задач, которые не должны отменяться?» Справедливо. Для них явно передавайте
Каждый async IO-вызов в вашем коде должен принимать и прокидывать
👉 @KodBlog
Эндпоинт принимает query-параметр, выполняет асинхронный запрос к БД и возвращает результат. На первый взгляд всё нормально. Но нигде нет
CancellationToken.Пользователь закрыл вкладку. Мобильный клиент словил таймаут. Load balancer разорвал соединение. А серверу всё равно. Он продолжает выполнять запрос, держит соединение, аллоцирует память и упорно считает результат, который уже никому не нужен.
Хотя .NET умеет это обрабатывать. Любой эндпоинт может принимать параметр
CancellationToken, а фреймворк автоматически пробрасывает туда HttpContext.RequestAborted. Дальше просто передаёте токен в EF Core, HttpClient, file IO, channels — в любые async-вызовы. Как только запрос прерывается, операции останавливаются. SQL-запрос отменяется прямо во время выполнения. HTTP-вызов обрывается. Соединение возвращается в pool.Два сценария, где это буквально разница между «система здорова» и «всё горит»:
Поток пользователей долбит медленный search-endpoint. Половина в ярости перекликивает UI и бросает запросы. Без токена сервер честно доводит каждый запрос до конца. С токеном брошенные запросы отменяются за миллисекунды, а pool остаётся доступен для тех, кто всё ещё ждёт ответ.
Долгий export падает на середине. Клиент делает retry уже с новыми параметрами. Без токена старый export продолжает молотить ещё две минуты, пока новый стоит в очереди за ним. С токеном разрыв соединения сразу освобождает worker.
Изменение — это всего два параметра: один в эндпоинте и один в методе доступа к данным. Всё.
Обычно в ответ слышу: «а что насчёт бэкграунд-задач, которые не должны отменяться?» Справедливо. Для них явно передавайте
CancellationToken.None — и намерение сразу видно прямо в сигнатуре.Каждый async IO-вызов в вашем коде должен принимать и прокидывать
CancellationToken.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍾4
Не каждой real-time фиче нужен SignalR.
Иногда вам не нужен full-duplex communication. Не нужны hubs. Не нужна client library.
Нужно лишь, чтобы сервер пушил обновления в браузер.
Именно здесь отлично подходит Server-Sent Events (SSE).
SSE даёт простой однонаправленный поток от сервера к клиенту поверх обычного HTTP.
А в ASP.NET Core 10 наконец появился нативный high-level API.
Можно вернуть stream из
На стороне браузера всё так же просто. Без npm-пакетов. Без кастомного протокола.
Просто
SSE также сразу даёт несколько полезных возможностей:
- автоматический reconnect в браузере
- стандартный HTTP middleware
- обычную authorization-модель
- простую фильтрацию по пользователям
- поддержку повторной отправки пропущенных событий через
Поэтому SSE отлично подходит для:
- notification bell
- dashboard’ов
- progress update’ов
- обновлений статуса заказов
- лёгких live feed
Но это не замена SignalR. Если нужен двусторонний обмен сообщениями, сложный scale-out или более богатый real-time protocol — SignalR всё ещё остаётся лучшим выбором.
Суть проще: Используйте самый лёгкий инструмент, который решает задачу.
👉 @KodBlog
Иногда вам не нужен full-duplex communication. Не нужны hubs. Не нужна client library.
Нужно лишь, чтобы сервер пушил обновления в браузер.
Именно здесь отлично подходит Server-Sent Events (SSE).
SSE даёт простой однонаправленный поток от сервера к клиенту поверх обычного HTTP.
А в ASP.NET Core 10 наконец появился нативный high-level API.
Можно вернуть stream из
IAsyncEnumerable, а .NET сам будет держать HTTP-соединение открытым:return Results.ServerSentEvents(
channelReader.ReadAllAsync(cancellationToken),
eventType: "orders");
На стороне браузера всё так же просто. Без npm-пакетов. Без кастомного протокола.
Просто
EventSource.SSE также сразу даёт несколько полезных возможностей:
- автоматический reconnect в браузере
- стандартный HTTP middleware
- обычную authorization-модель
- простую фильтрацию по пользователям
- поддержку повторной отправки пропущенных событий через
Last-Event-IDПоэтому SSE отлично подходит для:
- notification bell
- dashboard’ов
- progress update’ов
- обновлений статуса заказов
- лёгких live feed
Но это не замена SignalR. Если нужен двусторонний обмен сообщениями, сложный scale-out или более богатый real-time protocol — SignalR всё ещё остаётся лучшим выбором.
Суть проще: Используйте самый лёгкий инструмент, который решает задачу.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2🍾1
Я собрал рабочий Minimal API с EF Core всего в 3 файлах.
То же самое можно сделать за 10 минут. Без solution-файла. Без csproj. Без настройки проекта.
Только три
Это file-based apps из .NET 11 Preview 3.
И это полностью меняет подход к созданию внутренних инструментов и прототипов.
Структура из 3 файлов
↳ Обычный POCO с
↳ EF Core
↳ Настройка DI, Minimal API endpoints и
Вот и всё: 3 файла в одной папке.
Вся магия — в 4 директивах в начале
↳ Подключает
↳ При первом запуске подтягивает SQLite provider
↳ Добавляет entity в компиляцию
↳ Добавляет
Эти четыре строки заменяют целый
Ниже директив — обычный ASP.NET Core-код.
Запуск одной командой:
При первом запуске восстанавливается EF Core.
Все последующие запуски уже быстрые.
И в итоге у вас полноценный Web API с настоящей базой данных.
Где file-based apps особенно хороши
→ Internal tools без лишней церемонии
→ Прототипы, которыми можно делиться как одной папкой
→ Демо, запускаемые за пару минут
→ Замена Python-скриптов там, где нужна строгая типизация
→ Онбординг новых разработчиков без путаницы с
Где их использовать не стоит
→ Multi-project решения с shared libraries
→ Приложения с кастомной MSBuild-логикой
→ Разработка NuGet-пакетов
→ Production-приложения с полноценным CI/CD и test-проектами
А когда скрипт перерастёт свой формат — есть команда миграции:
Она создаст полноценный
👉 @KodBlog
То же самое можно сделать за 10 минут. Без solution-файла. Без csproj. Без настройки проекта.
Только три
.cs-файла и dotnet CLI.Это file-based apps из .NET 11 Preview 3.
И это полностью меняет подход к созданию внутренних инструментов и прототипов.
Структура из 3 файлов
Order.cs↳ Обычный POCO с
Id, OrderNumber, CustomerName, Amount, CreatedAtOrdersDbContext.cs↳ EF Core
DbContext с inline Fluent API mappingsmain.cs↳ Настройка DI, Minimal API endpoints и
app.Run()Вот и всё: 3 файла в одной папке.
Вся магия — в 4 директивах в начале
main.cs#:sdk Microsoft.NET.Sdk.Web
↳ Подключает
WebApplication и типы ASP.NET Core#:package Microsoft.EntityFrameworkCore.Sqlite@10.0.0
↳ При первом запуске подтягивает SQLite provider
#:include Order.cs
↳ Добавляет entity в компиляцию
#:include OrdersDbContext.cs
↳ Добавляет
DbContext в компиляциюЭти четыре строки заменяют целый
csproj и sln.Ниже директив — обычный ASP.NET Core-код.
Запуск одной командой:
dotnet run main.cs
При первом запуске восстанавливается EF Core.
Все последующие запуски уже быстрые.
И в итоге у вас полноценный Web API с настоящей базой данных.
Где file-based apps особенно хороши
→ Internal tools без лишней церемонии
→ Прототипы, которыми можно делиться как одной папкой
→ Демо, запускаемые за пару минут
→ Замена Python-скриптов там, где нужна строгая типизация
→ Онбординг новых разработчиков без путаницы с
csprojГде их использовать не стоит
→ Multi-project решения с shared libraries
→ Приложения с кастомной MSBuild-логикой
→ Разработка NuGet-пакетов
→ Production-приложения с полноценным CI/CD и test-проектами
А когда скрипт перерастёт свой формат — есть команда миграции:
dotnet project convert main.cs
Она создаст полноценный
csproj и перенесёт туда все директивы.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
Опенсорс домен-сервис с 162K звезд,
→ Регистрация доменов за $0
→ Бесплатное продление навсегда
→ Никаких скрытых подписок и ловушек
→ Полностью open-source и управляется сообществом
https://github.com/DigitalPlatDev/FreeDomain
👉 @KodBlog
→ Регистрация доменов за $0
→ Бесплатное продление навсегда
→ Никаких скрытых подписок и ловушек
→ Полностью open-source и управляется сообществом
https://github.com/DigitalPlatDev/FreeDomain
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🍾1
Большинство .NET-разработчиков используют Redis только как кэш — и на этом всё.
Redis хранит данные в памяти (RAM), а не на диске, поэтому чтение обычно занимает меньше миллисекунды.
Именно благодаря этой скорости Redis подходит не только для кэширования. Вот 10 сценариев, о которых стоит знать:
1. Кэширование ответов API
Сохраните результат медленного запроса к базе данных в Redis. Следующий запрос получит данные из памяти, не обращаясь к БД повторно.
2. Хранение сессий
Держите пользовательские сессии в Redis, чтобы любой сервер в кластере мог их прочитать. Больше никаких внезапных разлогиниваний при переключении балансировщиком нагрузки на другой сервер.
3. Ограничение частоты запросов (Rate Limiting)
С помощью одного счётчика Redis можно отслеживать количество запросов от IP-адреса за последнюю минуту и блокировать злоупотребления ещё до того, как они дойдут до API.
4. Лидерборды в реальном времени
Сортированные множества (Sorted Sets) позволяют автоматически поддерживать рейтинг по очкам. Запрос топ-10 выполняется практически мгновенно даже при миллионах игроков.
5. Обмен сообщениями через Pub/Sub
Один сервис публикует сообщение, а все подписанные сервисы получают его сразу. Отлично подходит для уведомлений в реальном времени без постоянных опросов базы данных.
6. Распределённые блокировки
Когда несколько серверов могут одновременно изменять одну и ту же запись, Redis выдаёт единственную блокировку. Это помогает избежать конфликтов и перезаписи данных.
7. Очереди задач
Помещайте длительные фоновые операции, например отправку писем, в список Redis. Отдельный воркер обработает задачу, а пользователю не придётся ждать.
8. Аналитика в реальном времени
Redis Streams позволяют записывать большие потоки событий (клики, просмотры страниц и т.д.) и обрабатывать их по мере поступления.
9. Флаги функциональности (Feature Flags)
Храните переключатели функций в Redis и включайте или отключайте возможности для всех пользователей мгновенно, без повторного развёртывания приложения.
10. Память для AI-чатов
Храните недавний контекст диалога в Redis, чтобы LLM (модель, лежащая в основе чат-бота) могла помнить, о чём шла речь ранее.
Один инструмент — десять сценариев использования. Но большинство команд так и остаются на первом пункте.
👉 @KodBlog
Redis хранит данные в памяти (RAM), а не на диске, поэтому чтение обычно занимает меньше миллисекунды.
Именно благодаря этой скорости Redis подходит не только для кэширования. Вот 10 сценариев, о которых стоит знать:
1. Кэширование ответов API
Сохраните результат медленного запроса к базе данных в Redis. Следующий запрос получит данные из памяти, не обращаясь к БД повторно.
2. Хранение сессий
Держите пользовательские сессии в Redis, чтобы любой сервер в кластере мог их прочитать. Больше никаких внезапных разлогиниваний при переключении балансировщиком нагрузки на другой сервер.
3. Ограничение частоты запросов (Rate Limiting)
С помощью одного счётчика Redis можно отслеживать количество запросов от IP-адреса за последнюю минуту и блокировать злоупотребления ещё до того, как они дойдут до API.
4. Лидерборды в реальном времени
Сортированные множества (Sorted Sets) позволяют автоматически поддерживать рейтинг по очкам. Запрос топ-10 выполняется практически мгновенно даже при миллионах игроков.
5. Обмен сообщениями через Pub/Sub
Один сервис публикует сообщение, а все подписанные сервисы получают его сразу. Отлично подходит для уведомлений в реальном времени без постоянных опросов базы данных.
6. Распределённые блокировки
Когда несколько серверов могут одновременно изменять одну и ту же запись, Redis выдаёт единственную блокировку. Это помогает избежать конфликтов и перезаписи данных.
7. Очереди задач
Помещайте длительные фоновые операции, например отправку писем, в список Redis. Отдельный воркер обработает задачу, а пользователю не придётся ждать.
8. Аналитика в реальном времени
Redis Streams позволяют записывать большие потоки событий (клики, просмотры страниц и т.д.) и обрабатывать их по мере поступления.
9. Флаги функциональности (Feature Flags)
Храните переключатели функций в Redis и включайте или отключайте возможности для всех пользователей мгновенно, без повторного развёртывания приложения.
10. Память для AI-чатов
Храните недавний контекст диалога в Redis, чтобы LLM (модель, лежащая в основе чат-бота) могла помнить, о чём шла речь ранее.
Один инструмент — десять сценариев использования. Но большинство команд так и остаются на первом пункте.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🤣3🍾1
Разработчики на .NET, автоматизируйте работу с документами.
→ Генерация PDF-документов (
→ Экспорт в Excel без использования Interop (
→ Объединение и разделение PDF-файлов (
→ Работа с шаблонами Word (
→ OCR и извлечение данных из документов (
Подробнее: https://buff.ly/65Hrxv4
👉 @KodBlog
→ Генерация PDF-документов (
QuestPDF / iText)→ Экспорт в Excel без использования Interop (
ClosedXML / EPPlus)→ Объединение и разделение PDF-файлов (
PdfSharp)→ Работа с шаблонами Word (
OpenXML / DocX)→ OCR и извлечение данных из документов (
PdfPig / Tesseract / Azure Document Intelligence)Подробнее: https://buff.ly/65Hrxv4
Please open Telegram to view this post
VIEW IN TELEGRAM
DEV Community
7 Document Processing Tasks Every .NET Developer Should Automate
Document processing is one of the most repetitive parts of many .NET applications. From generating...
🔥2🍾1
Срочная новость: появился новый способ создавать десктопные приложения на WinUI без XAML — с помощью декларативного компонентного фреймворка на C#.
Теперь вы можете создавать приложения на WinUI в формате single-file app — всё приложение может быть описано в одном файле.
Смотрите репозиторий: https://github.com/microsoft/microsoft-ui-reactor
@KodBlog
Теперь вы можете создавать приложения на WinUI в формате single-file app — всё приложение может быть описано в одном файле.
Смотрите репозиторий: https://github.com/microsoft/microsoft-ui-reactor
@KodBlog
🥴8❤2🍾1
50 тем по System Design — от простого к сложному
Идеальная дорожная карта для изучения System Design в 2026 году. Сохраните этот список.
1. Спроектировать Rate Limiter
2. Спроектировать сервис сокращения URL
3. Спроектировать Pastebin
4. Спроектировать генератор уникальных идентификаторов
5. Спроектировать Consistent Hashing
6. Спроектировать балансировщик нагрузки
7. Спроектировать API Gateway
8. Спроектировать простое Key-Value хранилище
9. Спроектировать систему кэширования (например, LRU Cache)
10. Спроектировать систему уведомлений
11. Спроектировать систему автодополнения (Typeahead/Autocomplete)
12. Спроектировать веб-краулер
13. Спроектировать очередь сообщений
14. Спроектировать чат один на один
15. Спроектировать групповой чат
16. Спроектировать ленту новостей
17. Спроектировать сервис определения близости пользователей (например, друзья поблизости)
18. Спроектировать Instagram (обмен фото и видео + лента)
19. Спроектировать Twitter/X (публикации + таймлайн)
20. Спроектировать WhatsApp (обмен сообщениями в реальном времени)
21. Спроектировать Dropbox (хранение и синхронизация файлов)
22. Спроектировать систему бронирования билетов
23. Спроектировать платформу электронной коммерции (каталог + оформление заказа)
24. Спроектировать рекомендательную систему
25. Спроектировать распределённый кэш
26. Спроектировать Uber (поиск и сопоставление водителей и пассажиров)
27. Спроектировать Netflix (платформа потокового видео)
28. Спроектировать YouTube (загрузка и стриминг видео)
29. Спроектировать TikTok (платформа коротких видео)
30. Спроектировать ленту новостей социальной сети уровня Facebook
31. Спроектировать Google Docs (совместное редактирование документов в реальном времени)
32. Спроектировать CDN (Content Delivery Network)
33. Спроектировать поисковую систему (индексация и поиск)
34. Спроектировать Google Maps (маршрутизация и геолокационные сервисы)
35. Спроектировать распределённую базу данных
36. Спроектировать систему аналитики в реальном времени
37. Спроектировать систему показа и отслеживания рекламы
38. Спроектировать систему обнаружения мошенничества
39. Спроектировать торговую платформу или биржу ценных бумаг
40. Спроектировать распределённый планировщик задач
41. Спроектировать архитектуру Event Sourcing + CQRS
42. Спроектировать мультиарендную SaaS-платформу (Multi-tenant SaaS)
43. Спроектировать масштабируемый сервис прямых видеотрансляций
44. Спроектировать высокомасштабируемую NoSQL-базу данных
45. Спроектировать серверную часть многопользовательской игры в реальном времени
46. Спроектировать инфраструктуру обслуживания ML-моделей (Model Serving)
47. Спроектировать геораспределённую систему с низкой задержкой
48. Спроектировать глобальную базу данных со строгой согласованностью
49. Спроектировать платформу для высокочастотной торговли (HFT)
50. Спроектировать распределённую систему планетарного масштаба (миллиарды пользователей, несколько регионов, высокая доступность)
👉 @KodBlog
Идеальная дорожная карта для изучения System Design в 2026 году. Сохраните этот список.
1. Спроектировать Rate Limiter
2. Спроектировать сервис сокращения URL
3. Спроектировать Pastebin
4. Спроектировать генератор уникальных идентификаторов
5. Спроектировать Consistent Hashing
6. Спроектировать балансировщик нагрузки
7. Спроектировать API Gateway
8. Спроектировать простое Key-Value хранилище
9. Спроектировать систему кэширования (например, LRU Cache)
10. Спроектировать систему уведомлений
11. Спроектировать систему автодополнения (Typeahead/Autocomplete)
12. Спроектировать веб-краулер
13. Спроектировать очередь сообщений
14. Спроектировать чат один на один
15. Спроектировать групповой чат
16. Спроектировать ленту новостей
17. Спроектировать сервис определения близости пользователей (например, друзья поблизости)
18. Спроектировать Instagram (обмен фото и видео + лента)
19. Спроектировать Twitter/X (публикации + таймлайн)
20. Спроектировать WhatsApp (обмен сообщениями в реальном времени)
21. Спроектировать Dropbox (хранение и синхронизация файлов)
22. Спроектировать систему бронирования билетов
23. Спроектировать платформу электронной коммерции (каталог + оформление заказа)
24. Спроектировать рекомендательную систему
25. Спроектировать распределённый кэш
26. Спроектировать Uber (поиск и сопоставление водителей и пассажиров)
27. Спроектировать Netflix (платформа потокового видео)
28. Спроектировать YouTube (загрузка и стриминг видео)
29. Спроектировать TikTok (платформа коротких видео)
30. Спроектировать ленту новостей социальной сети уровня Facebook
31. Спроектировать Google Docs (совместное редактирование документов в реальном времени)
32. Спроектировать CDN (Content Delivery Network)
33. Спроектировать поисковую систему (индексация и поиск)
34. Спроектировать Google Maps (маршрутизация и геолокационные сервисы)
35. Спроектировать распределённую базу данных
36. Спроектировать систему аналитики в реальном времени
37. Спроектировать систему показа и отслеживания рекламы
38. Спроектировать систему обнаружения мошенничества
39. Спроектировать торговую платформу или биржу ценных бумаг
40. Спроектировать распределённый планировщик задач
41. Спроектировать архитектуру Event Sourcing + CQRS
42. Спроектировать мультиарендную SaaS-платформу (Multi-tenant SaaS)
43. Спроектировать масштабируемый сервис прямых видеотрансляций
44. Спроектировать высокомасштабируемую NoSQL-базу данных
45. Спроектировать серверную часть многопользовательской игры в реальном времени
46. Спроектировать инфраструктуру обслуживания ML-моделей (Model Serving)
47. Спроектировать геораспределённую систему с низкой задержкой
48. Спроектировать глобальную базу данных со строгой согласованностью
49. Спроектировать платформу для высокочастотной торговли (HFT)
50. Спроектировать распределённую систему планетарного масштаба (миллиарды пользователей, несколько регионов, высокая доступность)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11😐4❤3👏1🍾1
AddDbContext — вариант по умолчанию. AddDbContextPool — оптимизация. AddDbContextFactory — запасной выход для особых сценариев. Большинство .NET-команд не понимают, когда стоит выбирать каждый из них.EF Core предоставляет три способа регистрации
DbContext. В Program.cs они выглядят похоже. В продакшене они ведут себя совершенно по-разному.1. AddDbContext
Вариант по умолчанию. Регистрирует
DbContext с временем жизни Scoped — новый экземпляр на каждый HTTP-запрос. Фреймворк создаёт его при начале запроса и освобождает после отправки ответа.Используйте его, если конфигурация контекста меняется от запроса к запросу: разные строки подключения в multi-tenant-приложениях, динамические фильтры логирования и всё, что нужно определять во время обработки запроса.
Цена такого подхода — создание и освобождение объекта на каждом запросе. В API с низкой нагрузкой вы этого не заметите. При 5000 запросах в секунду нагрузка на GC начинает проявляться в трассировках.
2. AddDbContextPool
EF Core поддерживает пул экземпляров
DbContext: выдаёт экземпляр на время запроса, а затем возвращает его обратно в пул. Никаких дополнительных аллокаций и затрат на создание объекта.Используйте этот вариант, если конфигурация стабильна и важна высокая пропускная способность. Он существенно снижает количество аллокаций на горячих эндпоинтах.
Но есть нюанс: экземпляры из пула переиспользуются, а не создаются заново. Если запрос изменяет состояние на уровне контекста — настройки
ChangeTracker, savepoint'ы, состояние пользовательских интерсепторов — и логика сброса что-то упустит, следующий запрос унаследует это состояние. Такой баг выглядит случайным. На самом деле он не случайный. Причина — некорректный сброс состояния перед возвратом объекта в пул.Не используйте пул, если вам нужна конфигурация, зависящая от конкретного запроса. Пул делает такой сценарий невозможным.
3. AddDbContextFactory
Здесь вы сами управляете жизненным циклом контекста. Внедряете
IDbContextFactory<T>, вызываете CreateDbContext(), используете контекст внутри блока using и затем освобождаете его.Используйте этот вариант в фоновых сервисах, worker-задачах, hosted services и любом коде, который выполняется вне HTTP-запроса.
Scoped-зависимости там не работают, потому что отсутствует scope запроса. Фабрика позволяет создавать контекст независимо от него.Цена — ответственность за освобождение ресурсов ложится на вас. Забудете
using — получите утечку соединений.Если конфигурация меняется для каждого запроса — используйте
AddDbContext.Если нужна максимальная производительность при стабильной конфигурации — используйте
AddDbContextPool и контролируйте корректный сброс состояния.Если код выполняется вне HTTP-скоупа (фоновые сервисы, воркеры) — используйте
AddDbContextFactory.Большинство команд по умолчанию используют
AddDbContext и больше не возвращаются к этому решению. Если у вас есть горячие эндпоинты или фоновые задачи, работающие с базой данных, стоит потратить 10 минут на аудит текущей конфигурации.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤3🍾2
Только сейчас наткнулся на полностью переписанный DesktopManager для .NET и PowerShell.
Штука неожиданно мощная. Из коробки умеет:
• Управлять мониторами и обоями
• Контролировать слайд-шоу рабочего стола
• Менять яркость экрана
• Находить окна и UI-элементы и взаимодействовать с ними
• Эмулировать мышь и клавиатуру
• Работать с буфером обмена
• Делать скриншоты
• Управлять раскладками окон и рабочим столом
По сути, это такой комбайн для автоматизации Windows. Если приходилось писать свои обёртки вокруг WinAPI, UI Automation или PowerShell-скрипты для управления рабочим столом, здесь многое уже собрано в одном месте.
Проект с открытым исходным кодом, доступен бесплатно как NuGet-пакет и PowerShell-модуль.
👉 @KodBlog
Штука неожиданно мощная. Из коробки умеет:
• Управлять мониторами и обоями
• Контролировать слайд-шоу рабочего стола
• Менять яркость экрана
• Находить окна и UI-элементы и взаимодействовать с ними
• Эмулировать мышь и клавиатуру
• Работать с буфером обмена
• Делать скриншоты
• Управлять раскладками окон и рабочим столом
По сути, это такой комбайн для автоматизации Windows. Если приходилось писать свои обёртки вокруг WinAPI, UI Automation или PowerShell-скрипты для управления рабочим столом, здесь многое уже собрано в одном месте.
Проект с открытым исходным кодом, доступен бесплатно как NuGet-пакет и PowerShell-модуль.
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - EvotecIT/DesktopManager: DesktopManager is a C# library and PowerShell module that allows to get and set wallpapers to…
DesktopManager is a C# library and PowerShell module that allows to get and set wallpapers to given monitor. - EvotecIT/DesktopManager
🍾2🔥1
Знаешь, как спроецировать вложенную коллекцию?
Вот один из способов:
SelectMany — это LINQ-метод, который работает с коллекциями IEnumerable и IQueryable и разворачивает элементы последовательности в одну коллекцию.
Если разложить весь процесс по шагам:
• Берёт последовательность элементов
• Выполняет преобразование для каждого элемента
• Генерирует новую последовательность элементов для каждого входного элемента
• Объединяет все полученные промежуточные последовательности в одну плоскую последовательность
Если коллекция равна
👉 @KodBlog
Вот один из способов:
SelectMany — это LINQ-метод, который работает с коллекциями IEnumerable и IQueryable и разворачивает элементы последовательности в одну коллекцию.
Если разложить весь процесс по шагам:
• Берёт последовательность элементов
• Выполняет преобразование для каждого элемента
• Генерирует новую последовательность элементов для каждого входного элемента
• Объединяет все полученные промежуточные последовательности в одну плоскую последовательность
Если коллекция равна
null, выбрасывается ArgumentNullException.Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😁2🍾1