Предпочитай
1. Корректность (например, проблема с турецкой буквой
2. Читаемость
3. Производительность
👉 @KodBlog
string.Equals вместо ToLower / ToUpper для нечувствительных к регистру сравнений строк1. Корректность (например, проблема с турецкой буквой
i)2. Читаемость
3. Производительность
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤4🔥2👏1
Нужны пиксельно идеальные PDF-отчёты в .NET?
Забей на проприетарные библиотеки, используй HTML-шаблоны и PuppeteerSharp.
Собери отчёт как HTML-шаблон на Handlebars, подставь данные, а потом отрендерь в PDF через headless-браузер.
Учись генерировать удобные и красивые PDF-отчёты с
👉 @KodBlog
Забей на проприетарные библиотеки, используй HTML-шаблоны и PuppeteerSharp.
Собери отчёт как HTML-шаблон на Handlebars, подставь данные, а потом отрендерь в PDF через headless-браузер.
Учись генерировать удобные и красивые PDF-отчёты с
Handlebars.NET и PuppeteerSharp — гайд МиланаPlease open Telegram to view this post
VIEW IN TELEGRAM
❤12👍4
Вызов Azure Function из Azure SQL DB
Да, это реально. Хранимая процедура
Кто-то уже пробовал?
👉 @KodBlog
Да, это реально. Хранимая процедура
sp_invoke_external_rest_endpoint позволяет дергать HTTPS REST endpoint, переданный ей в качестве аргумента.Кто-то уже пробовал?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🤔2🎉2🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🤔4🍌2🤨2
Лучшая техника dependency injection, которой почти никто не пользуется
(больше никаких конструкторов на 10 строк)
Используй
Это малоизвестная фича в ASP.NET Core, которая позволяет инжектить зависимости прямо в метод эндпоинта
Для этого можно использовать
Но
Когда это уместно
• Когда сервис нужен только в одном экшене
• Когда конструктор превращается в лапшу
• Когда сервис тяжёлый и хочется лучше контролировать память
Да, constructor injection по умолчанию — это стандартный подход
Но method injection — это удобный инструмент, если хочется делать более мелкие сервисы, которые соблюдают принцип единственной ответственности, и при этом иметь контроллеры, не превращённые в свалку зависимостей
👉 @KodBlog
(больше никаких конструкторов на 10 строк)
Используй
Method InjectionЭто малоизвестная фича в ASP.NET Core, которая позволяет инжектить зависимости прямо в метод эндпоинта
Для этого можно использовать
[FromServices] IYourServiceНо
[FromServices] можно и не указыватьКогда это уместно
• Когда сервис нужен только в одном экшене
• Когда конструктор превращается в лапшу
• Когда сервис тяжёлый и хочется лучше контролировать память
Да, constructor injection по умолчанию — это стандартный подход
Но method injection — это удобный инструмент, если хочется делать более мелкие сервисы, которые соблюдают принцип единственной ответственности, и при этом иметь контроллеры, не превращённые в свалку зависимостей
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤🔥4❤2😁2🔥1
Твой опыт с NuGet в .NET ограничивается AutoMapper?
Быть в курсе .NET = быть в курсе инструментов.
Не отставай — вот 24 NuGet-библиотеки
👉 @KodBlog
Быть в курсе .NET = быть в курсе инструментов.
Не отставай — вот 24 NuGet-библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥1
Когда исключения неизбежны, нужен механизм для их обработки.
Вот как это можно настроить за несколько минут:
Начиная с .NET 8 у вас есть интерфейс
Это абстракция для управления исключениями с одним методом:
Он отвечает за обработку исключений в пайплайне ASP.NET Core.
Метод возвращает
Это позволяет реализовать кастомную логику под разные сценарии.
Для конфигурации нужно сделать три шага:
1. Зарегистрировать сервис
2. Зарегистрировать
3. Зарегистрировать
Третий шаг опционален, но я настоятельно рекомендую его использовать, чтобы ошибки были более читаемыми.
👉 @KodBlog
Вот как это можно настроить за несколько минут:
Начиная с .NET 8 у вас есть интерфейс
IExceptionHandlerЭто абстракция для управления исключениями с одним методом:
TryHandleAsyncОн отвечает за обработку исключений в пайплайне ASP.NET Core.
Метод возвращает
true, если исключение обработано успешно, и false, если его нельзя обработать.Это позволяет реализовать кастомную логику под разные сценарии.
Для конфигурации нужно сделать три шага:
1. Зарегистрировать сервис
IExceptionHandler через dependency injection2. Зарегистрировать
ExceptionHandlerMiddleware в пайплайне запросов3. Зарегистрировать
ProblemDetails ответТретий шаг опционален, но я настоятельно рекомендую его использовать, чтобы ошибки были более читаемыми.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤5
Хочешь писать более чистый C#-код?
Начни с чистых функций.
Чистая функция проста:
Берёт входные данные, возвращает результат и больше ни на что не влияет.
Никаких запросов в базу. Никаких случайных значений. Никаких скрытых побочных эффектов
Такой код легче тестировать, отлаживать и ему проще доверять.
Если логика кажется непредсказуемой — попробуй вынести её в чистую функцию.
Удивишься, насколько всё станет понятнее.
👉 @KodBlog
Начни с чистых функций.
Чистая функция проста:
Берёт входные данные, возвращает результат и больше ни на что не влияет.
Никаких запросов в базу. Никаких случайных значений. Никаких скрытых побочных эффектов
Такой код легче тестировать, отлаживать и ему проще доверять.
Если логика кажется непредсказуемой — попробуй вынести её в чистую функцию.
Удивишься, насколько всё станет понятнее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🤨2
Примеры использования разделителя цифр (_) в C#
👉 @KodBlog
// Можно использовать в целых числах
int oneMillion = 1_000_000;
Console.WriteLine(oneMillion); // Выведет: 1000000
// Работает и с числами с плавающей точкой
double billion = 1_000_000_000.0;
Console.WriteLine(billion); // Выведет: 1000000000
// Поддерживается и в двоичной, и в шестнадцатеричной записи
int binary = 0b1010_1011_1100;
Console.WriteLine(binary); // Выведет: 2748
int hexadecimal = 0x1234_abcd;
Console.WriteLine(hexadecimal); // Выведет: 305441741
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥6❤4
До сих пор выкатываешь новые фичи через
Есть решение получше.
В .NET есть отличная поддержка feature flags, и что важнее - таргетированных feature flags
Это значит, что можно включать функциональность:
- только для внутренних тестировщиков
- для определённого сегмента пользователей
- или даже для одного конкретного юзера
Больше никаких флагов "для всех сразу". Больше никаких костылей с разветвлённой логикой в коде.
Ты задаёшь правила, а .NET сам обрабатывает таргетинг.
А если совместить это с версионированием API, то получаешь полный контроль над тем, кто и когда увидит новое поведение.
Feature flags — это не просто переключатель кода. Это инструмент доставки продукта.
👉 @KodBlog
if?Есть решение получше.
В .NET есть отличная поддержка feature flags, и что важнее - таргетированных feature flags
Это значит, что можно включать функциональность:
- только для внутренних тестировщиков
- для определённого сегмента пользователей
- или даже для одного конкретного юзера
Больше никаких флагов "для всех сразу". Больше никаких костылей с разветвлённой логикой в коде.
Ты задаёшь правила, а .NET сам обрабатывает таргетинг.
А если совместить это с версионированием API, то получаешь полный контроль над тем, кто и когда увидит новое поведение.
Feature flags — это не просто переключатель кода. Это инструмент доставки продукта.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤3🔥2❤🔥1
dotnet-backend-blueprint.zip
63.6 KB
Устал каждый раз собирать .NET-проекты с нуля?
Есть готовый blueprint для .NET backend, в котором уже настроены 12 продакшен-фич:
- Современный .NET 9 Web API
- Архитектура Vertical Slice
- PostgreSQL + Entity Framework Core
- Преднастроенная аутентификация через Keycloak
- Swagger UI с поддержкой авторизации для интерактивного тестирования
- Глобальная обработка ошибок
- Локальная разработка с .NET Aspire без лишних танцев
- Интеграционные тесты на Test Containers
- Деплой на Azure в продакшн
- CI/CD пайплайны для GitHub Actions и Azure DevOps
- Поддержка GitHub Codespaces
- Шаблон dotnet new готов к установке
Это не очередной "Hello World". Это полноценный продакшен-бэкенд, который обычно занимает у разработчиков недели настройки.
Собран на Vertical Slice Architecture, потому что чистый код важнее, чем следование устаревшим слоёным паттернам.
Честно, если делаешь простые CRUD-приложения, это перебор. Но если нужен API, готовый к продакшену без мучений на старте этот шаблон сэкономит тебе 40+ часов.
👉 @KodBlog
Есть готовый blueprint для .NET backend, в котором уже настроены 12 продакшен-фич:
- Современный .NET 9 Web API
- Архитектура Vertical Slice
- PostgreSQL + Entity Framework Core
- Преднастроенная аутентификация через Keycloak
- Swagger UI с поддержкой авторизации для интерактивного тестирования
- Глобальная обработка ошибок
- Локальная разработка с .NET Aspire без лишних танцев
- Интеграционные тесты на Test Containers
- Деплой на Azure в продакшн
- CI/CD пайплайны для GitHub Actions и Azure DevOps
- Поддержка GitHub Codespaces
- Шаблон dotnet new готов к установке
Это не очередной "Hello World". Это полноценный продакшен-бэкенд, который обычно занимает у разработчиков недели настройки.
Собран на Vertical Slice Architecture, потому что чистый код важнее, чем следование устаревшим слоёным паттернам.
Честно, если делаешь простые CRUD-приложения, это перебор. Но если нужен API, готовый к продакшену без мучений на старте этот шаблон сэкономит тебе 40+ часов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥2👏1
Разница между
🔸
- Пишется проще
- Загружает все совпавшие ID в память
- Тормозит на больших таблицах (например, Customers)
- Может плохо работать без индексов
- В случае
🔸
- Останавливается на первом совпадении
- Лучше дружит с индексами
- Эффективнее при коррелированных подзапросах
- Корректно обходит
- По производительности
- На маленьких выборках: разница минимальна
- На больших: чаще выигрывает
- В коррелированных подзапросах: почти всегда лучше
Современные оптимизаторы умеют уравнивать разницу, но понимать это полезно при работе с реальными данными.
👉 @KodBlog
IN и EXISTS в SQL:IN- Пишется проще
- Загружает все совпавшие ID в память
- Тормозит на больших таблицах (например, Customers)
- Может плохо работать без индексов
- В случае
NOT IN падает, если подзапрос возвращает NULLEXISTS- Останавливается на первом совпадении
- Лучше дружит с индексами
- Эффективнее при коррелированных подзапросах
- Корректно обходит
NULL- По производительности
- На маленьких выборках: разница минимальна
- На больших: чаще выигрывает
EXISTS- В коррелированных подзапросах: почти всегда лучше
EXISTSIN должен вычислить и сохранить весь результат подзапроса.EXISTS просто проверяет — существует ли строка, и идёт дальше.Современные оптимизаторы умеют уравнивать разницу, но понимать это полезно при работе с реальными данными.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤6🍌2
В dotnet 9 появился обобщённый
Во многих случаях нужно хранить пары ключ-значение с сохранением порядка и быстрым поиском по ключу. Теперь это можно делать с помощью обобщённого
👉 @KodBlog
OrderedDictionary Во многих случаях нужно хранить пары ключ-значение с сохранением порядка и быстрым поиском по ключу. Теперь это можно делать с помощью обобщённого
OrderedDictionary в .NET 9.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤3🔥1
С неявными преобразованиями в
👉 @KodBlog
Span<T> в .NET 10 теперь можно передавать массивы напрямую в методы, которые ожидают Span<T> или ReadOnlySpan<T>, без вызова .AsSpan(). Это делает высокопроизводительный код без аллокаций чище и безопаснее. Очень удобноPlease open Telegram to view this post
VIEW IN TELEGRAM
👍6😁4🔥2❤1
Dictionary Expressions в C#?
Сейчас это предложение в статусе champion (ссылка ниже) и продолжение фичи Collection Expressions из C# 12.
Что думаете?👎 или 👍
Предложение Dictionary Expressions
👉 @KodBlog
Сейчас это предложение в статусе champion (ссылка ниже) и продолжение фичи Collection Expressions из C# 12.
Что думаете?
Предложение Dictionary Expressions
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40🥴9👎5❤2🤔2
Большинство разработчиков используют Code-First или Database-First подход в EF Core.
Но немногие знают про Model-First
Database-First позволяет быстро сгенерировать модель из уже существующей базы.
Code-First даёт возможность строить базу данных из C#-классов и управлять схемой через миграции.
Однако оба подхода могут замедлять разработку, если приходится вручную настраивать сложные сущности и связи.
Есть более эффективный и современный вариант — Model-First.
Вместо ручного написания моделей и конфигураций вы проектируете их визуально.
Эти визуальные модели автоматически преобразуются в сущности EF Core и схемы базы данных.
Одним из лучших инструментов для Model-First является Entity Developer от Devart.
Он делает моделирование сущностей простым и удобным.
С помощью drag-and-drop интерфейса не нужно писать классы и вручную задавать связи.
– Меньше времени на шаблонный код и повторяющиеся конфигурации
– Быстрая генерация и обновление моделей по сравнению с ручным кодом
– Меньше риска ошибок рантайма из-за неверных маппингов или конфигураций
– Entity Developer генерирует корректный код и SQL-скрипты за вас
Вот гайд по тому, как именно это реализовать:
- Начало работы: создание EF Core модели для PostgreSQL
- Визуальное проектирование модели данных
- Генерация SQL-скриптов для PostgreSQL
- Автоматизация генерации кода EF Core
- Основные преимущества для разработки на EF Core + PostgreSQL
👉 @KodBlog
Но немногие знают про Model-First
Database-First позволяет быстро сгенерировать модель из уже существующей базы.
Code-First даёт возможность строить базу данных из C#-классов и управлять схемой через миграции.
Однако оба подхода могут замедлять разработку, если приходится вручную настраивать сложные сущности и связи.
Есть более эффективный и современный вариант — Model-First.
Вместо ручного написания моделей и конфигураций вы проектируете их визуально.
Эти визуальные модели автоматически преобразуются в сущности EF Core и схемы базы данных.
Одним из лучших инструментов для Model-First является Entity Developer от Devart.
Он делает моделирование сущностей простым и удобным.
С помощью drag-and-drop интерфейса не нужно писать классы и вручную задавать связи.
– Меньше времени на шаблонный код и повторяющиеся конфигурации
– Быстрая генерация и обновление моделей по сравнению с ручным кодом
– Меньше риска ошибок рантайма из-за неверных маппингов или конфигураций
– Entity Developer генерирует корректный код и SQL-скрипты за вас
Вот гайд по тому, как именно это реализовать:
- Начало работы: создание EF Core модели для PostgreSQL
- Визуальное проектирование модели данных
- Генерация SQL-скриптов для PostgreSQL
- Автоматизация генерации кода EF Core
- Основные преимущества для разработки на EF Core + PostgreSQL
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥5👏1
Всё, что нужно, чтобы запустить реальный продукт
1. Аутентификация → [ASP .NET Core Identity]
2. База данных → [EF Core + SQL Server/PostgreSQL]
3. Платежи → [Stripe, PayPal]
4. Безопасность → [FluentValidation, OWASP]
5. Фронтенд → [Next.js + Shadcn/UI]
6. Бэкенд → [ASP .NET Core Web API]
7. Уведомления → [SendGrid, SignalR]
8. Наблюдаемость → [Application Insights, Serilog, OpenTelemetry]
Надёжный фундамент превращает идеи в работающие продукты.
👉 @KodBlog
1. Аутентификация → [ASP .NET Core Identity]
2. База данных → [EF Core + SQL Server/PostgreSQL]
3. Платежи → [Stripe, PayPal]
4. Безопасность → [FluentValidation, OWASP]
5. Фронтенд → [Next.js + Shadcn/UI]
6. Бэкенд → [ASP .NET Core Web API]
7. Уведомления → [SendGrid, SignalR]
8. Наблюдаемость → [Application Insights, Serilog, OpenTelemetry]
Надёжный фундамент превращает идеи в работающие продукты.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤4
Какой способ пагинации лучше использовать?
Это зависит от данных.
Offset-пагинация используется по умолчанию: пропускаешь X строк, берёшь следующие Y.
Нормально для небольших выборок или неглубоких страниц, но чем дальше идёшь, тем медленнее работает.
Keyset (или cursor) пагинация лучше подходит для больших или часто обновляемых данных.
Вместо пропуска строк она «ищет» последнюю известную позицию (например, ID или timestamp) и оттуда достаёт следующую страницу.
Это быстрее, стабильнее и отлично работает для таких случаев, как:
- бесконечный скролл
- ленты активности
- почтовые ящики
Если делаешь что-то похожее, может помочь эта статья
А ты в своём проекте что используешь ?
offset - 👍 или keyset -❤️
👉 @KodBlog
Это зависит от данных.
Offset-пагинация используется по умолчанию: пропускаешь X строк, берёшь следующие Y.
Нормально для небольших выборок или неглубоких страниц, но чем дальше идёшь, тем медленнее работает.
Keyset (или cursor) пагинация лучше подходит для больших или часто обновляемых данных.
Вместо пропуска строк она «ищет» последнюю известную позицию (например, ID или timestamp) и оттуда достаёт следующую страницу.
Это быстрее, стабильнее и отлично работает для таких случаев, как:
- бесконечный скролл
- ленты активности
- почтовые ящики
Если делаешь что-то похожее, может помочь эта статья
А ты в своём проекте что используешь ?
offset - 👍 или keyset -❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤8
Похоже, ты пропустил эти два типа коллекций.
Стоит о них знать, потому что…
Frozen collections — это новые коллекции, которые на 100% неизменяемы.
Но разве в .NET уже нет read-only и immutable коллекций?
Есть, но нюанс вот в чём…
Read-only коллекция может поменяться, если изменить исходную структуру данных.
Immutable коллекция при изменении создаёт новую копию оригинала с новыми значениями.
И вот тут проблема.
Frozen collections работают иначе.
После создания их изменить нельзя + у них вообще нет методов модификации.
На данный момент доступны только два типа:
- FrozenDictionary
- FrozenSet
Это абстрактные классы, их нельзя создать напрямую, как обычные Dictionary или Set.
Но можно использовать extension-методы.
Их стоит применять там, где коллекция редко создаётся, но часто используется.
Они оптимизированы под:
- быстрый доступ по ключу
- эффективное использование памяти
- потокобезопасность
Минус — более медленное создание.
Но, на мой взгляд, это вполне оправдано с учётом получаемых оптимизаций. Cогласны?👍
👉 @KodBlog
Стоит о них знать, потому что…
Frozen collections — это новые коллекции, которые на 100% неизменяемы.
Но разве в .NET уже нет read-only и immutable коллекций?
Есть, но нюанс вот в чём…
Read-only коллекция может поменяться, если изменить исходную структуру данных.
Immutable коллекция при изменении создаёт новую копию оригинала с новыми значениями.
И вот тут проблема.
Frozen collections работают иначе.
После создания их изменить нельзя + у них вообще нет методов модификации.
На данный момент доступны только два типа:
- FrozenDictionary
- FrozenSet
Это абстрактные классы, их нельзя создать напрямую, как обычные Dictionary или Set.
Но можно использовать extension-методы.
Их стоит применять там, где коллекция редко создаётся, но часто используется.
Они оптимизированы под:
- быстрый доступ по ключу
- эффективное использование памяти
- потокобезопасность
Минус — более медленное создание.
Но, на мой взгляд, это вполне оправдано с учётом получаемых оптимизаций. Cогласны?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤5
Вот подробное руководство для C#-разработчиков по созданию и работе с серверами Model Context Protocol (MCP). Это практический материал для изучения MCP и интеграции AI-ассистентов в .NET-среде.
В .net 10 сервер MCP можно сделать за 20 строк кода — чек
👉 @KodBlog
В .net 10 сервер MCP можно сделать за 20 строк кода — чек
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - microsoft/lets-learn-mcp-csharp
Contribute to microsoft/lets-learn-mcp-csharp development by creating an account on GitHub.
❤8🔥1