C# Portal | Программирование
15K subscribers
755 photos
86 videos
19 files
666 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
В любом проекте важен контекст задачи.

Поэтому в моей архитектуре используется:

Подход с организацией по фичам

Классическая структура кода обычно строится вокруг технических паттернов:

- Command
- Queries
- Events

Из-за этого возникает серьёзная проблема — по коду непонятно, чем реально занимается приложение.

Подход с организацией по фичам полностью меняет эту логику.

Приложение структурируется вокруг бизнес-возможностей и фич.

Цель простая — проект должен «кричать» о своём назначении:

- Пользователи
- Заказы
- Продукты

Почему такая трансформация важна?

1. Высокая связанность внутри фич.
2. Низкая связанность между фичами.
3. Архитектура сама документирует себя.
4. Логичная и удобная навигация по проекту.

А что выберешь ты? 🌟

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Это настоящий кладезь годных бесплатных инструментов для разработчиков.

Здесь есть всё: хостинг, базы данных, CDN, API, домены и куча других полезностей. Всё аккуратно разделено по категориям, что помогает легко находить нужное

https://free-for.dev/#/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Запуск .NET в браузере без Blazor

https://andrewlock.net/running-dotnet-in-the-browser-without-blazor/

В этой статье автор показывает, как запустить .NET в браузере без использования Blazor, а вместо этого опереться на более низкоуровневые абстракции, которые предоставляют [JSImport] и [JSExport].

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥105👍2
В .NET долгое время одним из самых удобных инструментов для организации CQRS и разделения логики был MediatR, он помогал структурировать команды и запросы, разгружал API слой и снижал связанность кода. Многие проекты, особенно с архитектурой Vertical Slice, держались на нём годами.

Но в работе со сложными сценариями у MediatR есть нюанс. Из-за отвязки команд и обработчиков навигация по коду и отладка становятся менее очевидными, особенно когда один обработчик начинает вызывать другой.

Альтернатива, которая решает эти проблемы, — переход на простые ручные обработчики. Такой подход убирает лишнюю рефлексию и декораторы, упрощает трассировку, а IDE быстрее находит нужный участок кода.

Вот гайд как выстроить систему, где:

> Стартовая реализация использует MediatR, а затем заменяется на ручные обработчики

> Регистрация обработчиков происходит автоматически

> Уведомления обрабатываются без MediatR Notifications

> Общая функциональность (логирование, валидация, транзакции) подключается без лишней обвязки

В результате получается решение с теми же преимуществами в архитектуре, но с более прямым и прозрачным кодом, что особенно полезно для крупных и долгоживущих проектов.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥96
image_2025-08-14_11-10-45.png
1.7 MB
Примеры middleware для ограничения частоты запросов в ASP .NET

1. Fixed Window Limiter (20 запросов за 2 минуты)
Фиксированное временное окно. После достижения лимита блокирует все запросы до конца текущего окна. Лимит сбрасывается каждые 2 минуты.

2. Sliding Window Limiter (20 запросов за 2 минуты, 4 сегмента)
Делит окно на сегменты (в примере 4 сегмента по 30 секунд). Когда открывается новый сегмент, самый старый истекает. Это распределяет нагрузку более равномерно и сглаживает трафик.

3. Token Bucket Limiter (15 токенов максимум, пополнение 1 токен/сек)
Позволяет кратковременные всплески нагрузки за счёт накопленных токенов. Каждый запрос расходует токен, при их нехватке запросы ограничиваются до восстановления токенов (по 1 в секунду).

4. Concurrency Limiter (5 параллельных запросов, 10 в очереди)
Ограничивает число одновременно обрабатываемых запросов (в примере до 5). Остальные попадают в очередь (до 10). Если очередь переполнена, новые запросы возвращают 503 или 429 (если переопределено).

В коде эти лимитеры регистрируются в AddRateLimiter() и привязываются к конкретным эндпоинтам через .RequireRateLimiting()

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11👏32🔥1
Как находить медленные запросы в Entity Framework

Используя систему перехватчиков Entity Framework и подключаясь к событию ReaderExecuted мы можем видеть сколько времени реально занимают запросы

Сохрани в закладки 🧀

public class SlowQueryInterceptor : DbCommandInterceptor
{
private const int _slowQueryThreshold = 200; // миллисекунды

public override DbDataReader ReaderExecuted(
DbCommand command,
CommandExecutedEventData eventData,
DbDataReader result)
{
if (eventData.Duration.TotalMilliseconds > _slowQueryThreshold)
{
// Логируем медленный запрос — тут можно вставить свою систему логирования
Console.WriteLine(
$"Slow query ({eventData.Duration.TotalMilliseconds} ms): {command.CommandText}");
}

return base.ReaderExecuted(command, eventData, result);
}
}

public class YourDbContext : DbContext
{
// ... твои DbSet ...

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("YourConnectionString") // замени на свою строку подключения
.AddInterceptors(new SlowQueryInterceptor());
}
}


Как это работает

1. Создаём класс перехватчика, наследуемся от DbCommandInterceptor и реализуем метод ReaderExecuted

2. Регистрируем этот перехватчик в контексте через AddInterceptors

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍202
Изоляция данных в модульном монолите

- Схема и роль на модуль — для каждого модуля создаётся собственная схема и роль
- Привилегии только для своей схемы — модуль не имеет доступа к данным других схем
- Отдельный DbContext + схема по умолчанию — разделение кода и данных на уровне ORM
- Разные строки подключения и миграции — независимое управление конфигурацией и развёртыванием
- Read-only представления для межмодульных запросов — безопасный доступ к данным между модулями

Смотрите пошаговое руководство: ссылка

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Сохрани этот пост

Покажу репозиторий на GitHub, где есть 99% кода, который тебе нужен для разработки

485 примеров кода .NET в одном месте 🙏

Репозиторий называется:

practical-aspnetcore — https://github.com/dodyg/practical-aspnetcore

В одном месте собрано 485 практических примеров, чтобы ты мог понять и эффективно внедрить ключевые возможности ASP .NET Core

Что покрыто:

Authentication

Blazor

Caching

Email

gRPC

HealthCheck

Localization

Logging

Middleware

Minimal API

Open Telemetry

Routing

SignalR

Security

YARP


Это, по сути, швейцарский нож для .NET - инструменты почти для любой ситуации

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍164🔥4😁1
Что такое RBAC и как это помогает с авторизацией

RBAC расшифровывается как Role-Based Access Control, то есть управление доступом на основе ролей

Суть простая

• У ролей есть набор разрешений
• Пользователи получают роли
• Разрешения определяют, что пользователи могут делать

Всё довольно просто, но при этом мощно

Хотя сами по себе роли могут быть слишком широкими

Поэтому я предпочитаю комбинировать роли с более точечными разрешениями.
Вместо того чтобы хардкодить правила доступа, я привязываю разрешения к конкретным действиям и уже потом связываю эти разрешения с ролями

Так проще управлять и легче расширять

Как смоделировать такой подход и применить его в .NET — читать

А как у тебя сейчас устроена авторизация в системе 😏

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥4👍32🔥2
Я отучаюсь от всего, что знал про юнит-тестирование

Потому что большая часть этого — неправда

Для юнит-тестов нужен mocking-фреймворк

Юнит-тест должен покрывать один метод

С EF Core обязательно использовать Repository-паттерн для тестирования

Если всё это совместить, получаются хрупкие тесты, которые ничего не говорят о требованиях и вынуждают плодить ненужные слои

Вместо этого я придерживаюсь простых правил

• Использовать фейки вместо mocking-фреймворка
• Юнит-тесты проверяют поведение, а не структуру
• При работе с EF Core использовать in-memory или SQLite провайдер и обходить их ограничения через интеграционные тесты

Так тесты становятся менее хрупкими, покрывают больше кода и требуют меньше поддержки

Кто со мной?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53😁1🤔1
Предпочитай string.Equals вместо ToLower / ToUpper для нечувствительных к регистру сравнений строк

1. Корректность (например, проблема с турецкой буквой i)

2. Читаемость

3. Производительность

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103🔥2👏1
Нужны пиксельно идеальные PDF-отчёты в .NET?

Забей на проприетарные библиотеки, используй HTML-шаблоны и PuppeteerSharp.

Собери отчёт как HTML-шаблон на Handlebars, подставь данные, а потом отрендерь в PDF через headless-браузер.

Учись генерировать удобные и красивые PDF-отчёты с Handlebars.NET и PuppeteerSharp — гайд Милана

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍4
Вызов Azure Function из Azure SQL DB

Да, это реально. Хранимая процедура sp_invoke_external_rest_endpoint позволяет дергать HTTPS REST endpoint, переданный ей в качестве аргумента.

Кто-то уже пробовал?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2🤔2🎉2
Пример локальной функции в C#

Кто-нибудь вообще юзает их для мелкой логики?

Гайд: ссылка

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🤔3🍌2🤨1
Лучшая техника dependency injection, которой почти никто не пользуется
(больше никаких конструкторов на 10 строк)

Используй Method Injection

Это малоизвестная фича в ASP.NET Core, которая позволяет инжектить зависимости прямо в метод эндпоинта

Для этого можно использовать [FromServices] IYourService
Но [FromServices] можно и не указывать

Когда это уместно

• Когда сервис нужен только в одном экшене
• Когда конструктор превращается в лапшу
• Когда сервис тяжёлый и хочется лучше контролировать память

Да, constructor injection по умолчанию — это стандартный подход

Но method injection — это удобный инструмент, если хочется делать более мелкие сервисы, которые соблюдают принцип единственной ответственности, и при этом иметь контроллеры, не превращённые в свалку зависимостей

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤‍🔥2😁2
Rider 2025.2 теперь с расширенной поддержкой C# 14

Теперь доступны все свежие фичи языка:

> Extensions
> Partial events и конструкторы
> Null-conditional assignments

Плюс обновления анализа кода в Rider 2025.2 : подробнее

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍115
Твой опыт с NuGet в .NET ограничивается AutoMapper?

Быть в курсе .NET = быть в курсе инструментов.

Не отставай — вот 24 NuGet-библиотеки

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥1
Когда исключения неизбежны, нужен механизм для их обработки.

Вот как это можно настроить за несколько минут:

Начиная с .NET 8 у вас есть интерфейс IExceptionHandler

Это абстракция для управления исключениями с одним методом: TryHandleAsync

Он отвечает за обработку исключений в пайплайне ASP.NET Core.

Метод возвращает true, если исключение обработано успешно, и false, если его нельзя обработать.

Это позволяет реализовать кастомную логику под разные сценарии.

Для конфигурации нужно сделать три шага:

1. Зарегистрировать сервис IExceptionHandler через dependency injection
2. Зарегистрировать ExceptionHandlerMiddleware в пайплайне запросов
3. Зарегистрировать ProblemDetails ответ

Третий шаг опционален, но я настоятельно рекомендую его использовать, чтобы ошибки были более читаемыми.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43
Хочешь писать более чистый C#-код?

Начни с чистых функций.

Чистая функция проста:
Берёт входные данные, возвращает результат и больше ни на что не влияет.

Никаких запросов в базу. Никаких случайных значений. Никаких скрытых побочных эффектов

Такой код легче тестировать, отлаживать и ему проще доверять.

Если логика кажется непредсказуемой — попробуй вынести её в чистую функцию.
Удивишься, насколько всё станет понятнее.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7