Вот реальные примеры применения SOLID из .NET-приложений.
Давайте честно:
Большинство онлайн-примеров SOLID — отстой.
Если ты не пишешь приложение для зоопарка, то объяснение принципа подстановки Барбары Лисков через Dog : Animal бесполезно.
Я тоже так думал. Считал, что SOLID — это что-то абстрактное и академическое. Пока не начал видеть его в своём реальном коде. И тогда дошло.
Как SOLID выглядит в реальном C#-коде:
1. SRP (Single Responsibility Principle)
Принцип единственной ответственности
Каждый класс должен отвечать только за одну задачу — и делать её хорошо. (смотри код на 1 фото)
🔴 Нарушение: "Бог-класс"
доступ к данным, валидация, отправка email и т.д.
✅ Решение: Разделить на отдельные классы:
• UserValidator
• UserRepository
• EmailSender
2. OCP (Open/Closed Principle)
Принцип открытости/закрытости
Классы должны быть открыты для расширения, но закрыты для изменения.
🔴 Нарушение:
Добавляешь новую сущность — приходится лезть в DbContext.
✅ Решение: Использовать
Новая сущность — просто новый конфигурационный класс.
3. LSP (Liskov Substitution Principle)
Принцип подстановки Барбары Лисков
Дочерние классы должны заменять родительские без нарушения логики.
➡️ Этот принцип касается наследования.
На практике: избегай наследования в C#. Всё.
4. ISP (Interface Segregation Principle)
Принцип разделения интерфейсов
Не заставляй классы реализовывать методы, которые им не нужны.
🔴 Нарушение: Интерфейс
✅ Решение: Разделить на узкоспециализированные интерфейсы:
• IUserRepository
• IPasswordValidator
• IEmailSender
• ILogger
ISP — это SRP, но для интерфейсов.
5. DIP (Dependency Inversion Principle)
Принцип инверсии зависимостей
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций.
➡️ Слои бизнес-логики не должны зависеть от инфраструктуры (БД, файловой системы, внешних API и т.п.)
✅ Решение: В Clean Architecture слои
Совмести с Vertical Slices — получишь максимум пользы.
Вот и всё.
SOLID на реальном .NET-коде. Дай знать, стало ли понятнее.
👉 @KodBlog
Давайте честно:
Большинство онлайн-примеров SOLID — отстой.
Если ты не пишешь приложение для зоопарка, то объяснение принципа подстановки Барбары Лисков через Dog : Animal бесполезно.
Я тоже так думал. Считал, что SOLID — это что-то абстрактное и академическое. Пока не начал видеть его в своём реальном коде. И тогда дошло.
Как SOLID выглядит в реальном C#-коде:
1. SRP (Single Responsibility Principle)
Принцип единственной ответственности
Каждый класс должен отвечать только за одну задачу — и делать её хорошо. (смотри код на 1 фото)
UserService, который делает всё подряд:доступ к данным, валидация, отправка email и т.д.
• UserValidator
• UserRepository
• EmailSender
2. OCP (Open/Closed Principle)
Принцип открытости/закрытости
Классы должны быть открыты для расширения, но закрыты для изменения.
DbContext.OnModelCreating содержит конфигурацию для всех сущностей EF Core.Добавляешь новую сущность — приходится лезть в DbContext.
IEntityTypeConfiguration<T>. (смотри код на 2 фото)Новая сущность — просто новый конфигурационный класс.
DbContext остаётся нетронутым.3. LSP (Liskov Substitution Principle)
Принцип подстановки Барбары Лисков
Дочерние классы должны заменять родительские без нарушения логики.
На практике: избегай наследования в C#. Всё.
4. ISP (Interface Segregation Principle)
Принцип разделения интерфейсов
Не заставляй классы реализовывать методы, которые им не нужны.
IUserService, в котором всё подряд: валидация паролей, отправка писем, логирование и т.п.• IUserRepository
• IPasswordValidator
• IEmailSender
• ILogger
ISP — это SRP, но для интерфейсов.
5. DIP (Dependency Inversion Principle)
Принцип инверсии зависимостей
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций.
Entities и UseCases (доменная логика) не должны зависеть от инфраструктурных слоёв.Совмести с Vertical Slices — получишь максимум пользы.
Вот и всё.
SOLID на реальном .NET-коде. Дай знать, стало ли понятнее.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥21👌6🔥5👀4❤1
This media is not supported in your browser
VIEW IN TELEGRAM
В VS Code Insiders теперь по умолчанию включён IntelliSense в терминале
Попробуй — ты получишь плавные и динамичные подсказки прямо в терминале, например, при переключении на другую ветку🥰
👉 @KodBlog
Попробуй — ты получишь плавные и динамичные подсказки прямо в терминале, например, при переключении на другую ветку
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥5
Тебе не нужно больше покрытия тестами. Тебе нужна лучше спроектированная система.
Большинство разработчиков винят недостаточное покрытие в том, что не чувствуют уверенности в коде.
Но это — лишь вершина айсберга.
В чём настоящие проблемы?
1. Бизнес-логика размазана по сервисам и хендлерам
2. Внешние зависимости разделены неправильно
3. Доменная модель содержит только свойства, но не поведение
Как команды пытаются это решать?
Добавляют больше интеграционных тестов.
Но это создаёт ложное чувство уверенности:
• Вы сильно полагаетесь на медленные, широкие интеграционные тесты
↳ Кажется, что они надёжны. Но на деле они лишь скрывают архитектурные проблемы за хрупкой обёрткой.
• Основная логика не покрыта быстрыми unit-тестами
↳ Уверенность должна приходить от быстрого фидбека, а не от 15-минутного пайплайна.
• Вы компенсируете плохой дизайн большим количеством тестов
↳ Количество тестов не решит проблему с хаосом между сервисами и анемичной моделью домена.
Что реально работает:
→ Вся ключевая логика должна быть в насыщенной доменной модели
→ Покрывать её быстрыми, изолированными и точечными unit-тестами
→ А более высокоуровневые тесты должны лишь дополнять
Больше тестов — не решение.
Хорошая архитектура — вот что нужно
👉 @KodBlog
Большинство разработчиков винят недостаточное покрытие в том, что не чувствуют уверенности в коде.
Но это — лишь вершина айсберга.
В чём настоящие проблемы?
1. Бизнес-логика размазана по сервисам и хендлерам
2. Внешние зависимости разделены неправильно
3. Доменная модель содержит только свойства, но не поведение
Как команды пытаются это решать?
Добавляют больше интеграционных тестов.
Но это создаёт ложное чувство уверенности:
• Вы сильно полагаетесь на медленные, широкие интеграционные тесты
↳ Кажется, что они надёжны. Но на деле они лишь скрывают архитектурные проблемы за хрупкой обёрткой.
• Основная логика не покрыта быстрыми unit-тестами
↳ Уверенность должна приходить от быстрого фидбека, а не от 15-минутного пайплайна.
• Вы компенсируете плохой дизайн большим количеством тестов
↳ Количество тестов не решит проблему с хаосом между сервисами и анемичной моделью домена.
Что реально работает:
→ Вся ключевая логика должна быть в насыщенной доменной модели
→ Покрывать её быстрыми, изолированными и точечными unit-тестами
→ А более высокоуровневые тесты должны лишь дополнять
Больше тестов — не решение.
Хорошая архитектура — вот что нужно
Please open Telegram to view this post
VIEW IN TELEGRAM
💯5❤2
Трудно отследить, что происходит внутри твоего .NET-приложения?
Вот базовая настройка OpenTelemetry, которую я использую в каждом проекте:
- ASP .NET Core instrumentation
- HttpClient instrumentation
- EF Core instrumentation
- Redis instrumentation
- Npgsql (или SqlClient)
Это даёт полноценные, сквозные трассировки — и всё это быстро.
Для визуализации можно использовать:
- Seq
- Jaeger
- Grafana
- Aspire Dashboard
Seq также поддерживает структурированные логи, что хорошо сочетается с трассировкой.
Вот практическое руководство: ссылка
👉 @KodBlog
Вот базовая настройка OpenTelemetry, которую я использую в каждом проекте:
- ASP .NET Core instrumentation
- HttpClient instrumentation
- EF Core instrumentation
- Redis instrumentation
- Npgsql (или SqlClient)
Это даёт полноценные, сквозные трассировки — и всё это быстро.
Для визуализации можно использовать:
- Seq
- Jaeger
- Grafana
- Aspire Dashboard
Seq также поддерживает структурированные логи, что хорошо сочетается с трассировкой.
Вот практическое руководство: ссылка
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍2🔥2
Производительность критична для любого приложения.
Разработчики часто добавляют слой кэширования поверх медленных SQL-запросов. Тем самым они маскируют симптомы, вместо того чтобы устранить первопричину.
В этом мы разберёмся на практике: как оптимизировать медленный реальный запрос на EF Core. EF Core предоставляет мощные инструменты, но при неправильном использовании может приводить к медленным запросам.
Автор покажет, как пошагово оптимизировал запрос на EF Core — с неприемлемых 30 секунд до сверхбыстрых 30 миллисекунд.😮
В приложении используются следующие сущности:
🔸 Users (Пользователи): каждый пользователь может иметь много постов и комментариев.
🔸 Comments (Комментарии): каждый комментарий принадлежит пользователю и связан с постом.
🔸 Categories (Категории): посты имеют категории.
🔸 Posts (Посты): каждый пост относится к категории и может иметь множество лайков.
🔸 Likes (Лайки): каждый лайк относится к посту.
Условие задачи:
Выбрать топ-5 пользователей, которые оставили наибольшее число комментариев за последние 7 дней под постами в категории ".NET".
Для каждого пользователя вернуть:
🔸 UserId
🔸 Username
🔸 Количество комментариев пользователя (только по постам из категории ".NET" за последние 7 дней)
🔸 Топ-3 поста в категории ".NET" с наибольшим числом лайков, под которыми этот пользователь чаще всего комментировал (PostId, LikesCount)
Полное разбор задачи по оптимизации EF Core-запроса — читай тут
👉 @KodBlog
Разработчики часто добавляют слой кэширования поверх медленных SQL-запросов. Тем самым они маскируют симптомы, вместо того чтобы устранить первопричину.
В этом мы разберёмся на практике: как оптимизировать медленный реальный запрос на EF Core. EF Core предоставляет мощные инструменты, но при неправильном использовании может приводить к медленным запросам.
Автор покажет, как пошагово оптимизировал запрос на EF Core — с неприемлемых 30 секунд до сверхбыстрых 30 миллисекунд.
В приложении используются следующие сущности:
Условие задачи:
Выбрать топ-5 пользователей, которые оставили наибольшее число комментариев за последние 7 дней под постами в категории ".NET".
Для каждого пользователя вернуть:
Полное разбор задачи по оптимизации EF Core-запроса — читай тут
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥4
Самая большая ошибка джуниоров? Игнорировать SQL.
Невозможно по-настоящему понять, как работают базы данных, если полагаться только на ORM.
Реляционные базы данных существуют уже более 40 лет и не просто так.
Сфокусируйся на:
🔸 основах SQL
🔸 моделировании данных
🔸 транзакциях
🔸 индексировании
Как именно — cмотрите тут
Освой SQL и ты вырастешь как разработчик в 10 раз быстрее📖
👉 @KodBlog
Невозможно по-настоящему понять, как работают базы данных, если полагаться только на ORM.
Реляционные базы данных существуют уже более 40 лет и не просто так.
Сфокусируйся на:
Окупается быстро. Недавно я оптимизировал два запроса:
> SELECT: с 70 мс до 1 мс
> UPDATE: с 300 мс до 52 мс
Как именно — cмотрите тут
Освой SQL и ты вырастешь как разработчик в 10 раз быстрее
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2❤1😁1
𝟰𝟱 вопросов для подготовки к собеседованию по
👉 @KodBlog
ASP.NET Core→ Объясните, как работает маршрутизация в ASP . NET Core
→ Что такое middleware и в каком порядке они выполняются?
→ Как можно остановить выполнение последующих middleware?
→ В чём разница между MVC и Razor Pages?
→ Назовите 3 способа создания middleware
→ Объясните, как работает многослойная конфигурация в appsettings.json
→ В чём разница между сервисами Singleton, Scoped и Transient?
→ Как использовать Scoped-сервис внутри Singleton-сервиса?
→ Как выполнить код при запуске и остановке приложения?
→ Что такое BackgroundService?
→ Назовите несколько способов чтения данных из конфигурации appsettings.json
→ Что такое Options Pattern?
→ Назовите случаи использования ISnapshotMonitor и IOptionsMonitor
→ Как валидировать конфигурацию?
→ В чём разница между DataAnnotations и FluentValidation?
→ Какие бывают атрибуты фильтров у контроллеров?
→ Почему Minimal API работают быстрее, чем контроллеры?
→ Как добавить авторизацию в проект?
→ Как добавить авторизацию ко всем методам контроллера, кроме одного?
→ Как бы вы реализовали функциональность входа в систему (Log-In)?
→ Объясните, как работают JWT-токены
→ Объясните Refresh-токены и как они работают
→ Как бы вы реализовали доступ к ресурсам на основе прав пользователя?
→ Для чего используется HostedService?
→ Объясните разницу между PeriodicTimer и await Task.Delay()
→ Что такое HSTS?
→ Как вернуть файл из API-эндпойнта?
→ Как принять файл через API-эндпойнт?
→ Как получить параметры query string в API-эндпойнте?
→ Как получить информацию о текущем авторизованном пользователе?
→ Как внедрять зависимости в Minimal API?
→ Как структурировать эндпойнты в Minimal API?
→ Что такое Output Caching?
→ В чём разница между IMemoryCache и IDistributedCache?
→ Объясните, как работает HybridCache или FusionCache
→ Какие паттерны кэширования вы знаете?
→ Для чего используется Rate Limiting и какие его типы существуют?
→ Как инвалидировать данные в OutputCache?
→ Как реализовать версионирование API?
→ Как добавить версионирование в существующий API, если нельзя менять URL?
→ Для чего используется Swagger?
→ Как задокументировать эндпойнты, модели и поля в Swagger?
→ Как получить строку подключения из конфигурации?
→ Как развернуть приложение ASP. NET Core?
→ Как настроить логирование в ASP. NET Core?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22
Минималистичные API + версионирование API = дублирующийся беспорядок?
Нет, если сделать правильно.
Вместо того чтобы помечать каждый endpoint через
Версию указываешь один раз — и она применяется ко всем endpoint'ам внутри группы. Чище маршруты, меньше дублирования.
Отлично работает и для префиксов вроде
Хочешь увидеть, как это реализуется (и для Minimal API, и для контроллеров)?
▶️ Вот гайд: ссылка
👉 @KodBlog
Нет, если сделать правильно.
Вместо того чтобы помечать каждый endpoint через
ApiVersionSet, можно определить группу маршрутов.Версию указываешь один раз — и она применяется ко всем endpoint'ам внутри группы. Чище маршруты, меньше дублирования.
Отлично работает и для префиксов вроде
/v1Хочешь увидеть, как это реализуется (и для Minimal API, и для контроллеров)?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2
Что такое JSON Web Token (JWT)?
JWT — это компактный, безопасный для передачи по URL токен, предназначенный для безопасной передачи информации между двумя сторонами — обычно между клиентом и сервером.
Он широко используется для аутентификации и авторизации в современных веб-приложениях.
JWT выглядит так:
Он состоит из трёх частей:
🔸 Header: указывает тип токена и алгоритм подписи (например, HMAC или RSA)
🔸 Payload: содержит claims — данные о пользователе, такие как userId, role и т. д.
🔸 Signature: используется для проверки подлинности отправителя и гарантирует, что токен не был изменён
Как это работает:
1. Пользователь входит в систему, вводя логин и пароль.
2. Сервер проверяет учётные данные и генерирует JWT.
3. Сервер отправляет токен обратно клиенту.
4. Клиент сохраняет токен (обычно в
5. При последующих запросах клиент добавляет JWT в заголовок
👉 @KodBlog
JWT — это компактный, безопасный для передачи по URL токен, предназначенный для безопасной передачи информации между двумя сторонами — обычно между клиентом и сервером.
Он широко используется для аутентификации и авторизации в современных веб-приложениях.
JWT выглядит так:
xxxxx.yyyyy.zzzzzОн состоит из трёх частей:
Как это работает:
1. Пользователь входит в систему, вводя логин и пароль.
2. Сервер проверяет учётные данные и генерирует JWT.
3. Сервер отправляет токен обратно клиенту.
4. Клиент сохраняет токен (обычно в
localStorage или в cookie).5. При последующих запросах клиент добавляет JWT в заголовок
AuthorizationPlease open Telegram to view this post
VIEW IN TELEGRAM
1👍11🔥4❤2👏2🐳1
Одна из самых недооценённых возможностей HttpClient?
Идеально подходит для реализации сквозной логики, такой как:
➣ Аутентификация
➣ Логирование
➣ Аудит
➣ Кэширование
➣ Повторные попытки (Retries)
Вместо того чтобы дублировать этот код в каждом запросе — оформляется единый чистый pipeline.
Вот как использовать
А ты как обрабатываешь сквозную HTTP-логику в своих проектах?📝
👉 @KodBlog
DelegatingHandler — это middleware для исходящих HTTP-запросов.Идеально подходит для реализации сквозной логики, такой как:
➣ Аутентификация
➣ Логирование
➣ Аудит
➣ Кэширование
➣ Повторные попытки (Retries)
Вместо того чтобы дублировать этот код в каждом запросе — оформляется единый чистый pipeline.
Вот как использовать
DelegatingHandler в .NETА ты как обрабатываешь сквозную HTTP-логику в своих проектах?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍4
Исключения это Goto-команды современного .NET-разработчика. 😊
(И это не комплимент)
Многие разработчики выбрасывают исключения как способ по умолчанию для управления поведением приложения.
Но вот в чём проблема:
➣ Они ломают поток выполнения программы.
➣ Заставляют каждый вызывающий код оборачивать логику в try-catch (иначе — падение).
➣ И что хуже всего — при чрезмерном использовании могут влиять на производительность.
Что использовать вместо?
Паттерн Result
Вместо выбрасывания исключения метод возвращает объект-результат, который явно указывает на успех или неудачу.
Плюсы:
✅ Без неожиданностей
✅ Без скрытых переходов
✅ Предсказуемый, читаемый контроль потока
Совершенен ли этот подход? Нет.
Он может показаться многословным, и в C# пока нет нативной поддержки.
Но он даёт чёткость и явность в обработке ошибок.
В долгосрочной перспективе то, как ты обрабатываешь ошибки, определяет стабильность твоего приложения.
Можно продолжать:
– использовать исключения для повседневного контроля потока
– надеяться, что поймаешь все крайние кейсы
– чинить баги уже после крашей
Или можно использовать Result pattern:
– проектировать поведение на случай ошибок заранее
– явно различать успех и неудачу
👉 @KodBlog
Многие разработчики выбрасывают исключения как способ по умолчанию для управления поведением приложения.
Но вот в чём проблема:
➣ Они ломают поток выполнения программы.
➣ Заставляют каждый вызывающий код оборачивать логику в try-catch (иначе — падение).
➣ И что хуже всего — при чрезмерном использовании могут влиять на производительность.
Что использовать вместо?
Паттерн Result
Вместо выбрасывания исключения метод возвращает объект-результат, который явно указывает на успех или неудачу.
Плюсы:
Совершенен ли этот подход? Нет.
Он может показаться многословным, и в C# пока нет нативной поддержки.
Но он даёт чёткость и явность в обработке ошибок.
В долгосрочной перспективе то, как ты обрабатываешь ошибки, определяет стабильность твоего приложения.
Можно продолжать:
– использовать исключения для повседневного контроля потока
– надеяться, что поймаешь все крайние кейсы
– чинить баги уже после крашей
Или можно использовать Result pattern:
– проектировать поведение на случай ошибок заранее
– явно различать успех и неудачу
Please open Telegram to view this post
VIEW IN TELEGRAM
1🤨9❤7👍6
This media is not supported in your browser
VIEW IN TELEGRAM
Проект дня: переиспользуемый пайплайн деплоя, написанный на C#, который может взять любой проект на Aspire и задеплоить его на виртуальную машину через SSH и Docker.
➟ Использование C# >>>> shell-скрипты, вперемешку с YAML🤮
➟ Код пайплайна работает поверх модели. Один и тот же код подходит для любого Aspire-приложения без изменений. Это динамический шаблон пайплайна.
➟ Может запускаться локально или в CI
➟ Построено на новых API, которые появятся в Aspire 9.4 (ты тоже можешь собрать свой пайплайн и задеплоить куда угодно!)
https://github.com/davidfowl/AspirePipelines
👉 @KodBlog
➟ Использование C# >>>> shell-скрипты, вперемешку с YAML
➟ Код пайплайна работает поверх модели. Один и тот же код подходит для любого Aspire-приложения без изменений. Это динамический шаблон пайплайна.
➟ Может запускаться локально или в CI
➟ Построено на новых API, которые появятся в Aspire 9.4 (ты тоже можешь собрать свой пайплайн и задеплоить куда угодно!)
https://github.com/davidfowl/AspirePipelines
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
Тестировать API, не выходя из VS Code? Да, пожалуйста.
Новое расширение Postman для VS Code переносит разработку API прямо в IDE
Что оно умеет:
➣ Отправка HTTP-, WebSocket- и gRPC-запросов прямо из VS Code
➣ Совместное использование тестовых скриптов через коллекции Postman
➣ Импорт .env-файлов без ручного ввода переменных
➣ Отладка эндпоинтов рядом с кодом, в одном окне
Попробовать можно здесь:
🔸 https://fnf.dev/44C6rRm
А вот ещё пара обновлений от Postman, которые стоит заценить:
Интеграция с Jira Cloud
Падаешь на 500-ке при вызове API?
Создавай баг-репорты в Jira за один клик — без переключения между тулзами:
➣ Быстрое создание задач из упавших запросов
➣ Автоматически прикладываются заголовки, токены, тело запроса и ответ
➣ Добавляются конфигурация окружения и шаги воспроизведения
👉 https://fnf.dev/3THdIZM
Интеграция с GitHub
Держи API-спеки и исходники в синхронизации:
➣ Автокоммит коллекций в репозиторий
➣ Просмотр изменений в API рядом с кодом в pull request
➣ Прогон тестов в CI на тех же коллекциях, с которыми работает команда
Подробнее: https://fnf.dev/4l2905d
👉 @KodBlog
Новое расширение Postman для VS Code переносит разработку API прямо в IDE
Что оно умеет:
➣ Отправка HTTP-, WebSocket- и gRPC-запросов прямо из VS Code
➣ Совместное использование тестовых скриптов через коллекции Postman
➣ Импорт .env-файлов без ручного ввода переменных
➣ Отладка эндпоинтов рядом с кодом, в одном окне
Попробовать можно здесь:
А вот ещё пара обновлений от Postman, которые стоит заценить:
Интеграция с Jira Cloud
Падаешь на 500-ке при вызове API?
Создавай баг-репорты в Jira за один клик — без переключения между тулзами:
➣ Быстрое создание задач из упавших запросов
➣ Автоматически прикладываются заголовки, токены, тело запроса и ответ
➣ Добавляются конфигурация окружения и шаги воспроизведения
Интеграция с GitHub
Держи API-спеки и исходники в синхронизации:
➣ Автокоммит коллекций в репозиторий
➣ Просмотр изменений в API рядом с кодом в pull request
➣ Прогон тестов в CI на тех же коллекциях, с которыми работает команда
Подробнее: https://fnf.dev/4l2905d
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
Использование nameof вместо
В этом нет ничего надуманного, даже ReSharper содержит инспекцию на этот случай.
Reddit тред -> ссылка
👉 @KodBlog
ToString() при обращении к имени члена перечисления в .NET — это абсолютно валидная техника оптимизации производительности.В этом нет ничего надуманного, даже ReSharper содержит инспекцию на этот случай.
nameof выносит получение строки в compile-time, тем самым существенно снижает время выполнения и устраняет аллокации — что особенно важно в производительно-критичных hot-path'ахReddit тред -> ссылка
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍6❤2🤔1🥴1
Вот как я получаю индекс каждого элемента в .NET 9
Используй метод
LINQ всегда был крайне полезным инструментом для .NET-разработчиков.
Но с выходом .NET 9 в LINQ появились три новых метода:
> Index
> CountBy
> AggregateBy
Сконцентрируемся на методе Index.
Метод
Это отличный способ, если тебе нужно получить индекс каждого элемента в коллекции.
Пример кода прикрепил😎
👉 @KodBlog
Используй метод
Index из LINQ.LINQ всегда был крайне полезным инструментом для .NET-разработчиков.
Но с выходом .NET 9 в LINQ появились три новых метода:
> Index
> CountBy
> AggregateBy
Сконцентрируемся на методе Index.
Метод
Index возвращает перечисление (enumerable), в котором каждый элемент представлен в виде кортежа с его индексом.Это отличный способ, если тебе нужно получить индекс каждого элемента в коллекции.
Пример кода прикрепил
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥6
Как реализовать Refresh Tokens в 👇
Настоящая сложность не в базовой реализации аутентификации через JWT, а в том, чтобы обеспечить безопасность и хороший пользовательский опыт при истечении срока действия токенов.
Обычно JWT-аутентификация использует два токена:
● Access token — даёт доступ к защищённым ресурсам и живёт недолго (обычно 5–10 минут).
● Короткий срок жизни снижает риски при компрометации.
Refresh token — нужен для получения нового access token без повторного входа пользователя в систему.
Если access token живёт всего несколько минут — пользователь будет постоянно переавторизовываться. Это ужасный UX.
Здесь и вступает в игру refresh token. Он позволяет «тихо» получить новый access token, когда текущий истёк, не требуя логина.
Refresh token, как правило, живёт дольше — от нескольких дней до недель.
Anton Martyniuk рассказал:
🔸 Что такое refresh токены и как они работают
🔸 Как реализовать их в
🔸 Как обеспечить безопасность и соблюдать best practices
🔸 Как отзывать refresh токены, чтобы динамически обновлять права доступа пользователя
Хочешь прокачать безопасность в
👉 @KodBlog
ASP.NET Core и как отозвать токены пользователя Настоящая сложность не в базовой реализации аутентификации через JWT, а в том, чтобы обеспечить безопасность и хороший пользовательский опыт при истечении срока действия токенов.
Обычно JWT-аутентификация использует два токена:
● Access token — даёт доступ к защищённым ресурсам и живёт недолго (обычно 5–10 минут).
● Короткий срок жизни снижает риски при компрометации.
Refresh token — нужен для получения нового access token без повторного входа пользователя в систему.
Если access token живёт всего несколько минут — пользователь будет постоянно переавторизовываться. Это ужасный UX.
Здесь и вступает в игру refresh token. Он позволяет «тихо» получить новый access token, когда текущий истёк, не требуя логина.
Refresh token, как правило, живёт дольше — от нескольких дней до недель.
Anton Martyniuk рассказал:
ASP.NET CoreХочешь прокачать безопасность в
ASP.NET Core по индустриальным стандартам? вот статьяPlease open Telegram to view this post
VIEW IN TELEGRAM
❤10👍4👀2
Как быстро расчистить раздутые API-контроллеры:
Используй метод-инъекцию😨
Это малоизвестная фича в
Для этого используется
Хотя
Когда стоит использовать метод-инъекцию:
🔸 когда сервис используется только в одном экшене
🔸 когда конструктор начинает превращаться в кашу из зависимостей
🔸 когда сервис тяжёлый, и важно контролировать его создание и утилизацию
Да, внедрение через конструктор — это дефолтный подход.
Но метод-инъекция — это удобный инструмент, если ты:
- хочешь придерживаться Single Responsibility Principle
- не хочешь превращать контроллер в свалку зависимостей
👉 @KodBlog
Используй метод-инъекцию
Это малоизвестная фича в
ASP.NET Core, которая позволяет внедрять зависимости не в конструктор, а напрямую в метод-обработчик.Для этого используется
[FromServices] IYourServiceХотя
[FromServices] можно и опустить — оно не обязательно.Когда стоит использовать метод-инъекцию:
Да, внедрение через конструктор — это дефолтный подход.
Но метод-инъекция — это удобный инструмент, если ты:
- хочешь придерживаться Single Responsibility Principle
- не хочешь превращать контроллер в свалку зависимостей
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤7
C# наконец-то получает дискриминируемые объединения
Ну, возможно?
Появилось новое предложение по добавлению объединений типов (Type Unions) в C#. И это действительно важно.
Почему?
Это открывает нативную поддержку таких конструкций, как
Больше не нужно городить костыли, оборачивать значения или зависеть от сторонних библиотек, чтобы описать функцию, возвращающую успех или ошибку.
Теперь это может измениться.
В предложении описываются нативные union-типы, включая поддержку pattern matching, проверку исчерпывающего перебора (exhaustiveness checks) и другие фичи.
Не хочешь ждать?
Вот как можно реализовать паттерн
Если предпочитаешь бросать исключения — можешь это пропустить.🤵
👉 @KodBlog
Ну, возможно?
Появилось новое предложение по добавлению объединений типов (Type Unions) в C#. И это действительно важно.
Почему?
Это открывает нативную поддержку таких конструкций, как
Result и Option.Больше не нужно городить костыли, оборачивать значения или зависеть от сторонних библиотек, чтобы описать функцию, возвращающую успех или ошибку.
Я уже много лет выступаю за использование паттерна Result. Но до сих пор отсутствие поддержки на уровне языка делало его применение неуклюжим.
Теперь это может измениться.
В предложении описываются нативные union-типы, включая поддержку pattern matching, проверку исчерпывающего перебора (exhaustiveness checks) и другие фичи.
Не хочешь ждать?
Вот как можно реализовать паттерн
Result уже сегодняЕсли предпочитаешь бросать исключения — можешь это пропустить.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10
Миф о том, что Dapper на 50% быстрее EF Core — это неправда
Ты наверняка слышал, как говорят, что Dapper на 30%, 50% или даже в 2 раза быстрее, чем EF Core?
Это утверждение гуляет повсюду.
Но проведя реальный бенчмарк на .NET 8, с таким запросом:
Результаты удивили:
🔸 Dapper: 2.07 мс
🔸 EF Core: 2.43 мс
(см. скриншот для деталей)
Разница — всего 0.36 мс, или 14%.
Да, Dapper выделяет меньше памяти, но для большинства приложений эта разница мизерная.
Что это значит?
↳ Для 80% проектов такая разница в производительности вообще не критична.
> Поэтому EF Core — мой выбор по умолчанию.
12 причин выбрать EF Core вместо Dapper в реальной разработке:
1. Автоматическое отслеживание изменений сущностей — меньше ручного кода для insert, update, delete.
2. LINQ-запросы с проверкой на этапе компиляции, которые трансформируются в SQL.
3. Code-First миграции упрощают эволюцию схемы базы данных.
4. Возможность реверс-инжиниринга существующей базы в модели.
5. Навигационные свойства позволяют работать с отношениями без ручных join-ов.
6. Поддержка eager, lazy и explicit загрузки данных.
7. Глобальные фильтры запросов для soft delete и мультиарендности.
8. Value Conversions — удобное отображение кастомных типов на столбцы в БД.
9. Встроенные политики повторных попыток (retry) делают соединения с БД более устойчивыми.
10. Interceptors — можно реализовать аудит, логирование, кастомные поведения.
11. Один и тот же запрос работает с множеством провайдеров: SQL Server, PostgreSQL, MySQL, Oracle, SQLite и др.
12. Поддержка миграций сразу для нескольких БД из одного кода.
Важно:
EF Core может не быть самым быстрым в микробенчмарках, но его возможности экономят часы и дни в реальных проектах.
Выбирай инструмент, который делает код чище, а команду — продуктивнее,
а не просто тот, у которого время на пару миллисекунд меньше.
👉 @KodBlog
Ты наверняка слышал, как говорят, что Dapper на 30%, 50% или даже в 2 раза быстрее, чем EF Core?
Это утверждение гуляет повсюду.
Но проведя реальный бенчмарк на .NET 8, с таким запросом:
"Получить топ-5 пользователей, которые оставили больше всего комментариев за последние 7 дней к постам в категории '.NET'"
Результаты удивили:
(см. скриншот для деталей)
Разница — всего 0.36 мс, или 14%.
Да, Dapper выделяет меньше памяти, но для большинства приложений эта разница мизерная.
Что это значит?
↳ Для 80% проектов такая разница в производительности вообще не критична.
> Поэтому EF Core — мой выбор по умолчанию.
12 причин выбрать EF Core вместо Dapper в реальной разработке:
1. Автоматическое отслеживание изменений сущностей — меньше ручного кода для insert, update, delete.
2. LINQ-запросы с проверкой на этапе компиляции, которые трансформируются в SQL.
3. Code-First миграции упрощают эволюцию схемы базы данных.
4. Возможность реверс-инжиниринга существующей базы в модели.
5. Навигационные свойства позволяют работать с отношениями без ручных join-ов.
6. Поддержка eager, lazy и explicit загрузки данных.
7. Глобальные фильтры запросов для soft delete и мультиарендности.
8. Value Conversions — удобное отображение кастомных типов на столбцы в БД.
9. Встроенные политики повторных попыток (retry) делают соединения с БД более устойчивыми.
10. Interceptors — можно реализовать аудит, логирование, кастомные поведения.
11. Один и тот же запрос работает с множеством провайдеров: SQL Server, PostgreSQL, MySQL, Oracle, SQLite и др.
12. Поддержка миграций сразу для нескольких БД из одного кода.
Важно:
EF Core может не быть самым быстрым в микробенчмарках, но его возможности экономят часы и дни в реальных проектах.
Выбирай инструмент, который делает код чище, а команду — продуктивнее,
а не просто тот, у которого время на пару миллисекунд меньше.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥13👍7❤5🍌1