🧑💻 Больше не нужно открывать терминал от администратора
На Linux и macOS всё просто: нужны права администратора, добавили
Что это такое
Как включить
Через настройки: Параметры → Система → Для разработчиков → Включить sudo.
Или через командную строку с правами администратора:
Три режима работы
Переключение между режимами:
Примеры использования
Редактирование системного файла:
Установка глобального npm-пакета:
Проверка сетевых соединений:
Про безопасность
При запуске через
Что нужно учесть
Инструмент доступен только на Windows 11, начиная с версии 24H2. Управлять им можно через настройки, командную строку или реестр (
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
На Linux и macOS всё просто: нужны права администратора, добавили
sudo перед командой. На Windows для этого приходилось открывать новый терминал от имени администратора, делать правый клик, подтверждать UAC. Microsoft наконец добавила sudo в Windows 11 нативно, начиная со сборки 26045.Что это такое
Sudo for Windows позволяет запускать команды с правами администратора прямо из обычного терминала, без переоткрытия сессии. Это не порт Unix-утилиты, а отдельная Windows-реализация той же идеи. Некоторые детали поведения отличаются от привычного sudo на Linux.Как включить
Через настройки: Параметры → Система → Для разработчиков → Включить sudo.
Или через командную строку с правами администратора:
sudo config --enable normal
Три режима работы
forceNewWindow — режим по умолчанию. Команда запускается в новом окне с правами администратора. Похоже на runas, но удобнее.disableInput — команда выполняется в текущем окне, но без возможности ввода. Подходит для автоматических задач, где интерактивный ввод не нужен.normal — полный инлайн-режим, как на Linux. Команда запускается в текущем окне и может принимать ввод. Наиболее удобный вариант, но несёт больше рисков безопасности.Переключение между режимами:
sudo config --enable forceNewWindow
sudo config --enable disableInput
sudo config --enable normal
Примеры использования
Редактирование системного файла:
sudo notepad C:\Windows\System32\drivers\etc\hosts
Установка глобального npm-пакета:
sudo npm install -g package-name
Проверка сетевых соединений:
sudo netstat -ab
Про безопасность
При запуске через
sudo появляется UAC-запрос на подтверждение. Режимы disableInput и normal несут дополнительные риски: нежелательный процесс с низкими правами теоретически может взаимодействовать с повышенным процессом. Для большинства сценариев рекомендован forceNewWindow.Что нужно учесть
Инструмент доступен только на Windows 11, начиная с версии 24H2. Управлять им можно через настройки, командную строку или реестр (
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Sudo). Есть и GPO-политика для корпоративного управления.📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2😁1
Когда в коллекции хранятся объекты разных типов, обычный перебор с ручной проверкой
is или as быстро превращается в шаблонный код. OfType<T> решает это в одну строку.Пример:
var mixedList = new List<object> { 1, "hello", 2.5, "world", 3, true };
var stringsOnly = mixedList.OfType<string>();
// Результат: hello, worldИз шести элементов метод выбирает только строки. Числа, булево значение и
double игнорируются.Как это работает под капотом
OfType<T> использует оператор is для каждого элемента. Примерно так выглядит его реализация:public static IEnumerable<T> OfType<T>(this IEnumerable source)
{
foreach (var item in source)
{
if (item is T typed)
yield return typed;
}
}
Метод ленивый: перебор происходит только при итерации по результату, не сразу при вызове.
Когда использовать
Удобно при работе с
IEnumerable<object>, коллекциями ArrayList из старого кода, или когда нужно вытащить конкретный тип из гетерогенной иерархии объектов.var textBoxes = Controls.OfType<TextBox>();
Чем отличается от
Cast<T>Cast<T> бросает InvalidCastException, если встречает несовместимый тип. OfType<T> просто пропускает такой элемент. Если коллекция точно однородная и ошибка должна сигнализировать о проблеме, уместен Cast<T>. В остальных случаях безопаснее OfType<T>.📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤5😁1
🗺 Группировка меток в картах MAUI
Если на карте десятки или сотни меток, они сливаются в непроходимую кашу. В .NET MAUI 11 Preview 3 появилась кластеризация меток из коробки на Android и iOS/Mac Catalyst.
Как включить
Одно свойство:
Ближайшие метки автоматически группируются в кластер с числом внутри. При увеличении масштаба кластер раскрывается до отдельных пинов.
Разные группы кластеров
Если нужно, чтобы кофейни кластеризовались отдельно от парков, используем
Пины с одинаковым идентификатором группируются вместе. С разными — образуют независимые кластеры, даже если географически рядом. Пины без идентификатора попадают в общую группу по умолчанию.
Обработка нажатия на кластер
При тапе на кластер срабатывает событие
В
•
•
•
Платформенные детали
На Android кластеризация работает через собственный алгоритм на основе сетки, пересчитывается при смене масштаба. Сторонние зависимости не нужны.
На iOS и Mac Catalyst используется нативный
Пример с кластеризацией уже есть в репозитории, страница
➡️ Блог разработчиков
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Если на карте десятки или сотни меток, они сливаются в непроходимую кашу. В .NET MAUI 11 Preview 3 появилась кластеризация меток из коробки на Android и iOS/Mac Catalyst.
Как включить
Одно свойство:
<maps:Map IsClusteringEnabled="True" />
Ближайшие метки автоматически группируются в кластер с числом внутри. При увеличении масштаба кластер раскрывается до отдельных пинов.
Разные группы кластеров
Если нужно, чтобы кофейни кластеризовались отдельно от парков, используем
ClusteringIdentifier на Pin:map.Pins.Add(new Pin
{
Label = "Pike Place Coffee",
Location = new Location(47.6097, -122.3331),
ClusteringIdentifier = "coffee"
});
map.Pins.Add(new Pin
{
Label = "Occidental Square",
Location = new Location(47.6064, -122.3325),
ClusteringIdentifier = "parks"
});
Пины с одинаковым идентификатором группируются вместе. С разными — образуют независимые кластеры, даже если географически рядом. Пины без идентификатора попадают в общую группу по умолчанию.
Обработка нажатия на кластер
При тапе на кластер срабатывает событие
ClusterClicked:map.ClusterClicked += async (sender, e) =>
{
string names = string.Join("\n", e.Pins.Select(p => p.Label));
await DisplayAlert(
$"Кластер ({e.Pins.Count} меток)",
names,
"OK");
// Отменить стандартное приближение к кластеру:
// e.Handled = true;
};
В
ClusterClickedEventArgs три поля: •
Pins — список пинов в кластере•
Location — географический центр•
Handled — если true, стандартное поведение (зум к кластеру) отменяется.Платформенные детали
На Android кластеризация работает через собственный алгоритм на основе сетки, пересчитывается при смене масштаба. Сторонние зависимости не нужны.
На iOS и Mac Catalyst используется нативный
MKClusterAnnotation из MapKit — анимации и поведение платформенные.Пример с кластеризацией уже есть в репозитории, страница
Clustering в проекте MapDemo.📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2😁1
Лайфхак, который используют единицы: найти профили людей с нужным тайтлом, которые уже устроились и проанализировать их через ИИ.
200–300 профилей дадут чёткую картину: в чём вы сильнее рынка, где сливаете на фоне конкурентов и что исправить в резюме прямо сейчас.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Тема:
Как эффективно управлять контекстным окном LLM в мультиагентных системах и не сливать бюджет на токены
В кружке Кирилл рассказал, какие именно подходы будем разбирать.
👉 Занять место на вебинаре
Please open Telegram to view this post
VIEW IN TELEGRAM
😁2❤1
Microsoft выпустила внеплановый патч для .NET 10. Причина — баг в пакете
Microsoft.AspNetCore.DataProtection, который попал в релиз вместе с плановым обновлением 10.0.6.Что случилось
После выхода 10.0.6 пользователи начали сообщать, что расшифровка данных перестала работать. Microsoft изучила проблему и обнаружила, что регрессия также открывает уязвимость CVE-2026-40372.
Суть бага: управляемый энкриптор вычислял HMAC-тег не над теми байтами полезной нагрузки, а потом и вовсе выбрасывал результат. Это приводило к повышению привилегий. Затронуты версии
Microsoft.AspNetCore.DataProtection от 10.0.0 до 10.0.6 включительно.Кого это касается
Всех, кто использует ASP.NET Core Data Protection в приложениях на .NET 10. Это стандартный механизм защиты данных в ASP.NET Core — сессии, антифоргери-токены, куки и всё, что шифруется через
IDataProtector.Что делать
Обновить пакет
Microsoft.AspNetCore.DataProtection до версии 10.0.7 как можно скорее:dotnet add package Microsoft.AspNetCore.DataProtection --version 10.0.7
После обновления пакета пересобрать и перевыложить приложение. Проверить текущую версию SDK можно командой:
dotnet --info
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤5😁3
Старший Backend C# ASP. NET разработчик — от 300 000 до 400 000 ₽ , удалёнка или гибрид в Москве
Разработчик C# — офис в Минске
Unity Developer — удалёнка
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3😁1
🛠 Native AOT в Node.js: пишем аддоны на C#
Исторически для платформоспецифичных задач в VS Code расширении (например, чтение реестра Windows) использовались нативные аддоны на C++. Их сборка требовала
Решение
Native AOT умеет компилировать .NET-код в нативную shared library с произвольными точками входа. Node.js аддоны требуют только одного: экспортированной функции
Как это работает
Аддон взаимодействует с Node.js через N-API — стабильный C-совместимый интерфейс. Язык реализации значения не имеет, важно лишь соответствие сигнатурам.
Минимальный
Точка входа модуля:
Атрибут
Вызов N-API из .NET
N-API функции экспортирует сам
После этого P/Invoke с именем
Пример экспортируемой функции
Функция читает значение из реестра Windows и возвращает его в JavaScript:
Исключения нужно обязательно перехватывать: необработанное исключение в методе с
Что в итоге
Команда убрала зависимость от Python и
Производительность сопоставима с C++-реализацией: Native AOT генерирует оптимизированный нативный код, а для задач типа доступа к реестру и маршалинга строк разницы на практике нет.
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Исторически для платформоспецифичных задач в VS Code расширении (например, чтение реестра Windows) использовались нативные аддоны на C++. Их сборка требовала
node-gyp и конкретной версии Python на каждой машине разработчика. Для .NET-команды это лишняя зависимость, которую нужно поддерживать и в CI, и при онбординге новых участников.Решение
Native AOT умеет компилировать .NET-код в нативную shared library с произвольными точками входа. Node.js аддоны требуют только одного: экспортированной функции
napi_register_module_v1. Native AOT с этим справляется.Как это работает
Аддон взаимодействует с Node.js через N-API — стабильный C-совместимый интерфейс. Язык реализации значения не имеет, важно лишь соответствие сигнатурам.
Минимальный
.csproj:<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PublishAot>true</PublishAot>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
PublishAot говорит SDK собрать нативную библиотеку при публикации. AllowUnsafeBlocks нужен из-за работы с указателями при интеропе с N-API.Точка входа модуля:
[UnmanagedCallersOnly(
EntryPoint = "napi_register_module_v1",
CallConvs = [typeof(CallConvCdecl)])]
public static nint Init(nint env, nint exports)
{
Initialize();
RegisterFunction(env, exports, "readStringValue"u8, &ReadStringValue);
return exports;
}
Атрибут
[UnmanagedCallersOnly] экспортирует метод с нужным именем и calling convention. Суффикс u8 создаёт ReadOnlySpan<byte> с UTF-8 строкой без аллокаций.Вызов N-API из .NET
N-API функции экспортирует сам
node.exe. Чтобы не линковаться с отдельной библиотекой, используется кастомный резолвер через NativeLibrary.SetDllImportResolver:NativeLibrary.SetDllImportResolver(
Assembly.GetExecutingAssembly(),
(libraryName, assembly, searchPath) =>
libraryName is "node"
? NativeLibrary.GetMainProgramHandle()
: 0);
После этого P/Invoke с именем
"node" будет резолвиться в хост-процесс:[LibraryImport("node", EntryPoint = "napi_create_string_utf8")]
internal static partial Status CreateStringUtf8(
nint env, ReadOnlySpan<byte> str, nuint length, out nint result);Пример экспортируемой функции
Функция читает значение из реестра Windows и возвращает его в JavaScript:
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
private static nint ReadStringValue(nint env, nint info)
{
try
{
var keyPath = GetStringArg(env, info, 0);
var valueName = GetStringArg(env, info, 1);
if (keyPath is null || valueName is null)
{
ThrowError(env, "Expected two string arguments: keyPath, valueName");
return 0;
}
using var key = Registry.CurrentUser.OpenSubKey(keyPath, writable: false);
return key?.GetValue(valueName) is string value
? CreateString(env, value)
: GetUndefined(env);
}
catch (Exception ex)
{
ThrowError(env, $"Registry read failed: {ex.Message}");
return 0;
}
}
Исключения нужно обязательно перехватывать: необработанное исключение в методе с
[UnmanagedCallersOnly] крашит хост-процесс. ThrowError пробрасывает ошибку в JavaScript как стандартный Error.Что в итоге
Команда убрала зависимость от Python и
node-gyp. Теперь yarn install работает только с Node.js и .NET SDK, которые и так нужны для разработки. CI стал проще, онбординг быстрее.Производительность сопоставима с C++-реализацией: Native AOT генерирует оптимизированный нативный код, а для задач типа доступа к реестру и маршалинга строк разницы на практике нет.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5😁1
Представьте картину: CPU загружен на 30–40%, ошибок нет, но запросы внезапно начинают тормозить, а время ответа под нагрузкой улетает в небо. Это не магия и не баг в инфраструктуре. Скорее всего, вы столкнулись с голоданием пула потоков.
Потоки это ваша пропускная способность. Каждый заблокированный поток это запрос, который ждёт в очереди. Когда таких потоков становится много, латентность взрывается, хотя CPU при этом спокойно отдыхает.
Причина почти всегда в одном из таких паттернов:
var data = httpClient.GetStringAsync(url).Result; // блокирует поток
Task.Run(() => DoWork()).Wait(); // форсированная синхронизация
Эти вызовы берут асинхронную операцию и намеренно блокируют поток до её завершения. В результате поток занят, но не делает ничего полезного, а просто ждёт.
Попробуйте сделать так и замеряйте результат:
var data = await httpClient.GetStringAsync(url);
📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱8❤3👍2😁1🤔1
Валидация входящих данных в .NET-проектах это рутина, которую каждый решает по-своему. Кто-то пишет
if (value == null) throw new ArgumentNullException(...) в каждом методе, кто-то тащит FluentValidation и настраивает его под свои нужды. OrionGuard предлагает ещё один вариант: fluent-интерфейс, поддержку ASP.NET Core, MediatR, Blazor, gRPC и SignalR. Всё в одной экосистеме.Установка базового пакета:
dotnet add package OrionGuard
Простая валидация выглядят так:
using Moongazing.OrionGuard.Core;
using Moongazing.OrionGuard.Extensions;
Ensure.That(email).NotNull().NotEmpty().Email();
Ensure.That(age).InRange(18, 120);
Если нужна производительность без аллокаций, то есть
FastGuard на основе Span<T>:FastGuard.NotNullOrEmpty(name, nameof(name));
FastGuard.Email(email, nameof(email));
Что внутри
Библиотека разбита на 9 пакетов. Каждый подключается отдельно.
OrionGuard — ядро. OrionGuard.AspNetCore — middleware, фильтры, интеграция с IOptions. OrionGuard.MediatR — автоматическая валидация в CQRS-пайплайне. OrionGuard.Generators — source-генераторы для компайл-тайм валидации без рефлексии. OrionGuard.Blazor — интеграция с EditForm. OrionGuard.Grpc и OrionGuard.SignalR — перехватчики для gRPC и SignalR.Несколько конкретных примеров
Накопление ошибок без исключений:
var result = GuardResult.Combine(
Ensure.Accumulate(email, "Email").NotNull().Email().ToResult(),
Ensure.Accumulate(password, "Password").MinLength(8).ToResult()
);
if (result.IsInvalid)
return BadRequest(result.ToErrorDictionary());
Защита от SQL-инъекций и XSS:
userInput.AgainstSqlInjection(nameof(userInput));
userInput.AgainstXss(nameof(userInput));
filePath.AgainstPathTraversal(nameof(filePath));
Вложенная валидация с путями до поля:
var result = Validate.Nested(order)
.Property(o => o.OrderNumber, p => p.NotEmpty())
.Nested(o => o.Customer, customer => customer
.Property(c => c.Email, p => p.NotEmpty().Email())
.Nested(c => c.Address, address => address
.Property(a => a.ZipCode, p => p.NotEmpty())))
.Collection(o => o.Items, (item, _) => item
.Property(i => i.Quantity, p => p.GreaterThan(0)))
.ToResult();
// Ошибки будут выглядеть так: "Customer.Address.ZipCode", "Items[2].Quantity"
Динамические правила из JSON. Для случаев, когда правила хранятся в базе или конфиге:
var json = """
{
"Rules": [
{ "PropertyName": "Email", "RuleType": "Email" },
{ "PropertyName": "Age", "RuleType": "Range", "Parameters": { "Min": 18, "Max": 120 } }
]
}
""";
var validator = DynamicValidator.FromJson(json);
var result = validator.Validate(userDto);
Source-генератор для NativeAOT:
[GenerateValidator]
public sealed class CreateUserRequest
{
[NotNull, NotEmpty, Length(3, 50)]
public string Name { get; set; }
[NotNull, Email]
public string Email { get; set; }
}
// Валидатор генерируется на этапе компиляции — без рефлексии
var result = CreateUserRequestValidator.Validate(request);
Интеграция с ASP.NET Core:
// Program.cs
builder.Services.AddOrionGuardAspNetCore();
app.MapPost("/api/users", (CreateUserRequest req) => { ... })
.WithValidation<CreateUserRequest>();
Библиотека поддерживает 14 языков для сообщений об ошибках, включая русский. Есть слой совместимости с FluentValidation, миграция сводится к замене
using. Все regex-паттерны генерируются через GeneratedRegex, FrozenSet используется для O(1)-поиска в security-паттернах.📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3
Это классика технических интервью в C#:
Статический конструктор — когда именно его вызывает рантайм
Вы не пишете
new MyClass(), не обращаетесь к объекту, не делаете вообще ничего явного. А он всё равно срабатывает.📍 Навигация: Вакансии • Задачи • Собесы
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7😁1
🛠 Структуры не всегда быстрее
Распространённое заблуждение среди разработчиков на C#, что структуры всегда эффективнее классов. На самом деле это работает только для маленьких структур.
Структуры живут на стеке и не создают нагрузку на GC. Но у этого есть цена: при каждой передаче структуры в метод или присваивании создаётся полная копия. Для маленьких структур это быстро. Для больших не очень.
Вот пример структуры, которая выглядит безобидно, но копирует 64+ байт при каждом вызове:
Обратите внимание на List<Items>. Как только структура содержит ссылочные типы, часть преимуществ стека теряется, ведь ссылка всё равно уходит в кучу.
Для маленьких значений без ссылочных типов
Для всего остального
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор
Распространённое заблуждение среди разработчиков на C#, что структуры всегда эффективнее классов. На самом деле это работает только для маленьких структур.
Структуры живут на стеке и не создают нагрузку на GC. Но у этого есть цена: при каждой передаче структуры в метод или присваивании создаётся полная копия. Для маленьких структур это быстро. Для больших не очень.
Вот пример структуры, которая выглядит безобидно, но копирует 64+ байт при каждом вызове:
// Копируется целиком при каждой передаче
public struct BigOrderStruct
{
public int Id;
public string Customer;
public decimal Total;
// ... ещё 12 полей
public List<Item> Items; // это уже ссылочный тип
}
Обратите внимание на List<Items>. Как только структура содержит ссылочные типы, часть преимуществ стека теряется, ведь ссылка всё равно уходит в кучу.
Для маленьких значений без ссылочных типов
readonly record struct идеален:public readonly record struct SmallOrderId(int Id);
Для всего остального
readonly record class чаще выигрывает и по читаемости, и по производительности за счёт лучшего поведения кэша.📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2😁2
Вышел Ubuntu 26.04 LTS. Вместе с ним официальная поддержка .NET 10 прямо из стандартного репозитория.
Две команды и SDK готов:
sudo apt update
sudo apt install dotnet-sdk-10.0
Проверить, что всё работает:
dotnet run - << 'EOF'
using System.Runtime.InteropServices;
Console.WriteLine($"Hello {RuntimeInformation.OSDescription} from .NET {RuntimeInformation.FrameworkDescription}");
EOF
Вывод будет примерно таким:
Hello Ubuntu Resolute Raccoon from .NET .NET 10.0.5
Это так называемый file-based app. Он передаётся через
stdin напрямую в dotnet run. Стандартный unix-подход.Контейнеры
Образы с тегом
resolute уже доступны. Если вы использовали -noble, достаточно поменять суффикс:sed -i "s/noble/resolute/g" Dockerfile.chiseled
После этого собрать и запустить с ограничениями ресурсов:
docker build --pull -t aspnetapp -f Dockerfile.chiseled .
docker run --rm -it -p 8000:8080 -m 50mb --cpus .5 aspnetapp
Chiseled-образы остались, ничего не убрали
Native AOT
Если нужен маленький бинарь с быстрым стартом —
dotnet-sdk-aot-10.0 теперь в репозитории Ubuntu.Установка:
apt install -y dotnet-sdk-aot-10.0 clang
Публикация простого приложения:
dotnet publish app.cs
Результат:
1.4M artifacts/app/app
3.0M artifacts/app/app.dbg
Запуск занял 3 миллисекунды. Для веб-сервиса с
PublishAot=true итоговый размер около 13 МБ вместе с метаданными System.Text.Json..NET 8 и 9 не входят в основной репозиторий Ubuntu 26.04, но доступны через отдельный PPA от Canonical:
apt install -y software-properties-common
add-apt-repository ppa:dotnet/backports
После подключения появятся пакеты
dotnet-sdk-8.0, dotnet-sdk-9.0 и соответствующие aspnetcore-runtime-*. Поддержка там на уровне "best-effort", то есть официально, но без гарантий уровня LTS.Что важно
Ubuntu 26.04 принёс три заметных изменения на уровне ОС:
• Linux 7.0 — команда .NET начнёт тестирование, как только получит VM.
• Постквантовая криптография — поддержка уже есть в .NET 10.
• Удаление cgroup v1. Переход на cgroup v2 в .NET сделали несколько лет назад, так что сломаться ничего не должно.
Если переходите на Ubuntu 26.04 в продакшне, то всё основное готово с первого дня.
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤1😁1
🛠 От горизонтальных слоёв к вертикальным срезам
Структура
Чтобы разобраться в одной фиче, приходится прыгать между тремя папками. Когда фича сложная код размазан по десятку файлов, и никто не держит в голове полную картину
Проблема: классические слои
Фича в типичном проекте выглядит так:
Каждый из файлов знает только о своём слое. Хотите понять одну операцию — обходите весь проект.
Вертикальные срезы
Принцип простой: код, который меняется вместе живёт вместе.
Вместо горизонтальных слоёв на весь проект вертикальные срезы: один срез на одну фичу. Всё нужное в одной папке:
Один файл содержит команду, валидацию и обработчик:
Пример использует MediatR для pipeline и Carter для регистрации. Они удобны, но не обязательны. Главное — положение кода
Что получаем
Высокая связность. Новый разработчик открывает одну папку и видит фичу целиком — от входа до выхода.
Низкое зацепление. Изменения в одном срезе не затрагивают другие. Никакого страха "а вдруг сломается что-то в другом месте".
Конец раздутым сервисам.
А что с дублированием
Между срезами иногда появляется похожий код. Это нормально.
Цена небольшого дублирования несравнимо меньше, чем цена высокого зацепления и низкой связности, которые приносят горизонтальные слои. Долгосрочно это огромная победа.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Структура
Controllers / Services / Models настолько привычна, что мы перестали её замечать. Но она главный источник боли по мере роста проекта.Чтобы разобраться в одной фиче, приходится прыгать между тремя папками. Когда фича сложная код размазан по десятку файлов, и никто не держит в голове полную картину
Проблема: классические слои
Фича в типичном проекте выглядит так:
Controllers/ProductsController.cs
Services/IProductService.cs
Services/ProductService.cs
Models/CreateProductRequest.cs
Каждый из файлов знает только о своём слое. Хотите понять одну операцию — обходите весь проект.
Вертикальные срезы
Принцип простой: код, который меняется вместе живёт вместе.
Вместо горизонтальных слоёв на весь проект вертикальные срезы: один срез на одну фичу. Всё нужное в одной папке:
Features/
Products/
CreateProduct/
CreateProduct.cs ← всё здесь
Один файл содержит команду, валидацию и обработчик:
public static class CreateProduct
{
// Входные данные
public record Command(string Name, decimal Price) : IRequest<Guid>;
// Валидация
public class Validator : AbstractValidator<Command>
{
public Validator()
{
RuleFor(x => x.Name).NotEmpty();
RuleFor(x => x.Price).GreaterThan(0);
}
}
// Логика
internal class Handler(AppDbContext db) : IRequestHandler<Command, Guid>
{
public async Task<Guid> Handle(Command req, CancellationToken ct)
{
var product = new Product { Name = req.Name, Price = req.Price };
db.Products.Add(product);
await db.SaveChangesAsync(ct);
return product.Id;
}
}
}
Пример использует MediatR для pipeline и Carter для регистрации. Они удобны, но не обязательны. Главное — положение кода
Что получаем
Высокая связность. Новый разработчик открывает одну папку и видит фичу целиком — от входа до выхода.
Низкое зацепление. Изменения в одном срезе не затрагивают другие. Никакого страха "а вдруг сломается что-то в другом месте".
Конец раздутым сервисам.
IProductService неизбежно превращается в класс на тысячу строк с двадцатью ответственностями. Handler делает ровно одно дело.А что с дублированием
Между срезами иногда появляется похожий код. Это нормально.
Цена небольшого дублирования несравнимо меньше, чем цена высокого зацепления и низкой связности, которые приносят горизонтальные слои. Долгосрочно это огромная победа.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔3😁2❤1😢1
🔄 Мелкий релиз с нужными правками API
Вышел релиз v6.2.0 библиотеки OrionGuard для валидации в .NET. Версия небольшая, но устраняет несколько неудобств, которые вылезли при написании демо к v6.1.0.
Что добавили
Появился интерфейс
Добавили абстрактный record
Сгенерированные struct-идентификаторы теперь реализуют
Source-генератор стал умнее: он проверяет во время компиляции, подключён ли EF Core, и генерирует
Что изменили
Все sub-пакеты переименованы — префикс
И так далее для
C#-пространства имён и структура папок не изменились. Существующие
Миграция с v6.1.0
В
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#async_news
Вышел релиз v6.2.0 библиотеки OrionGuard для валидации в .NET. Версия небольшая, но устраняет несколько неудобств, которые вылезли при написании демо к v6.1.0.
Что добавили
Появился интерфейс
IStronglyTypedId<TValue> — теперь strongly-typed ID на основе record и ID, сгенерированные source-генератором через struct, работают под одним контрактом. Guards и DI-хелперы принимают оба варианта без дополнительного кода.Добавили абстрактный record
DomainEventBase. Раньше в каждом доменном событии нужно было вручную объявлять EventId и OccurredOnUtc. Теперь достаточно унаследоваться:public sealed record OrderShippedEvent(OrderId OrderId) : DomainEventBase;
Сгенерированные struct-идентификаторы теперь реализуют
IParsable<TSelf> и ISpanParsable<TSelf>. Это значит, что route-биндинг в ASP.NET Core minimal API работает из коробки без кастомных конверторов.Source-генератор стал умнее: он проверяет во время компиляции, подключён ли EF Core, и генерирует
ValueConverter<,> только если да. Лишний код в проект не попадает.Что изменили
Все sub-пакеты переименованы — префикс
Moongazing. убрали из NuGet PackageId:Moongazing.OrionGuard.AspNetCore → OrionGuard.AspNetCoreMoongazing.OrionGuard.MediatR → OrionGuard.MediatRMoongazing.OrionGuard.Generators → OrionGuard.GeneratorsИ так далее для
Swagger, OpenTelemetry, Blazor, Grpc, SignalR.C#-пространства имён и структура папок не изменились. Существующие
using-директивы продолжают работать.Миграция с v6.1.0
В
.csproj нужно обновить ссылки на пакеты: заменить Moongazing.OrionGuard.X на OrionGuard.X. Код трогать не нужно. Если хочется убрать бойлерплейт в доменных событиях — можно добавить : DomainEventBase, но это опционально.📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1😁1
🔥 База по ИИ-агентам от научного сотрудника Сколтеха и НИУ ВШЭ
Знакомьтесь, Екатерина Трофимова. Кандидат компьютерных наук, ресерчер в Центре ИИ Сколтеха и лаборатории LAMBDA. Она объединяет глубокую академическую экспертизу и практику: знает, как ИИ-системы устроены «под капотом» и как встроить их в реальные проекты (в т.ч. для Т-банка).
Мы попросили Екатерину собрать список мастхев материалов для тех, кто хочет проектировать агентов в проде. Сохраняйте список.
🛠 Стек и фреймворки:
DSPy — алгоритмическая оптимизация промптов (вместо ручного подбора слов).
Semantic Kernel и LangMem — инструменты для управления сессионной и долгосрочной памятью.
MCP (Model Context Protocol) — новый стандарт от Anthropic для подключения агентов к вашим БД и локальным файлам.
📖 Документация, которую нужно знать:
Anthropic Prompt Caching — как кэшировать контекст и радикально резать косты на API.
OpenAI Agents SDK / Cookbook — лучшие практики работы с памятью.
Augment — платформа для оптимизации работы ИИ-агентов и контроля токенов.
🔬 Хардкорные статьи и препринты (на выходные):
Lost in the Middle — почему LLM «слепнут» на длинных текстах и забывают середину контекста.
How Do Coding Agents Spend Your Money? — куда улетает бюджет при работе автономных кодинг-агентов.
MemGPT — архитектура операционной системы для LLM с иллюзией бесконечной памяти.
InjecAgent / AgentSentry — всё о безопасности и защите агентов от инъекций в промпты.
Екатерина Трофимова — один из ключевых экспертов нашего курса AgentOps. На своих лекциях она детально разбирает, как проектировать инструменты для агентов, как агент принимает решения о вызове инструментов и какие ограничения возникают в реальном проде
🎁 Акция в честь старта продаж!
Прямо сейчас при покупке Инженерного трека вы получаете полный доступ к материалам курса «Разработка ИИ-агентов» в подарок.
👉 Забрать 2 курса по цене 1 и начать обучение
Знакомьтесь, Екатерина Трофимова. Кандидат компьютерных наук, ресерчер в Центре ИИ Сколтеха и лаборатории LAMBDA. Она объединяет глубокую академическую экспертизу и практику: знает, как ИИ-системы устроены «под капотом» и как встроить их в реальные проекты (в т.ч. для Т-банка).
Мы попросили Екатерину собрать список мастхев материалов для тех, кто хочет проектировать агентов в проде. Сохраняйте список.
🛠 Стек и фреймворки:
DSPy — алгоритмическая оптимизация промптов (вместо ручного подбора слов).
Semantic Kernel и LangMem — инструменты для управления сессионной и долгосрочной памятью.
MCP (Model Context Protocol) — новый стандарт от Anthropic для подключения агентов к вашим БД и локальным файлам.
📖 Документация, которую нужно знать:
Anthropic Prompt Caching — как кэшировать контекст и радикально резать косты на API.
OpenAI Agents SDK / Cookbook — лучшие практики работы с памятью.
Augment — платформа для оптимизации работы ИИ-агентов и контроля токенов.
🔬 Хардкорные статьи и препринты (на выходные):
Lost in the Middle — почему LLM «слепнут» на длинных текстах и забывают середину контекста.
How Do Coding Agents Spend Your Money? — куда улетает бюджет при работе автономных кодинг-агентов.
MemGPT — архитектура операционной системы для LLM с иллюзией бесконечной памяти.
InjecAgent / AgentSentry — всё о безопасности и защите агентов от инъекций в промпты.
Екатерина Трофимова — один из ключевых экспертов нашего курса AgentOps. На своих лекциях она детально разбирает, как проектировать инструменты для агентов, как агент принимает решения о вызове инструментов и какие ограничения возникают в реальном проде
🎁 Акция в честь старта продаж!
Прямо сейчас при покупке Инженерного трека вы получаете полный доступ к материалам курса «Разработка ИИ-агентов» в подарок.
👉 Забрать 2 курса по цене 1 и начать обучение
❤3😁1
Кого смотрите и читаете по C# и .NET? Авторы на YouTube, Хабре, телеграм-каналы, подкасты — пишите в комменты 💬
Мы, естественно, следим за Ником Чапсасом, но может есть менее гигантские медиа-личности?
📍 Навигация: Вакансии • Задачи • Собесы
#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3❤🔥1
Я пойду работать в понедельник, ведь в выходные..
— Внеплановое обновление .NET 10.0.7
— ИИ найдёт слабые места в вашем резюме
— Группировка меток в картах MAUI
— Sudo for Windows
— Native AOT в Node.js
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3