Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👌4
Все еще сидишь на .sln в 2026?
Давай покажу, с чем ты реально имеешь дело:
🤮 Везде GUID’ы, вечные merge-конфликты, читать невозможно.
А теперь то же самое в .slnx:
Вот и всё. Читаемо человеком, дружит с git, никаких GUID’ов.
Почему стоит мигрировать сейчас:
▪️ Поддерживается в Visual Studio 2022 (17.10+) и .NET 9+
▪️
▪️ Меньше merge-конфликтов, меньше боли в команде
▪️ В code review это наконец можно нормально читать
Как мигрировать:
Готово.
Старый формат делали под внутренности Visual Studio, не под людей. SLNX делают для разработчиков.
Все еще держишься за .sln? Почему?
👉 @KodBlog
Давай покажу, с чем ты реально имеешь дело:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyApp", "MyApp\MyApp.csproj", "{8A3B4E29-7F7D-4C51-9A18-5D8B9A3E1234}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
.... +200 more unreadable lines?А теперь то же самое в .slnx:
<Solution>
<Project Path="MyApp/MyApp.csproj" />
</Solution>
Вот и всё. Читаемо человеком, дружит с git, никаких GUID’ов.
Почему стоит мигрировать сейчас:
dotnet sln migrate делает это одной командойКак мигрировать:
dotnet sln migrate MyApp.sln
Готово.
.slnx создан.Старый формат делали под внутренности Visual Studio, не под людей. SLNX делают для разработчиков.
Все еще держишься за .sln? Почему?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍28❤4🔥1
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