fa
Feedback
C# 1001 notes

C# 1001 notes

رفتن به کانال در Telegram

Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp

نمایش بیشتر
6 549
مشترکین
+324 ساعت
+77 روز
+830 روز
آرشیو پست ها
⚡️ Что происходит внутри инфраструктурных сервисов Yandex Cloud? Разработчики Yandex Cloud и Yandex Infrastructure расскажут
⚡️ Что происходит внутри инфраструктурных сервисов Yandex Cloud? Разработчики Yandex Cloud и Yandex Infrastructure расскажут об этом на встрече для разработчиков, архитекторов и инженеров, которая пройдет 16 апреля. В программе вас ждут реальные технические варианты реализации и опыт нетривиальных решений разработчиков платформы: — Инфраструктура как код для управления оповещениями: и никаких проблем — Развёртывание в ритме танго: как мы заменили оркестрацию процесса установки «хореографией» — Как мы оптимизируем вывод больших языковых моделей: кэширование, время отклика и ресурсы графических ускорителей — Как мы строили собственную сеть доставки контента и через что нам пришлось пройти? — Как мы работаем с уязвимостями на примере современных аппаратных атак Также команда расскажет о разработке программных решений, которые устанавливаются в инфраструктуре заказчика, и о том, как в процессе установки оркестрацию заменили «хореографией». Участники смогут обсудить волнующие вопросы, варианты реализации и ошибки с разработчиками сервисов Yandex Cloud и другими участниками. Встреча пройдет офлайн в Москве и онлайн. Помимо экспертных докладов, офлайн участников ждут секретная техническая сессия и развлекательная программа, а онлайн-участников ждёт инженерное соревнование в прямом эфире. Зарегистрируйтесь, чтобы послушать реальные истории от разработчиков, обменяться опытом и узнать, что скрыто под «капотом» инфраструктурных сервисов, а также какие планы у команды на будущее.

Полезный паттерн для Minimal APIs в .NET, если вы хотите организовать проект по принципу Vertical Slice Architecture. Идея оч
Полезный паттерн для Minimal APIs в .NET, если вы хотите организовать проект по принципу Vertical Slice Architecture. Идея очень простая. Вместо того чтобы держать все роуты в Program.cs, каждый endpoint выносится в отдельный класс. Создаётся небольшой интерфейс:

public interface IEndpoint
{
    void MapEndpoint(IEndpointRouteBuilder app);
}
Дальше каждый endpoint просто реализует этот интерфейс:

public class GetFollowerStats : IEndpoint
{
    public void MapEndpoint(IEndpointRouteBuilder app)
    {
        app.MapGet("users/{userId}/followers/stats", async (
            Guid userId,
            ISender sender) =>
        {
            var query = new GetFollowerStatsQuery(userId);

            Result<FollowerStatsResponse> result = await sender.Send(query);

            return result.Match(Results.Ok, CustomResults.Problem);
        })
        .WithTags(Tags.Users);
    }
}
Что это даёт: • endpoints изолированы по фичам • код становится намного чище • проще масштабировать API • удобно использовать вместе с CQRS / MediatR Регистрация таких endpoints занимает буквально пару миллисекунд при старте приложения. Отличный способ держать Minimal API структурированным даже в больших проектах.

Vector Search - как это работает (и почему это важно для .NET разработчиков) Vector search ищет смысловую близость, а не прос
Vector Search - как это работает (и почему это важно для .NET разработчиков) Vector search ищет смысловую близость, а не просто точные совпадения. Он сравнивает данные - текст, изображения или аудио - используя векторные эмбеддинги в многомерном пространстве. То есть система ищет не одинаковые слова, а похожие по смыслу объекты. Почему это важно? Vector search лежит в основе многих AI-функций: - семантический поиск - рекомендательные системы - интеграции с LLM - умные ассистенты внутри приложений Добавив векторный поиск в приложение, разработчик может создавать намного более умные продукты, которые понимают смысл запросов пользователя. Это дает реальную бизнес-ценность - от поиска по документам до персонализированных рекомендаций. 📍 Полный пример реализации

🔵Ozon Tech приглашает на Community .NET Meetup 24 марта (вторник) в Москве (Лофт Casa Picassa) и онлайн. В программе три док
🔵Ozon Tech приглашает на Community .NET Meetup 24 марта (вторник) в Москве (Лофт Casa Picassa) и онлайн. В программе три доклада, много кейсов и камерная дискуссия без записи. В фокусе primitive obsession, нагрузка с Load Shedding и Escape Analysis в JIT. За подробной программой и регистрацией — сюда ⬅️

⚡️ Языки программирования и их самые любимые фичи • 🐍 Python - чистый и читаемый синтаксис • 🖥️ BASIC - очень дружелюбен для новичков • 📊 Visual Basic - простое создание GUI • 🟨 JavaScript - запускается везде и сразу • 🐘 PHP - очень простой деплой веб-приложений • 💎 Ruby - красивый и элегантный синтаксис • 🎵 Groovy - бесшовная интеграция с Java • ☕ Java - огромная экосистема и стабильность • 🟣 C# - отличные инструменты и IDE • 🐹 Go - простая и быстрая конкурентность • 🐦 Swift - современный и безопасный дизайн • 🅺 Kotlin - встроенная защита от null • 🎯 Dart - отлично работает с Flutter • 🧮 Fortran - сверхбыстрые научные вычисления • 🔧 C - полный контроль над железом • 🍎 Objective-C - мощная динамическая runtime-система • 🔺 Scala - сочетание функционального и ООП • ⚡ Zig - простой и предсказуемый системный код • 🐪 Perl - невероятно мощная обработка текста • 🚀 C++ - высокая производительность и контроль • 🦀 Rust - безопасность памяти без garbage collector • ⚙️ Assembly - максимальный контроль и производительность

Нам и так нормально.
Нам и так нормально.

В .NET 8 появился простой способ сделать HttpClient устойчивым к сбоям — буквально одной строкой. Microsoft добавила библиоте
В .NET 8 появился простой способ сделать HttpClient устойчивым к сбоям — буквально одной строкой. Microsoft добавила библиотеку Microsoft.Extensions.Http.Resilience, в которой уже есть готовые pipeline’ы для обработки ошибок при HTTP-запросах. Что это даёт из коробки: - Retry при временных сбоях - Timeout - Circuit Breaker - Rate limiting - Защиту от перегрузки Подключается максимально просто:

services.AddHttpClient<GitHubService>(static httpClient =>
{
    httpClient.BaseAddress = new Uri("https://api.github.com/");
})
.AddStandardResilienceHandler();

⚡️ URL shortener за &lt;100 строк на .NET - реально Идея простая: у тебя есть входной URL -&gt; генеришь короткий код -&gt; с
⚡️ URL shortener за <100 строк на .NET - реально Идея простая: у тебя есть входной URL -> генеришь короткий код -> сохраняешь в БД -> по коду делаешь редирект. Что нужно собрать - Генератор уникального кода Делай base62 (0-9, a-z, A-Z) длиной 6-8 символов. Главное - гарантировать уникальность: - либо проверка в БД и повтор генерации при коллизии - либо уникальный индекс по Code и ретрай при ошибке сохранения - База данных Таблица ShortenedUrl: - Id (Guid) - LongUrl (string) - Code (string, unique) - CreatedOnUtc (DateTime) Опционально: - ExpiresOnUtc - Clicks - CreatedByIp - 2 эндпоинта (Minimal API) - POST /shorten - валидируешь URL (Uri.TryCreate) - генеришь code - формируешь shortUrl из scheme + host + code - сохраняешь в БД - возвращаешь shortUrl - GET /{code} - ищешь code в БД - если нет - 404 - если есть - Results.Redirect(LongUrl) Почему чаще всего "падают" такие сервисы - Коллизии кода -> решается unique index + retry - Открытый редирект на мусор -> валидируй UriKind.Absolute и при желании режь опасные схемы (только http/https) - Производительность поиска -> индекс по Code обязателен - Правильный shortUrl за прокси -> если сервис за nginx/cloudflare, учитывай Forwarded Headers, иначе host/scheme будут неправильными Если делать максимально чисто - генератор кода отдельным сервисом, модель + DbContext, и два эндпоинта. Это и укладывается в <100 строк.

🚀 LOAD BALANCER ЗА 1 МИНУТУ Load Balancer - это «диспетчер трафика» между пользователями и серверами. Когда пользователей становится много, один сервер перестаёт справляться: - 500 пользователей — работает нормально - 1 000 — начинает тормозить - 10 000 — может упасть из-за перегрузки Load Balancer распределяет входящие запросы между несколькими серверами, чтобы ни один из них не перегружался. Это повышает производительность и позволяет системе обслуживать больше пользователей. Проблемы без Load Balancer: - Один сервер = одна точка отказа - Любой сбой или проблема с сетью — приложение полностью недоступно - Ограниченная мощность - При росте нагрузки — медленные ответы и падения Как работает Load Balancer: 1. Все запросы сначала попадают в Load Balancer 2. Он проверяет, какие серверы работают и доступны 3. Распределяет трафик по серверам на основе: - текущей нагрузки - времени ответа - доступности 4. Если сервер перестаёт отвечать — трафик автоматически перенаправляется на рабочие В результате: - нагрузка распределяется равномерно - используются только «здоровые» серверы - уменьшаются задержки - система остаётся стабильной Зачем нужен Load Balancer: - Scalability — можно добавлять новые серверы без изменений на стороне клиента - High Availability — если один сервер падает, система продолжает работать - Better Performance — запросы обрабатываются быстрее - Efficient resource usage — равномерное использование ресурсов и отсутствие узких мест Главная идея: Load Balancer — основа масштабируемых и отказоустойчивых систем. Без него любое приложение рано или поздно упрётся в предел одного сервера. Подписывайся, больше фишек каждый день !

// Пример конфигурации Nginx как Load Balancer

http {
    upstream backend {
        server 192.168.1.10;
        server 192.168.1.11;
        server 192.168.1.12;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://backend;
        }
    }
}

👨‍💻 Ручная сборка, деплой по инструкции в Confluence и ночные правки на сервере — частая реальность ASP.NET-проектов. Пока система доставки не автоматизирована, скорость разработки и стабильность всегда под угрозой. На открытом уроке разберём, как выстроить рабочий pipeline от коммита до деплоя. Покажем типовую цепочку: сборка, тесты, упаковка в Docker-образ, публикация в реестр и автоматическое развертывание. ❗️ Вы увидите CI/CD не как абстрактную DevOps-теорию, а как воспроизводимый процесс, который можно применить в собственном проекте. Это фундамент для перехода к микросервисам и контейнерной инфраструктуре без лишней сложности. 🗓 Встречаемся 11 февраля в 20:00 МСК в преддверии старта курса «C# ASP.NET Core-разработчик». ➡️ Регистрация открыта: https://tglink.io/ebe2ec9f037e4d?erid=2W5zFGj7XNQ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru #реклама О рекламодателе

⚡️ Миграция хеширования паролей без поломки логина Ты сделал маленький и вроде бы аккуратный рефакторинг - и сломал весь логи
⚡️ Миграция хеширования паролей без поломки логина Ты сделал маленький и вроде бы аккуратный рефакторинг - и сломал весь логин. Логику хеширования паролей ты аккуратно вынес в отдельный слой. Отлично. А потом решил обновиться — заменить PBKDF2 на bcrypt. Просто поменял реализацию. Казалось бы, безопасно. Но внезапно: - старые пользователи больше не могут войти - пароли перестали совпадать - аутентификация массово падает Ты только что внёс breaking change, даже не заметив этого. Это классическая ловушка в аутентификации — менять алгоритм хеширования без стратегии миграции. Важно понимать: - пароли в базе уже захешированы старым алгоритмом - новый алгоритм не умеет их проверять - простой swap реализации = мгновенный outage - ⚡️Правильный подход: - поддерживать несколько алгоритмов одновременно - определять алгоритм по формату хеша - при успешном логине пересохранять пароль новым алгоритмом - без сброса паролей - без даунтайма Маленькие изменения в use case-ах, особенно в аутентификации, могут иметь огромные последствия.

Есть соглашения по именованию в коде, которые все постоянно нарушают? Имена классов, слоёв, обработчиков, сервисов - это част
Есть соглашения по именованию в коде, которые все постоянно нарушают? Имена классов, слоёв, обработчиков, сервисов - это часть архитектуры. Но обычно всё держится на: • договорённостях в голове • комментариях в Wiki “ну мы же так решили” А потом кто-то добавляет UserCmdHandler, DoStuffManager или NewService2 - и структура просто разваливается. 💡 Решение: архитектурные тесты Вы можете написать тесты, которые проверяют саму архитектуру, а не бизнес-логику. Например:все CommandHandler обязаны заканчиваться на CommandHandler • классы из Application не должны ссылаться на Infrastructure • контроллеры не имеют доступа к репозиториям напрямую DTO не должны жить в доменной модели И если кто-то нарушил правило - тест падает. Сразу. В CI. ⚙️ Что это даёт Архитектура перестаёт быть кривой и косой. Она начинает подчиняться строгим правилам. Новый разработчик в команде может не знать всех договорённостей, но код всё равно останется чистым, потому что правила защищены тестами. 🧠 Главное осознание Архитектурные тесты защищают структуру. А структура - это то, что определяет, станет проект поддерживаемым… или превратится в хаос через год.

🖥 Если ты делаешь бэкенд на .NET и хочешь расти не «по туториалам», а в сторону прод-уровня, архитектуры и реальных систем - это золото. Архитектура и структура проектов N-Layered vs Clean vs Vertical Slice Architecture https://antondevtips.com/blog/n-layered-vs-clean-vs-vertical-slice-architecture Лучшая структура .NET-проектов с Clean Architecture и Vertical Slices https://antondevtips.com/blog/the-best-way-to-structure-your-dotnet-projects-with-clean-architecture-and-vertical-slices Зачем писать архитектурные тесты https://antondevtips.com/blog/why-do-you-need-to-write-architecture-tests-in-dotnet От модульного монолита к микросервисам https://antondevtips.com/blog/migrating-modular-monolith-to-microservices-in-dotnet API и бэкенд-практики Best Practices для REST API https://antondevtips.com/blog/best-practices-for-building-rest-apis 90% API не RESTful - что вы упускаете https://antondevtips.com/blog/90-of-apis-are-not-restful-what-youre-missing-and-when-it-matters Как ускорить Web API https://antondevtips.com/blog/how-to-increase-performance-of-web-apis-in-dotnet Аутентификация и авторизация в ASP.NET Core https://antondevtips.com/blog/authentication-and-authorization-best-practices-in-aspnetcore Интеграционные тесты в ASP.NET Core https://antondevtips.com/blog/asp-net-core-integration-testing-best-practises EF Core и данные Почему не нужен Repository поверх EF Core https://antondevtips.com/blog/why-you-dont-need-a-repository-in-ef-core 5 скрытых NuGet-пакетов для EF Core https://antondevtips.com/blog/5-hidden-efcore-nuget-packages Кеширование в .NET https://antondevtips.com/blog/how-to-implement-caching-strategies-in-dotnet Resilience, инфраструктура, прод Retry и устойчивость с Polly и Microsoft Resilience https://antondevtips.com/blog/how-to-implement-retries-and-resilience-patterns-with-polly-and-microsoft-resilience Загрузка больших файлов в Azure Blob Storage https://antondevtips.com/blog/implementing-large-file-uploads-and-downloads-in-azure-blob-storage-with-dotnet Деплой в Azure с Neon Postgres и .NET Aspire https://antondevtips.com/blog/how-to-deploy-dotnet-application-to-azure-using-neon-postgres-and-dotnet-aspire Job Scheduler TickerQ https://antondevtips.com/blog/tickerq-the-modern-dotnet-job-scheduler-that-beats-quartz-and-hangfire Observability Старт с OpenTelemetry, Jaeger и Seq https://antondevtips.com/blog/getting-started-with-open-telemetry-in-dotnet-with-jaeger-and-seq Код и язык Как писать чище и лучше код в .NET https://antondevtips.com/blog/how-to-write-better-and-cleaner-code-in-dotnet Новые фичи .NET 10 и C# 14 https://antondevtips.com/blog/new-features-in-dotnet-10-and-csharp-14 Extension Members в C# 14 https://antondevtips.com/blog/extension-members-in-csharp14-changed-how-we-write-code-forever Практические проекты Invoice Builder на .NET с IronPDF https://antondevtips.com/blog/how-to-build-a-production-ready-invoice-builder-in-dotnet-using-ironpdf Ошибки разработчиков Top 10 вещей, которые должен делать .NET-разработчик в 2026 https://antondevtips.com/blog/top-10-things-every-dotnet-developer-needs-to-do-in-2026 15 ошибок .NET-разработчиков https://antondevtips.com/blog/top-15-mistakes-dotnet-developers-make-how-to-avoid-common-pitfalls 15 ошибок при создании Web API https://antondevtips.com/blog/top-15-mistakes-developers-make-when-creating-web-apis Это не «почитать на досуге». Это roadmap от уровня “пишу контроллеры” до “проектирую систему, которая живёт в проде годами”.

⚙️ Вы настраиваете ASP.NET Core «по наитию» и тратите время на поиск, почему приложение ведет себя по-разному в продакшене и локально? 📆 29 января в 20:00 OTUS проводит открытый урок «Конфигурирование приложения ASP.NET Core» в преддверии старта курса «C# ASP.NET Core разработчик». На занятии разберем, как выстроить прозрачную и управляемую систему настроек: appsettings.json, провайдеры конфигурации, приоритет применения конфигураций, настройки специфичные для среды и шаблон Options для работы с настройками. Вы поймете, как проектировать конфигурации так, чтобы приложения были стабильными и предсказуемыми. ❗️Урок будет полезен разработчикам ASP.NET Core начального и среднего уровня, которые хотят систематизировать знания и работать по индустриальным стандартам. ➡️ Регистрируйтесь на бесплатный урок: https://tglink.io/0180da777d54?erid=2W5zFH1uFyz 🎁 Все участники открытого урока получат скидку на обучение. #реклама О рекламодателе

✔️ C# может прокачать collection expressions: “аргументы при создании коллекции” Есть прикольное предложение в csharplang: сд
✔️ C# может прокачать collection expressions: “аргументы при создании коллекции” Есть прикольное предложение в csharplang: сделать так, чтобы в collection expressions (`[a, b, c]`) можно было передавать аргументы в создание коллекции. Проблема сейчас: Postgres-стайл удобный синтаксис уже есть: List<int> xs = [1, 2, 3]; Но если тебе важно задать, например, capacity (чтобы не было лишних realloc внутри списка), то приходится писать “старым способом”: var xs = new List<int>(capacity: 32) { 1, 2, 3 }; Предлагаемое решение: добавить возможность передавать аргументы прямо в collection expression: List<int> xs = [args(capacity: 32); 1, 2, 3]; То есть: - args(...) - это аргументы для конструктора / create-метода - после ; - элементы коллекции Зачем это нужно: - можно сохранить суперкороткий синтаксис [ ... ] - но при этом контролировать создание коллекции (capacity, comparer и т.д.) - меньше лишних аллокаций → быстрее в hot-path коде Если фича дойдёт до релиза, это будет реально удобный апгрейд синтаксиса коллекций в C#. https://github.com/dotnet/csharplang/blob/main/proposals/collection-expression-arguments.md

🖥 Многопоточность в .NET часто сводят к lock. Но в реальных системах этого недостаточно — особенно под нагрузкой, в легаси-коде и распределённых сценариях. 📕 На открытом уроке разберём, какие инструменты действительно есть в .NET и как выбирать подходящий примитив под конкретную задачу. Рассмотрим Monitor, Mutex, Semaphore, а также другие примитивы из System.Threading: ReaderWriterLockSlim, Barrier, ManualResetEventSlim, SpinLock. ❗️ Вы увидите практические примеры, типовые ошибки и узнаете, где блокировки становятся узким местом. Урок будет полезен разработчикам, работающим с высоконагруженными системами и легаси-кодом, а также тимлидам, которые проектируют архитектуру и отвечают за производительность. 📣 Встречаемся 27 января в 20:00 МСК в преддверии старта курса «C# Developer. Professional». Регистрация открыта: https://otus.pw/t6Xj/

✅ API Input Validation в .NET: почему FluentValidation лучше, чем Data Annotations Data Annotations отлично подходят для прос
✅ API Input Validation в .NET: почему FluentValidation лучше, чем Data Annotations Data Annotations отлично подходят для простых правил: [Required] - ок [MaxLength(50)] - норм Но как только тебе нужно что-то “умнее”, начинается боль: - проверить данные в базе - валидировать по настройкам из appsettings.json - вызвать сервис и принять решение динамически Data Annotations упираются в потолок, потому что Attribute - это статичная штука. Туда не получится нормально прокинуть зависимости через DI. И вот здесь FluentValidation реально сияет ✨ Почему: FluentValidation-валидаторы - это обычные классы, которые регистрируются в DI контейнере. А значит, внутрь можно инжектить что угодно: - сервисы - конфиги - репозитории - кэш - внешние API Пример: нужно проверить, что CouponCode валиден через IPricingService? Просто инжектишь IPricingService в конструктор валидатора и делаешь проверку. В итоге валидация превращается из “статической проверки полей” в полноценный слой логики - динамический, умный и расширяемый. FluentValidation = правильная валидация для реального продакшена.

🤖 Open Claude Cowork: AI-партнёр для программирования Open Claude Cowork — это настольный AI-ассистент, который помогает в п
🤖 Open Claude Cowork: AI-партнёр для программирования Open Claude Cowork — это настольный AI-ассистент, который помогает в программировании, управлении файлами и выполнении задач. Он совместим с Claude Code и предлагает визуальный интерфейс для удобной работы с AI, позволяя легко управлять сессиями и получать результаты в реальном времени. 🚀Основные моменты: - 🖥️ Настольное приложение с визуальным интерфейсом - 🤖 AI-партнёр для выполнения задач - 🔁 Полная совместимость с Claude Code - 📂 Удобное управление сессиями и историей - 🔐 Контроль разрешений для безопасных действий 📌 GitHub: https://github.com/DevAgentForge/Claude-Cowork

⚡️ Автоматическая регистрация Minimal APIs в .NET - без ручного маппинга Если в проекте 20+ endpoint’ов, app.MapGet/MapPost п
⚡️ Автоматическая регистрация Minimal APIs в .NET - без ручного маппинга Если в проекте 20+ endpoint’ов, app.MapGet/MapPost превращается в ад. Решение - авторегистрировать endpoints через DI. Идея: 1) Делаешь общий интерфейс IEndpoint 2) Каждый endpoint реализует его 3) На старте приложения сканируешь сборку, регистрируешь все реализации в DI 4) Достаёшь их из DI и вызываешь MapEndpoints() Плюсы: ✅ чистый Program.cs ✅ каждый endpoint в отдельном файле ✅ масштабируется без хаоса ✅ легко тестировать и поддерживать Пример паттерна:

builder.Services.AddEndpoints(typeof(Program).Assembly);

public interface IEndpoint
{
    void Map(IEndpointRouteBuilder app);
}

public static class EndpointExtensions
{
    public static IServiceCollection AddEndpoints(this IServiceCollection services, Assembly assembly)
    {
        var endpoints = assembly.DefinedTypes
            .Where(t => !t.IsAbstract && !t.IsInterface && typeof(IEndpoint).IsAssignableFrom(t))
            .Select(t => ServiceDescriptor.Transient(typeof(IEndpoint), t))
            .ToArray();

        services.TryAddEnumerable(endpoints);
        return services;
    }

    public static void MapEndpoints(this WebApplication app)
    {
        foreach (var endpoint in app.Services.GetServices<IEndpoint>())
            endpoint.Map(app);
    }
}

✔️ C# стал языком 2025 года по версии TIOBE. Индекс TIOBE подвел итоги года: звание «Язык 2025 года» досталось C#, который по
✔️ C# стал языком 2025 года по версии TIOBE. Индекс TIOBE подвел итоги года: звание «Язык 2025 года» досталось C#, который показал рекордный рост популярности (+2.94%)? однако в общем зачете он по-прежнему занимает 5-ю строчку. Абсолютным лидером остается Python с 22.61% долей рынка. В первой пятерке произошли перестановки: язык C поднялся на 2 место, сместив C++ на 4-ю позицию; 3 место досталось Java, а R вернулся в топ-10. Провал года - Go, который неожиданно сдал позиции, опустившись сразу на 16-е место. Индекс оценивает популярность технологий на основе поисковых запросов, активности комьюнити и количества обучающих материалов. https://www.tiobe.com/tiobe-index/