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

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
Рендеринг шаблона в PDF с помощью PuppeteerSharp:

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍3🤔1
Первичные конструкторы в dotnet

ДО .NET 8 (Традиционный подход с конструктором):

public class UserService
{
private readonly HospitalDBContext _dbContext;
private readonly ILogger<UserService> _logger;
private readonly IEmailService _emailService;

public UserService(
HospitalDBContext dbContext,
ILogger<UserService> logger,
IEmailService emailService)
{
_dbContext = dbContext;
_logger = logger;
_emailService = emailService;
}

// Методы бизнес-логики здесь...
}


ПОСЛЕ .NET 8 (Использование Primary Constructor):

public class UserService(
HospitalDBContext _dbContext,
ILogger<UserService> _logger,
IEmailService _emailService)
{
// Методы бизнес-логики здесь...
}


Круто или нет?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19🤨76🐳2😁1
Не совершайте эту ошибку

Не используйте .ToLower() для сравнения строк. Почему?

Метод .ToLower() создаёт новую строку в памяти для каждого сравнения, что приводит к лишним аллокациям.

Представьте метод, который вызывается очень часто — это может деградировать производительность приложения.

Кроме того, .ToLower() чувствителен к культуре, то есть результат может различаться в зависимости от текущей культуры, установленной в исполняющем потоке.

Что использовать вместо этого?

В .NET есть мощное перечисление — StringComparison.

Возможные варианты StringComparison:

- Ordinal — используйте в большинстве случаев, когда культурные правила не важны. Самый быстрый вариант.
- OrdinalIgnoreCase — для сравнений без учёта регистра, где культурные правила не имеют значения.
- CurrentCulture и CurrentCultureIgnoreCase — используйте при сравнении строк, отображаемых пользователю, так как они учитывают культурные правила.
- InvariantCulture и InvariantCultureIgnoreCase — подходят, когда нужна единообразная логика вне зависимости от культуры, например, при сохранении и извлечении данных.

> EF Core выбросит исключение, если использовать методы вроде
> String.Equals(string, StringComparison), так как они не транслируются в SQL.

Это не будет работать с EF.
Если вы используете SQL Server с коллацией по умолчанию, сравнение строк уже нечувствительно к регистру, поэтому обычное a == b или string.Equals(a, b) в LINQ будет работать.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍303
Посмотрите этот классный open-source инструмент для визуализации JSON-данных в интерактивных графах.

Он предлагает функции конвертации JSON в другие форматы (CSV, YAML), генерацию JSON Schema, выполнение запросов и экспорт визуализаций в виде изображений.

Также он умеет форматировать, валидировать и создавать интерфейсы TypeScript.

Репозиторий: https://github.com/AykutSarac/jsoncrack.com

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍138🥴2
Что нового в C# 14

Главные апдейты

Extension members теперь можно расширять не только методами но и свойствами и индексаторами плюс есть статические расширения для самого типа.

field как контекстный токен для простых автосвойств с логикой сеттера без явного бэкинг филда.

Условный доступ слева от присваивания то есть ?. и ?[] можно ставить перед тем что присваиваешь удобно и безопасно.

nameof понимает «пустой» дженерик тип например nameof(List<>).

Модификаторы у параметров простых лямбд ref, in, out, scoped теперь можно без явного типа.

Больше не мучаемся со Span<T> и ReadOnlySpan<T> стало больше неявных конверсий и это лучше дружит с инференсом и экстеншенами.

Больше partial теперь можно частично объявлять конструкторы и события.

Пользовательские составные операторы присваивания то есть можно задавать свою семантику для вроде +=.

Пара мини примеров

field в действии

public class Box
{
public string Title
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
}


Условное присваивание

customer?.Order = FetchOrder();
bag?["count"] += 1;


nameof с незаполненным дженериком

var n = nameof(List<>); // "List"


Модификатор у лямбды без явных типов

delegate void Bump(ref int x);
Bump inc = (ref x) => x++;


Как попробовать


Ставишь свежий .NET 10 SDK и актуальный Visual Studio 2022 эти фичи уже в превью ветки для десятки. Страница с новыми фичами обновлялась под .NET 10 Preview 1 в апреле 2025.

🔸подробнее - https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
14😁1
Лучший урок по C# за сегодня

(чтобы срезать количество багов примерно на 50%)

Не возвращайте из методов null для коллекций

Возвращайте пустые коллекции

STOP:
- Заставлять вызывающий код проверять null
- Захламлять код лишними условиями
- Рисковать трудноотлавливаемыми runtime-исключениями

Начните:
- Возвращать new List<T>()
- Возвращать Enumerable.Empty<T>()
- Возвращать [] (фича C# 12 — collection expression)

Так пишется безопасный, чистый и читаемый код

Пусть остальные продолжают тонуть в проверках на null 👍

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🕊75🐳1
Джуниор должен знать 4 паттерна

Мидл — уже 12

Сеньор — около 20


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

Задумывался, на какие паттерны стоит делать упор, когда растешь как разработчик? 🌟

Это реально разница между «писать неплохой код» и «строить крутое ПО»

🔸Джуниор

Тебе не нужно сразу выучить всё.
Сконцентрируйся на базовых паттернах, которые встречаются повсюду

> Builder
> Factory Method
> Singleton
> Decorator

Эти четыре паттерна помогут эффективно создавать, организовывать и расширять объекты.
Освоишь их — с первого дня начнешь писать чище и гибче

🔸Мидл

Готов прокачаться дальше

Пора добавить в свой арсенал более универсальные инструменты

> Strategy
> Adapter
> Abstract Factory
> Template Method
> Facade
> Bridge
> Command
> Mediator

Они научат подменять поведение на лету, упрощать сложные системы и писать более модульный код

🔸Сеньор

Базу ты уже знаешь.
Теперь можно разбираться с паттернами, которые решают самые жёсткие архитектурные задачи

> Prototype
> Composite
> Chain of Responsibility
> State
> Flyweight
> Proxy
> Visitor
> Interpreter

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

Не пытайся выучить всё за раз

Иди по порядку — сначала базу, потом средний уровень, потом продвинутые паттерны

Кстати, а у тебя какой паттерн дольше всего не заходил, и как ты в итоге его понял? 👀

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤨1512👍6😁2🤣1
Паттерн Options в .NET — это одна из тех фич, которые я стабильно использую во всех своих C#-проектах

Более чистое управление конфигами
Сильно типизированные классы
Простая интеграция с DI
Без проблем работает с appsettings.json, secrets.json, Azure Key Vault и прочим

Почему это важно

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

Обычно это выглядит так

🔹Определяешь конфиг в appsettings.json
🔹Создаёшь POCO-класс
🔹Биндишь его через .AddOptions<T>().BindConfiguration()
🔹Инжектишь в сервисы через IOptions<T>

Просто. Масштабируемо. Аккуратно.

А ты используешь этот паттерн у себя или до сих пор дёргаешь значения конфигов через IConfiguration["key"] 😃

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
26👍6🍓3👨‍💻1
В любом проекте важен контекст задачи.

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

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

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

- Command
- Queries
- Events

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

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

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

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

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

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

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

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥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
👍9👏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
👍191
Изоляция данных в модульном монолите

- Схема и роль на модуль — для каждого модуля создаётся собственная схема и роль
- Привилегии только для своей схемы — модуль не имеет доступа к данным других схем
- Отдельный 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
👍154🔥4😁1
Что такое RBAC и как это помогает с авторизацией

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

Суть простая

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

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

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

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

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

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

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3👍21🔥1
Forwarded from Сазонов о Web
🎁 РОЗЫГРЫШ ПРИЗОВ 🎁

🤩 Nintendo Switch, оригинальный Labubu и Робот-доставщик на пульте управления: разыгрываем среди подписчиков!

Все что нужно сделать:

1. ПОДПИСАТЬСЯ на все каналы:

Сазонов о Web

Путь Инди

MZGames

Платонов Девелопер

Тот самый Алекс из Appwill

Инди Андрюша | GameDev

Kozlov Dev - Разработка игр

Baxx Studio | Unity GameDev

Savely Teplov | Welwise Universe

Владислав Сухацкий - GameDev Блог

2. Нажать на кнопку «УЧАСТВУЮ» под постом

❗️ Победителя определим 22 августа в 19:00 мск на стриме! Итоги также появятся в телеграм-каналах.

Победителей выберем случайно с помощью бота. Важно быть подписанным на все каналы.

P.S. Все каналы по геймдеву
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣7🤯2😐2🥴1
Я отучаюсь от всего, что знал про юнит-тестирование

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

Для юнит-тестов нужен 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
👍82