Please open Telegram to view this post
VIEW IN TELEGRAM
❤13😐9👎1
Знаешь, что даже простая смена
В C# 11 поменялась генерация кода для конверсии method group так, чтобы в некоторых случаях избегать аллокаций.
Пример:
на net4.8 при LangVersion C# 10 и ниже вариант с method group может создавать делегат (то есть аллоцировать) и из-за этого быть заметно медленнее. А при LangVersion C# 11+ компилятор меняет генерацию кода так, чтобы делегат кэшировался, и аллокации пропадают.
В C# 11 поменяли codegen, чтобы кэшировать конверсию method group
C# 10 и ниже (делегат создается на месте):
C# 11 и выше (делегат кэшируется):
👉 @KodBlog
C# langversion может повлиять на производительность?В C# 11 поменялась генерация кода для конверсии method group так, чтобы в некоторых случаях избегать аллокаций.
Пример:
[Benchmark]
public int Lambda()
{
Func<int> func = () => Method();
return func();
}
[Benchmark]
public int MethodGroup()
{
Func<int> func = Method;
return func();
}
static int Method() => 42;
на net4.8 при LangVersion C# 10 и ниже вариант с method group может создавать делегат (то есть аллоцировать) и из-за этого быть заметно медленнее. А при LangVersion C# 11+ компилятор меняет генерацию кода так, чтобы делегат кэшировался, и аллокации пропадают.
В C# 11 поменяли codegen, чтобы кэшировать конверсию method group
C# 10 и ниже (делегат создается на месте):
return new Func<int>((object)null, __methodptr(Method))();
C# 11 и выше (делегат кэшируется):
return (MethodGroupBenchmarks.<>O.<0>__Method ??
(MethodGroupBenchmarks.<>O.<0>__Method = new Func<int>((object)null, __methodptr(Method))))();
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔8
В .NET 10 больше не нужно писать Dockerfile.
Кто уже пользуется новой фичей? Как ощущения в проде?
Типичный многостадийный Dockerfile для .NET-приложения выглядит примерно так:
Это работает, но есть кривая обучения и накладные расходы на поддержку:
Поддержка: нужно вручную обновлять теги базовых образов
Кэширование слоёв: неправильный порядок COPY убивает кэш сборки
Дублирование: почти каждому проекту нужен похожий Dockerfile
Переключение контекста: ты пишешь Docker DSL, а не .NET-код
Подход с .NET SDK устраняет все эти проблемы.
Если ты работаешь на .NET 10, ничего дополнительно включать не нужно. Публикация в контейнеры работает из коробки для ASP.NET Core-приложений, worker-сервисов и консольных приложений.
Можно сразу публиковать приложение в контейнерный образ:
И всё. .NET SDK сам:
соберёт приложение
подберёт подходящий базовый образ
создаст контейнерный образ с результатом публикации
загрузит его в локальный OCI-совместимый демон
Чаще всего это Docker, но Podman тоже поддерживается.
(На скрине показан вывод команды dotnet publish, создающей контейнерный образ.)
👉 @KodBlog
Кто уже пользуется новой фичей? Как ощущения в проде?
Типичный многостадийный Dockerfile для .NET-приложения выглядит примерно так:
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["src/MyApi/MyApi.csproj", "src/MyApi/"]
RUN dotnet restore "src/MyApi/MyApi.csproj"
COPY . .
WORKDIR "/src/src/MyApi"
RUN dotnet build "MyApi.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "MyApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApi.dll"]
Это работает, но есть кривая обучения и накладные расходы на поддержку:
Поддержка: нужно вручную обновлять теги базовых образов
Кэширование слоёв: неправильный порядок COPY убивает кэш сборки
Дублирование: почти каждому проекту нужен похожий Dockerfile
Переключение контекста: ты пишешь Docker DSL, а не .NET-код
Подход с .NET SDK устраняет все эти проблемы.
Если ты работаешь на .NET 10, ничего дополнительно включать не нужно. Публикация в контейнеры работает из коробки для ASP.NET Core-приложений, worker-сервисов и консольных приложений.
Можно сразу публиковать приложение в контейнерный образ:
dotnet publish --os linux --arch x64 /t:PublishContainer
И всё. .NET SDK сам:
соберёт приложение
подберёт подходящий базовый образ
создаст контейнерный образ с результатом публикации
загрузит его в локальный OCI-совместимый демон
Чаще всего это Docker, но Podman тоже поддерживается.
(На скрине показан вывод команды dotnet publish, создающей контейнерный образ.)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14❤6
This media is not supported in your browser
VIEW IN TELEGRAM
AviyalWM: портативный и лёгкий оконный менеджер, написанный на C#
Рад сообщить о релизе AviyalWM — простого, лёгкого и портативного динамического тайлингового оконного менеджера для Windows. Краткий список возможностей:
▪️ Рабочие пространства
▪️ Анимации рабочих пространств (горизонтальные и вертикальные)
▪️ Макеты: Dwindle, Stack, Master
▪️ Переключение в плавающий режим
▪️ Закрытие окна в фокусе
▪️ Переключение фокуса
▪️ Конфигурация через JSON
▪️ Горячая перезагрузка
▪️ Запрос состояния через WebSocket и выполнение команд
▪️ Запуск приложений с помощью горячих клавиш
Репозиторий: https://github.com/TheAjaykrishnanR/aviyal
👉 @KodBlog
Рад сообщить о релизе AviyalWM — простого, лёгкого и портативного динамического тайлингового оконного менеджера для Windows. Краткий список возможностей:
Репозиторий: https://github.com/TheAjaykrishnanR/aviyal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12🔥2
В .NET теперь добавили
Это изменение вчера влито в dotnet main и, судя по всему, будет доступно в .NET 11.
На втором фото есть таблица от Gemini с сравнением Gzip, Brotli и Zstandard по скорости и сжатию.
👉 @KodBlog
DecompressionMethods.Zstandard для автоматической распаковки HTTP-ответов Это изменение вчера влито в dotnet main и, судя по всему, будет доступно в .NET 11.
На втором фото есть таблица от Gemini с сравнением Gzip, Brotli и Zstandard по скорости и сжатию.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👏13🔥2❤1
Когда появился Docker, это была настоящая революция.
Теперь .NET Aspire меняет способ доставки ПО навсегда.
И многие разработчики до сих пор не осознают масштаб этого сдвига.
Docker решил хаос с окружениями
До Docker проблема «у меня работает» была ежедневной:
• Разные версии ОС
• Отсутствующие зависимости
• Сломанные окружения повсюду
Docker решил это, стандартизировав окружения через контейнеры.
Одна команда → одно и то же приложение, одинаковое поведение, везде.
Это действительно было революцией.
Но Docker не решил всё
Он пакует приложения, но связи между сервисами всё ещё настраиваются вручную:
• Всё ещё приходится управлять строками подключения
• Всё ещё самому настраивать наблюдаемость
И распределённые системы остаются сложными.
Здесь .NET Aspire меняет правила игры
Aspire — это слой оркестрации для современных приложений.
Что Aspire делает из коробки:
• Service discovery → никаких хардкодных URL или портов
• Injection конфигураций → базы данных и кеши подключаются автоматически
• Встроенная наблюдаемость → логи, метрики, трассировки, готово с первого дня
• Локальная оркестрация → запускаем всю систему одной командой
• Production-ready деплой → через Docker Compose
• Cloud-ready деплой → Azure или AWS
Вот сам гайд
👉 @KodBlog
Теперь .NET Aspire меняет способ доставки ПО навсегда.
И многие разработчики до сих пор не осознают масштаб этого сдвига.
Docker решил хаос с окружениями
До Docker проблема «у меня работает» была ежедневной:
• Разные версии ОС
• Отсутствующие зависимости
• Сломанные окружения повсюду
Docker решил это, стандартизировав окружения через контейнеры.
Одна команда → одно и то же приложение, одинаковое поведение, везде.
Это действительно было революцией.
Но Docker не решил всё
Он пакует приложения, но связи между сервисами всё ещё настраиваются вручную:
• Всё ещё приходится управлять строками подключения
• Всё ещё самому настраивать наблюдаемость
И распределённые системы остаются сложными.
Здесь .NET Aspire меняет правила игры
Aspire — это слой оркестрации для современных приложений.
Что Aspire делает из коробки:
• Service discovery → никаких хардкодных URL или портов
• Injection конфигураций → базы данных и кеши подключаются автоматически
• Встроенная наблюдаемость → логи, метрики, трассировки, готово с первого дня
• Локальная оркестрация → запускаем всю систему одной командой
• Production-ready деплой → через Docker Compose
• Cloud-ready деплой → Azure или AWS
Вот сам гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍6
Вышел новый превью .NET для Microsoft Agent Framework! Обновлённые API, только асинхронные потоки и помощники
Подробнее: https://hubs.li/Q0410DQ-0
👉 @KodBlog
AsAIAgent. Разбираем критические изменения, новые примеры с Durable Agents и ключевые обновления пакетов.Подробнее: https://hubs.li/Q0410DQ-0
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥3👍2❤1🔥1
Я очень долго не знал, что в Swagger есть такая фича. Даже не задумывался о ней до недавнего времени.
Совет:
Если ты тоже об этом не знал, это вполне может сэкономить тебе немного времени!
👉 @KodBlog
Совет:
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
// подожди… он ЗАПОМИНАЕТ мой Bearer Token?!
// даже после полного обновления браузера…
c.EnablePersistAuthorization();
// на один клик меньше, на одно лишнее дёрганье мышью меньше
c.EnableTryItOutByDefault();
});
}
Если ты тоже об этом не знал, это вполне может сэкономить тебе немного времени!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24❤4🤯2
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
ASP.NET Core roadmap for .NET 11 · Issue #64787 · dotnet/aspnetcore
ASP.NET Core planning for .NET 11 is now in progress! This roadmap is currently just a placeholder. We'll update the roadmap with specific planned features as planning progresses. This issue re...
❤4
Перестаньте использовать булевые параметры.
Когда читаешь такой код, приходится останавливаться и думать.
Что значит
Это называется flag argument.
Он заставляет лезть в определение метода, чтобы понять намерение.
Решение: заменяйте размытые булевые значения явными методами.
Вместо
✅ Намерение очевидно.
✅ Язык читается естественно.
✅ Комментарии не нужны.
Код читают намного чаще, чем пишут.
👉 @KodBlog
user.SetStatus(true)Когда читаешь такой код, приходится останавливаться и думать.
Что значит
true? Активен? Подтверждён? Удалён?Это называется flag argument.
Он заставляет лезть в определение метода, чтобы понять намерение.
Решение: заменяйте размытые булевые значения явными методами.
Вместо
SetStatus(true) используйте user.Activate().Код читают намного чаще, чем пишут.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤4👎1
Деплой и апгрейд сервисов это всегда риск. В этом посте разбираем, как этот риск снижать.
Диаграмма выше показывает самые частые подходы.
▪️ Multi-Service Deployment
В этой модели мы выкатываем изменения сразу в несколько сервисов одновременно. Реализовать просто. Но из-за того, что все сервисы обновляются в один момент, сложно управлять и тестировать зависимости. И так же сложно безопасно откатиться.
▪️ Blue-Green Deployment
В blue-green деплое есть две одинаковые среды: одна staging (blue), другая production (green). Staging на одну версию впереди прода. Когда тесты в staging пройдены, пользовательский трафик переключается на staging, и staging становится продом. У этой стратегии простой rollback, но держать две одинаковые прод-качества среды может быть дорого.
▪️ Canary Deployment
Canary-деплой обновляет сервисы постепенно, каждый раз только для части пользователей. Это дешевле, чем blue-green, и откатываться тоже удобно. Но так как staging-среды нет, тестировать приходится на проде. Процесс сложнее, потому что нужно мониторить canary и шаг за шагом переводить все больше пользователей со старой версии на новую.
▪️ A/B Test
В A/B тесте разные версии сервисов одновременно крутятся в проде. Каждая версия проводит “эксперимент” на своей доле пользователей. Это дешевый способ проверять новые фичи в проде. При этом нужно жестко контролировать деплой, чтобы какие-то фичи случайно не уехали пользователям.
Твой ход: какую стратегию деплоя ты использовал? Были ли у тебя продовые инциденты из-за деплоя, и почему они случились?
👉 @KodBlog
Диаграмма выше показывает самые частые подходы.
В этой модели мы выкатываем изменения сразу в несколько сервисов одновременно. Реализовать просто. Но из-за того, что все сервисы обновляются в один момент, сложно управлять и тестировать зависимости. И так же сложно безопасно откатиться.
В blue-green деплое есть две одинаковые среды: одна staging (blue), другая production (green). Staging на одну версию впереди прода. Когда тесты в staging пройдены, пользовательский трафик переключается на staging, и staging становится продом. У этой стратегии простой rollback, но держать две одинаковые прод-качества среды может быть дорого.
Canary-деплой обновляет сервисы постепенно, каждый раз только для части пользователей. Это дешевле, чем blue-green, и откатываться тоже удобно. Но так как staging-среды нет, тестировать приходится на проде. Процесс сложнее, потому что нужно мониторить canary и шаг за шагом переводить все больше пользователей со старой версии на новую.
В A/B тесте разные версии сервисов одновременно крутятся в проде. Каждая версия проводит “эксперимент” на своей доле пользователей. Это дешевый способ проверять новые фичи в проде. При этом нужно жестко контролировать деплой, чтобы какие-то фичи случайно не уехали пользователям.
Твой ход: какую стратегию деплоя ты использовал? Были ли у тебя продовые инциденты из-за деплоя, и почему они случились?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥3❤1
Что мне реально нравится в C#
Это не какая-то огромная или супер-впечатляющая фича, но мне заходит вот такое:
Наверное потому что это близко к C и ассемблеру, поэтому такие штуки мне особенно кайфовые :-D
Почти всегда лучше дать компилятору сделать свою работу: он оптимизирует лучше, чем мы руками. Поэтому такие фичи и полезны.
Трюк и самая сложная часть для разработчика это понимать, когда компилятор что-то оптимизирует, а когда нет. И без понимания, как эти штуки устроены, и без чтения release notes ты этого просто не узнаешь.
Раньше было так: переписал LINQ-запрос и почти всегда получал ускорение. Но в .NET 10 это уже не так, потому что теперь он оптимизирует и LINQ тоже.
Вообще на современном .NET 10 и актуальной версии C# стало как никогда просто писать код на C#, который по перформансу близок к C++, а иногда даже обгоняет его. Потому что теперь есть LibraryImport, и он может генерировать MSIL-интероп код без runtime marshalling...
По сути, единственный реально сильный аргумент против C# вместо системных языков сейчас это сборщик мусора.
Если GC в твоем кейсе неприемлем, тогда да, бери системный язык. Но если GC не критичен, и ты не пишешь драйвер или код под embedded, то скорее всего C# тебе ок.
GC это реально единственное, что мешает делать AAA 3D игры на C#.
Но даже это сейчас довольно управляемо благодаря stackalloc, Memory<T>, Span<T> и ref struct.
Пулы памяти тоже теперь есть: можно создавать объекты из пула и переиспользовать RAM, что отлично для GPU-сцен, где хочется минимум мусора и аллокаций.
👉 @KodBlog
Это не какая-то огромная или супер-впечатляющая фича, но мне заходит вот такое:
if (element is { Name: "tileset" })
{
...
}Наверное потому что это близко к C и ассемблеру, поэтому такие штуки мне особенно кайфовые :-D
Почти всегда лучше дать компилятору сделать свою работу: он оптимизирует лучше, чем мы руками. Поэтому такие фичи и полезны.
Трюк и самая сложная часть для разработчика это понимать, когда компилятор что-то оптимизирует, а когда нет. И без понимания, как эти штуки устроены, и без чтения release notes ты этого просто не узнаешь.
Раньше было так: переписал LINQ-запрос и почти всегда получал ускорение. Но в .NET 10 это уже не так, потому что теперь он оптимизирует и LINQ тоже.
Вообще на современном .NET 10 и актуальной версии C# стало как никогда просто писать код на C#, который по перформансу близок к C++, а иногда даже обгоняет его. Потому что теперь есть LibraryImport, и он может генерировать MSIL-интероп код без runtime marshalling...
По сути, единственный реально сильный аргумент против C# вместо системных языков сейчас это сборщик мусора.
Если GC в твоем кейсе неприемлем, тогда да, бери системный язык. Но если GC не критичен, и ты не пишешь драйвер или код под embedded, то скорее всего C# тебе ок.
GC это реально единственное, что мешает делать AAA 3D игры на C#.
Но даже это сейчас довольно управляемо благодаря stackalloc, Memory<T>, Span<T> и ref struct.
Пулы памяти тоже теперь есть: можно создавать объекты из пула и переиспользовать RAM, что отлично для GPU-сцен, где хочется минимум мусора и аллокаций.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13
This media is not supported in your browser
VIEW IN TELEGRAM
Как можно использовать состояние при работе с MediatR?
Популярный nuget-пакет MediatR по умолчанию не делает хендлеры stateful. То есть при обработке сообщения каждый раз создается новый инстанс хендлера.
Само по себе это не проблема, и я уверен, что это осознанное архитектурное решение... Но бывают ситуации, когда хочется иметь хотя бы какое-то состояние.
Например, что если тебе нужен кэш?
Самое простое решение: вынести ответственность за состояние в отдельный компонент. А дальше пусть dependency injection подсовывает этот компонент в хендлер.
Проблема решена✌️
Полное видео тут
👉 @KodBlog
Популярный nuget-пакет MediatR по умолчанию не делает хендлеры stateful. То есть при обработке сообщения каждый раз создается новый инстанс хендлера.
Само по себе это не проблема, и я уверен, что это осознанное архитектурное решение... Но бывают ситуации, когда хочется иметь хотя бы какое-то состояние.
Например, что если тебе нужен кэш?
Самое простое решение: вынести ответственность за состояние в отдельный компонент. А дальше пусть dependency injection подсовывает этот компонент в хендлер.
Проблема решена
Полное видео тут
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🥴1
Git Tip: юзай команду
👉 @KodBlog
git checkout -, чтобы быстро переключаться на предыдущую ветку, с которой ты только что работал.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🥴7😁2🔥1😐1
Начиная с Entity Framework 10 у нас появилась поддержка именованных (и нескольких) query filters 🥳
👉 @KodBlog
// Entity Framework 10 will support Named query filters:
modelBuilder.Entity<Blog>()
.HasQueryFilter("SoftDeletionFlter", b => !b.IsDeleted)
.HasQueryFilter("TenantFilter", b => b.TenantId == tenantId);
// this allows us to remove explicit query filters:
var allBlogs = await
context.Blogs.IgnoreQueryFilters(["SoftDeletionFlter"]).ToListAsync();
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
API Gateway как RESTful-микросервис (версия 6.0)
Эта новая версия поддерживает .NET 10.
То есть теперь поддерживаются .NET 8/9/10.
hubs.li/Q041B9js0
👉 @KodBlog
Эта новая версия поддерживает .NET 10.
То есть теперь поддерживаются .NET 8/9/10.
hubs.li/Q041B9js0
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔2
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4🔥3
Если ты все еще сидишь на Swashbuckle в .NET 10, то вот что ты пропустил.
Swashbuckle нормально не обновлялся уже больше года. Поэтому Microsoft убрали его из шаблонов .NET 9+ и сделали свой встроенный вариант.
Замена:
Встроенный, легче, поддерживается и развивается.
UI: Scalar лучше, чем Swagger UI. Быстрее, выглядит приятнее, и темная тема есть из коробки.
Миграция реально на 5 минут: убираешь Swashbuckle, добавляешь
Статья, которая поможет переехать: https://codewithmukesh.com/blog/dotnet-swagger-alternatives-openapi/
👉 @KodBlog
Swashbuckle нормально не обновлялся уже больше года. Поэтому Microsoft убрали его из шаблонов .NET 9+ и сделали свой встроенный вариант.
Замена:
Microsoft.AspNetCore.OpenApiВстроенный, легче, поддерживается и развивается.
UI: Scalar лучше, чем Swagger UI. Быстрее, выглядит приятнее, и темная тема есть из коробки.
Миграция реально на 5 минут: убираешь Swashbuckle, добавляешь
builder.Services.AddOpenApi(), и готово.Статья, которая поможет переехать: https://codewithmukesh.com/blog/dotnet-swagger-alternatives-openapi/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥4👎2