Visitor позволяет добавлять операции к иерархии объектов без изменения их классов. Классический пример — обход AST, дерева документа или иерархии фигур. Вы создаёте отдельный объект-посетитель, который «обходит» структуру и выполняет нужное действие для каждого типа.
Долгое время это был единственный нормальный способ реализовать double dispatch в C#. Но начиная с C# 8 появился
switch по типам, а в C# 12 эта возможность стала ещё мощнее. И теперь Visitor выглядит как лишняя обвязка.Как выглядел Visitor
Допустим, есть иерархия фигур и нужно посчитать площадь.
public interface IShape
{
void Accept(IShapeVisitor visitor);
}
public class Circle : IShape
{
public double Radius { get; init; }
public void Accept(IShapeVisitor visitor) => visitor.Visit(this);
}
public class Rectangle : IShape
{
public double Width { get; init; }
public double Height { get; init; }
public void Accept(IShapeVisitor visitor) => visitor.Visit(this);
}
public interface IShapeVisitor
{
void Visit(Circle circle);
void Visit(Rectangle rectangle);
}
public class AreaCalculator : IShapeVisitor
{
public double Result { get; private set; }
public void Visit(Circle circle) =>
Result = Math.PI * circle.Radius * circle.Radius;
public void Visit(Rectangle rectangle) =>
Result = rectangle.Width * rectangle.Height;
}
Два интерфейса, метод
Accept в каждом классе, отдельный класс на каждую операцию. Для двух фигур это терпимо. Для десяти — уже много шаблонного кода.Как это делается через pattern matching
Тот же расчёт площади в одном
switch выражении.public static double CalculateArea(IShape shape) => shape switch
{
Circle c => Math.PI * c.Radius * c.Radius,
Rectangle r => r.Width * r.Height,
_ => throw new ArgumentException($"Unknown shape: {shape.GetType().Name}")
};
Нет интерфейса
IShapeVisitor. Нет метода Accept. Нет отдельного класса калькулятора. Логика читается сверху вниз, в одном месте.Что происходит, когда добавляется новый тип
Это ключевое отличие. Допустим, вы добавили
Triangle.В Visitor нужно добавить метод
Visit(Triangle t) в интерфейс IShapeVisitor, потом реализовать его в каждом посетителе. Если забыли — получите ошибку в рантайме. Или хуже — молчаливое некорректное поведение, если базовый класс имеет реализацию по умолчанию.В
switch выражении компилятор выдаст предупреждение, что Triangle не обработан. Вы узнаете об этом до запуска, на этапе сборки.// CS8509: The switch expression does not handle all possible values
public static double CalculateArea(IShape shape) => shape switch
{
Circle c => Math.PI * c.Radius * c.Radius,
Rectangle r => r.Width * r.Height
// Triangle не обработан — компилятор предупредит
};
Когда Visitor всё ещё уместен
Если иерархия типов находится в чужой библиотеке и вы не можете на неё влиять, а
switch по типам становится слишком длинным и разбросанным по кодовой базе — Visitor помогает собрать логику в одном месте. Также он полезен, когда операция требует сложного состояния между вызовами, которое неудобно протаскивать через отдельные методы.Но для большинства задач, где вы контролируете код и типы,
switch выражения проще, короче и безопаснее. Компилятор работает на вашей стороне, а не против вас.📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🤔3
🆚 Minimal APIs vs контроллер
ASP.NET Core предлагает два способа строить HTTP API. Minimal APIs и контроллеры. Microsoft в документации рекомендует Minimal APIs для новых проектов, потому что это меньше кода, меньше конфигурации и выше производительность. Но это не значит, что контроллеры устарели. Это значит, что нужен осознанный выбор.
Когда Minimal APIs подходят лучше
Minimal APIs хорошо работают, когда API небольшой и сфокусированный. Микросервисы, внутренние API, легковесные эндпоинты, vertical slice архитектура. Каждый эндпоинт явно определяет маршрут, нет лишней церемонии с наследованием и атрибутами.
Вот как выглядит чистый эндпоинт на Minimal API:
Читаемо, прямолинейно, бизнес-логика вынесена в
Когда контроллеры всё ещё уместны
Контроллеры полезны там, где уже есть устоявшаяся MVC-инфраструктура, стандартизированные фильтры, сложное версионирование или большая команда, привыкшая к этому паттерну. Если в проекте выстроены конвенции вокруг контроллеров и это работает, переписывать на Minimal APIs ради моды нет смысла.
Что изменилось в .NET 10
В .NET 10 Microsoft добавила поддержку валидации для Minimal APIs, включая кастомизацию ответов через
Главная ловушка обоих подходов
Плохо организованный Minimal API проект превращается в огромный
Что выбрать
Для новых микросервисов и сфокусированных API автор статьи рекомендует Minimal APIs с vertical slices. Но не сваливать всё в
Для систем с уже выстроенной контроллерной архитектурой или жёсткими корпоративными стандартами контроллеры остаются рабочим выбором.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
ASP.NET Core предлагает два способа строить HTTP API. Minimal APIs и контроллеры. Microsoft в документации рекомендует Minimal APIs для новых проектов, потому что это меньше кода, меньше конфигурации и выше производительность. Но это не значит, что контроллеры устарели. Это значит, что нужен осознанный выбор.
Когда Minimal APIs подходят лучше
Minimal APIs хорошо работают, когда API небольшой и сфокусированный. Микросервисы, внутренние API, легковесные эндпоинты, vertical slice архитектура. Каждый эндпоинт явно определяет маршрут, нет лишней церемонии с наследованием и атрибутами.
Вот как выглядит чистый эндпоинт на Minimal API:
public static class CreateOrderEndpoint
{
public static IEndpointRouteBuilder MapCreateOrder(this IEndpointRouteBuilder app)
{
app.MapPost("/orders", async (
CreateOrderRequest request,
ICreateOrderUseCase useCase,
CancellationToken cancellationToken) =>
{
var result = await useCase.ExecuteAsync(request, cancellationToken);
return Results.Created($"/orders/{result.OrderId}", result);
});
return app;
}
}
Читаемо, прямолинейно, бизнес-логика вынесена в
ICreateOrderUseCase.Когда контроллеры всё ещё уместны
Контроллеры полезны там, где уже есть устоявшаяся MVC-инфраструктура, стандартизированные фильтры, сложное версионирование или большая команда, привыкшая к этому паттерну. Если в проекте выстроены конвенции вокруг контроллеров и это работает, переписывать на Minimal APIs ради моды нет смысла.
Что изменилось в .NET 10
В .NET 10 Microsoft добавила поддержку валидации для Minimal APIs, включая кастомизацию ответов через
IProblemDetailsService. Раньше отсутствие встроенной валидации было одним из главных аргументов против Minimal APIs. Теперь этот аргумент слабее.Главная ловушка обоих подходов
Плохо организованный Minimal API проект превращается в огромный
Program.cs. Плохо организованный проект на контроллерах превращается в папку с пустыми pass-through экшенами. Ни один из подходов не спасёт от слабой архитектуры.Что выбрать
Для новых микросервисов и сфокусированных API автор статьи рекомендует Minimal APIs с vertical slices. Но не сваливать всё в
Program.cs, а организовывать эндпоинты по фичам, выносить бизнес-логику из обработчиков маршрутов, использовать явные контракты запросов и ответов.Для систем с уже выстроенной контроллерной архитектурой или жёсткими корпоративными стандартами контроллеры остаются рабочим выбором.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥2
ref struct в C#ref struct появился не просто как ограниченная версия обычного struct. За этим стоит конкретная гарантия компилятора о том, где может находиться такой тип в памяти.Подумайте: что произойдёт, если попробовать передать
ref struct в лямбду, сохранить в поле класса или сделать boxing?📍 Навигация: Вакансии • Задачи • Собесы
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
Основная компетенция специалиста по Data Science – способность анализировать и интерпретировать данные, а математика является фундаментом для начала работы.
В карточках мы разбираем основные разделы математики, с которых стоит начать изучение специалисту по анализу данных.
Хотите подготовиться к офферу или подтянуть знания? Оставляйте заявку на наш курс по математике для Data Science 💙
P.S. Только до 31 мая на курс (и вообще на все программы Академии) действует
А как у вас дела с высшей математикой?
❤️ — Помню всё
🔥 — Знаю основы
🌚 — Ничего не знаю
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🌚1👾1
Следующий дайжест будет последним за май.
— Microsoft обвинила исследователя в публикации обхода BitLocker через WinRE
— Microsoft выложила свежие ISO-образы Windows 11
Образы доступны на странице загрузки Windows Insider Program и подходят для чистой установки, развёртывания на виртуалку или in-place апгрейда.
— GitHub взломали через расширение VS Code
— Vibe hiring
📍 Навигация: Вакансии • Задачи • Собесы
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
Service Locator — это глобальный реестр сервисов. Любой класс в любой момент может запросить нужную зависимость через что-то вроде
ServiceLocator.Get<IEmailService>(). Выглядит удобно и гибко. На практике — это ловушка, которая усложняет поддержку кода с каждым месяцем.Марк Симанн назвал этот паттерн антипаттерном ещё в 2010 году. С тех пор аргументы стали только сильнее.
В чём проблема
Когда класс получает зависимости через конструктор, вы видите всё, что ему нужно, прямо в сигнатуре:
public class OrderService
{
private readonly IEmailService _email;
private readonly IOrderRepository _repo;
public OrderService(IEmailService email, IOrderRepository repo)
{
_email = email;
_repo = repo;
}
}
Два параметра — две зависимости. Всё на виду.
Теперь тот же класс через Service Locator:
public class OrderService
{
public void PlaceOrder(Order order)
{
var repo = ServiceLocator.Get<IOrderRepository>();
repo.Save(order);
var email = ServiceLocator.Get<IEmailService>();
email.SendConfirmation(order);
}
}
Снаружи
OrderService выглядит так, будто ему ничего не нужно. Зависимости спрятаны внутри метода. Чтобы понять, что класс использует, нужно читать весь его код. На десяти классах это неудобно. На сотне — это археология.Тесты превращаются в боль
Для юнит-теста с constructor injection вы просто передаёте моки в конструктор.
var service = new OrderService(mockEmail, mockRepo);
С Service Locator нужно сначала настроить глобальный реестр, зарегистрировать в нём все нужные моки, убедиться, что между тестами состояние очищается. Тесты становятся хрупкими и зависимыми друг от друга.
IServiceProvider в бизнес-логике — тот же Service Locator
В .NET есть встроенный DI-контейнер, и соблазн использовать
IServiceProvider напрямую велик. Но если вы инжектите IServiceProvider в бизнес-класс и достаёте из него сервисы вручную, это ровно тот же Service Locator, просто в обёртке от Microsoft:// Так делать не стоит
public class ReportGenerator
{
private readonly IServiceProvider _provider;
public ReportGenerator(IServiceProvider provider)
{
_provider = provider;
}
public void Generate()
{
var formatter = _provider.GetRequiredService<IReportFormatter>();
// ...
}
}
Зависимость от
IReportFormatter снова спрятана. Конструктор говорит только «мне нужен весь контейнер», что бесполезно.Правильный вариант:
public class ReportGenerator
{
private readonly IReportFormatter _formatter;
public ReportGenerator(IReportFormatter formatter)
{
_formatter = formatter;
}
public void Generate()
{
// _formatter уже здесь
}
}
Когда IServiceProvider допустим
Есть ограниченный список ситуаций, где обращение к
IServiceProvider оправдано. Фабрики, которые создают объекты с разным временем жизни. Плагинные системы, где набор сервисов неизвестен на этапе компиляции. Инфраструктурный код фреймворка, middleware, активаторы. Во всех этих случаях речь идёт об инфраструктуре, а не о бизнес-логике.Если ваш класс решает доменную задачу и при этом тянет
IServiceProvider, стоит вынести конкретную зависимость в конструктор. Код станет прозрачнее, тесты проще, а рефакторинг перестанет быть раскопками.📍 Навигация: Вакансии • Задачи • Собесы
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍4❤🔥2
До 31 мая можно забрать любой курс Proglib Academy со скидкой 40%
Если давно хотели прокачаться в Python, ML, алгоритмах или AI-агентах, сейчас самое время выбрать программу и начать обучение по сниженной цене.
🎁 Разработка AI-агентов — от 49.000 ₽ (вместо 69.000 ₽)
Практический курс по разработке AI-агентов для автоматизации задач, работы и собственных проектов
🎁 Курс AgentOps — 129.000 ₽ (вместо 149.000 ₽)
Для разработчиков и LLM-инженеров, которые хотят внедрять AI-логику в бэкенд и сохранять стабильность сервиса.
🎁 Математика для разработки AI-моделей — 23.990 ₽ (вместо 31.990 ₽)
Практическая база по математике для анализа данных, ML и дальнейшего развития в AI.
🎁 Математика для Data Science — от 29.990 ₽ (вместо 39.990 ₽)
Курс для тех, кто хочет решать задачи, которые дают на собеседованиях на позицию дата-сайентиста в бигтехе.
🎁 ML для старта в Data Science — 28.990 ₽ (вместо 38.990 ₽)
Разберётесь в машинном обучении: от базовых понятий и линейных моделей до ансамблей, бустинга и рекомендательных систем.
🎁 Основы IT для непрограммистов — 16.990 ₽ (вместо 28.990 ₽)
Курс для IT-рекрутеров, маркетологов, проджектов, продактов и всех, кто работает с IT, но не пишет код.
🎁 Архитектуры и шаблоны проектирования — 27.990 ₽ (вместо 37.900 ₽)
Освоите основные паттерны проектирования и прокачаете навыки архитектора программного обеспечения.
🎁 Специалист по ИИ — 89.000 ₽ (вместо 113.900 ₽)
Курс для тех, кто хочет получить профессию в сфере ИИ, собрать портфолио из 5 проектов и научиться разрабатывать сложных AI-агентов.
🎁 Алгоритмы и структуры данных — 33.990 ₽ (вместо 57.990 ₽)
Подготовитесь к алгоритмическим собеседованиям, разберёте структуры данных и научитесь писать более эффективный код.
🎁 Программирование на языке Python — 27.990 ₽ (вместо 47.390 ₽)
Освоите Python на практике: без сухой теории, с пошаговой прокачкой навыков и итоговым проектом в портфолио.
🙌 Выбирайте курс по ссылке, оставляйте заявку, и менеджер поможет подобрать программу под ваши цели — https://clc.to/Jeob-A
Если давно хотели прокачаться в Python, ML, алгоритмах или AI-агентах, сейчас самое время выбрать программу и начать обучение по сниженной цене.
🎁 Разработка AI-агентов — от 49.000 ₽ (вместо 69.000 ₽)
Практический курс по разработке AI-агентов для автоматизации задач, работы и собственных проектов
🎁 Курс AgentOps — 129.000 ₽ (вместо 149.000 ₽)
Для разработчиков и LLM-инженеров, которые хотят внедрять AI-логику в бэкенд и сохранять стабильность сервиса.
🎁 Математика для разработки AI-моделей — 23.990 ₽ (вместо 31.990 ₽)
Практическая база по математике для анализа данных, ML и дальнейшего развития в AI.
🎁 Математика для Data Science — от 29.990 ₽ (вместо 39.990 ₽)
Курс для тех, кто хочет решать задачи, которые дают на собеседованиях на позицию дата-сайентиста в бигтехе.
🎁 ML для старта в Data Science — 28.990 ₽ (вместо 38.990 ₽)
Разберётесь в машинном обучении: от базовых понятий и линейных моделей до ансамблей, бустинга и рекомендательных систем.
🎁 Основы IT для непрограммистов — 16.990 ₽ (вместо 28.990 ₽)
Курс для IT-рекрутеров, маркетологов, проджектов, продактов и всех, кто работает с IT, но не пишет код.
🎁 Архитектуры и шаблоны проектирования — 27.990 ₽ (вместо 37.900 ₽)
Освоите основные паттерны проектирования и прокачаете навыки архитектора программного обеспечения.
🎁 Специалист по ИИ — 89.000 ₽ (вместо 113.900 ₽)
Курс для тех, кто хочет получить профессию в сфере ИИ, собрать портфолио из 5 проектов и научиться разрабатывать сложных AI-агентов.
🎁 Алгоритмы и структуры данных — 33.990 ₽ (вместо 57.990 ₽)
Подготовитесь к алгоритмическим собеседованиям, разберёте структуры данных и научитесь писать более эффективный код.
🎁 Программирование на языке Python — 27.990 ₽ (вместо 47.390 ₽)
Освоите Python на практике: без сухой теории, с пошаговой прокачкой навыков и итоговым проектом в портфолио.
🙌 Выбирайте курс по ссылке, оставляйте заявку, и менеджер поможет подобрать программу под ваши цели — https://clc.to/Jeob-A
❤1
В C# переделывают модель работы с
unsafe. Ключевое слово больше не будет просто «включать указатели». Оно станет контрактом между вызываемым и вызывающим методом. Превью появится в .NET 11, продакшен-релиз в .NET 12.Проблема
Сейчас
unsafe на методе означает «здесь можно использовать указатели». Он не накладывает обязательств на вызывающую сторону. Метод вроде Marshal.ReadByte принимает IntPtr, разыменовывает указатель внутри, но вызывается из безопасного кода без ограничений. Конвенции не проверяет компилятор и не видит ревьюер с первого взгляда.Что меняется
unsafe в сигнатуре метода теперь означает контракт: вызывающая сторона обязана выполнить задокументированные условия. Каждая небезопасная операция должна быть обёрнута во внутренний блок unsafe { }. Каждый unsafe-метод должен содержать блок /// <safety> с описанием обязательств.Вот
Marshal.ReadByte в новой модели:/// <safety>
/// Сумма ptr и ofs должна указывать на байт,
/// доступный вызывающей стороне для чтения.
/// </safety>
public static unsafe byte ReadByte(IntPtr ptr, int ofs)
{
byte* addr = (byte*)ptr;
unsafe
{
// SAFETY: полагаемся на обязательство вызывающей стороны.
return addr[ofs];
}
}
Приведение
(byte*)ptr безопасно, это преобразование числа. А вот addr[ofs] опасно, потому что разыменовывает указатель. Именно эта строка обёрнута в unsafe { }.Другие изменения
unsafe на типе теперь вызывает ошибку компиляции. Область действия опускается на уровень методов и свойств. unsafe на методе больше не создаёт unsafe-контекст автоматически. Типы указателей в сигнатуре больше не распространяют unsafe, опасна только операция разыменования. Новое ключевое слово safe обязательно для extern-деклараций, пропустить оба модификатора нельзя.Включение
Модель включается через новое свойство проекта и работает независимо от
<AllowUnsafeBlocks>. Для миграции планируется dotnet format fixer, который механически обернёт вызовы в unsafe { } и перенесёт модификаторы с типов на методы. Писать <safety>-документацию придётся вручную.Нарушения становятся ошибками компиляции, не предупреждениями. Модель повторяет подход Rust и Swift, но с учётом экосистемы .NET. Для тех, кто использует unsafe, код станет прозрачнее для ревью.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍1
🧑💻 Генераторы в .NET замедляют билд
Генераторы кода работают внутри компилятора. Они запускаются при каждой сборке и при каждом нажатии клавиши в IDE. Если не следить за ними, билд на 10 секунд может превратиться в полторы минуты без видимых причин. Вот что можно сделать, чтобы этого не допустить.
Сделайте сгенерированный код видимым
По умолчанию сгенерированные
Добавьте в
Теперь все сгенерированные файлы попадают в папку
Замеряйте время через binary log
Ощущение «билд стал медленнее» ничего не даёт. Нужны конкретные числа по каждому генератору. Соберите проект с флагом:
Откройте полученный
Проверьте транзитивные зависимости
Генераторы кода приезжают вместе с NuGet-пакетами. Вы подключаете библиотеку логирования или маппер, а внутри пакета лежит генератор, который теперь запускается в каждом проекте. Вы его не выбирали, но он работает.
В том же binary log задача CSC показывает все загруженные сборки анализаторов и генераторов. Пройдитесь по списку. Если видите незнакомое имя, выясните, откуда оно пришло. Команда
Используйте только инкрементальные генераторы
Если вы пишете свои генераторы, реализуйте
Но сам по себе интерфейс ничего не гарантирует. Генератор, который реализует
Принимайте решения по числам
Если дорогой генератор пришёл из стороннего пакета, вы не можете его исправить. Но можете решить, стоит ли пакет своего времени сборки. Иногда стоит. Иногда дешевле отказаться от пакета и решить задачу иначе.
Главное тут не гадать, а смотреть в binary log. Там есть имя генератора и его стоимость в миллисекундах. Этого достаточно, чтобы принять осознанное решение.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
Генераторы кода работают внутри компилятора. Они запускаются при каждой сборке и при каждом нажатии клавиши в IDE. Если не следить за ними, билд на 10 секунд может превратиться в полторы минуты без видимых причин. Вот что можно сделать, чтобы этого не допустить.
Сделайте сгенерированный код видимым
По умолчанию сгенерированные
.g.cs файлы не записываются на диск. Они существуют только в памяти компилятора. Когда что-то ломается, вы видите ошибку в файле, который не можете открыть.Добавьте в
Directory.Build.props в корне решения:<Project>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>
$(BaseIntermediateOutputPath)generated
</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
Теперь все сгенерированные файлы попадают в папку
obj/generated. Их можно читать, искать по ним и ставить точки останова в отладчике. Это настройка на один раз, и она стоит того.Замеряйте время через binary log
Ощущение «билд стал медленнее» ничего не даёт. Нужны конкретные числа по каждому генератору. Соберите проект с флагом:
dotnet build -bl
Откройте полученный
msbuild.binlog в MSBuild Structured Log Viewer. Найдите задачу CSC. Внутри будет список всех генераторов с временем выполнения в миллисекундах. Собирайте именно полное решение, а не отдельный проект. Стоимость генератора умножается на количество проектов, которые его подтягивают.Проверьте транзитивные зависимости
Генераторы кода приезжают вместе с NuGet-пакетами. Вы подключаете библиотеку логирования или маппер, а внутри пакета лежит генератор, который теперь запускается в каждом проекте. Вы его не выбирали, но он работает.
В том же binary log задача CSC показывает все загруженные сборки анализаторов и генераторов. Пройдитесь по списку. Если видите незнакомое имя, выясните, откуда оно пришло. Команда
dotnet nuget why поможет отследить цепочку зависимостей.Используйте только инкрементальные генераторы
Если вы пишете свои генераторы, реализуйте
IIncrementalGenerator, а не устаревший ISourceGenerator. Инкрементальный генератор кеширует промежуточные результаты. Если входные данные не изменились, он пропускает повторную обработку.Но сам по себе интерфейс ничего не гарантирует. Генератор, который реализует
IIncrementalGenerator и при этом пересобирает всё заново на каждый вызов, работает так же медленно, как устаревший. Кеширование должно быть реальным. Пайплайн нужно строить так, чтобы неизменённые входы давали кешированный выход.Принимайте решения по числам
Если дорогой генератор пришёл из стороннего пакета, вы не можете его исправить. Но можете решить, стоит ли пакет своего времени сборки. Иногда стоит. Иногда дешевле отказаться от пакета и решить задачу иначе.
Главное тут не гадать, а смотреть в binary log. Там есть имя генератора и его стоимость в миллисекундах. Этого достаточно, чтобы принять осознанное решение.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤🔥3👾1
Если вы запускали NuGet Audit на .NET-проекте, то наверняка видели предупреждения о транзитивных пакетах, которые не устанавливали. Часто это
System.Text.Json, System.Memory и подобные, которые уже есть в рантайме в более свежей версии. Предупреждение есть, а реальной проблемы нет. В .NET 10 эту ситуацию исправили.
В чём была проблема
Многие библиотеки на nuget.org таргетят
netstandard2.0 и тянут за собой пакеты вроде System.Text.Json 8.0.0. Проект на .NET 10 уже содержит их в рантайме в более новой версии, но NuGet всё равно резолвит старый пакет в граф. Когда на него публикуется CVE, сканер помечает его как уязвимый. По факту приложение использует версию из рантайма. Это ложное срабатывание, но отличить его от настоящего без ручного разбора сложно.
Что такое package pruning
Package pruning убирает из графа зависимостей пакеты, которые уже поставляются .NET Runtime Libraries. NuGet при restore сверяется со списком пакетов, входящих в целевой фреймворк. Если транзитивная зависимость попадает в диапазон, она исключается. Пакет не скачивается и не фигурирует в аудите.
Для прямых
PackageReference логика другая: NuGet ставит PrivateAssets='all' и IncludeAssets='none'. Ссылка остаётся в csproj, пока вы сами её не удалите. Если пакет можно убрать полностью, NuGet выдаёт NU1510.Pruning работает только в пределах версии фреймворка. Проект на
net8.0 с транзитивной зависимостью System.Text.Json 9.0.0 не уберёт пакет, потому что платформа поставляет только 8.0.x.Что изменилось в .NET 10
Package pruning впервые появился как opt-in в SDK 9.0.200. В .NET 10 он включён по умолчанию для
net10.0 и выше. Одновременно NuGetAuditMode по умолчанию стал all, то есть NuGet проверяет и транзитивные зависимости.По телеметрии Microsoft, проекты с новыми дефолтами получают на 70% меньше транзитивных предупреждений об уязвимостях. Restore ускоряется до 50% на уровне проекта за счёт меньшего графа.
Дефолтные настройки .NET 10:
<PropertyGroup>
<NuGetAuditMode>all</NuGetAuditMode>
<RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
</PropertyGroup>
Граф зависимостей теперь точнее отражает то, что приложение реально использует. Меньше ложных срабатываний, быстрее restore, понятнее аудит. Для проектов на .NET 10 всё работает из коробки.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🎉4🔥2👏1
Model Context Protocol (MCP) упростил подключение инструментов к AI-агентам. Но чем больше инструментов доступно агенту, тем острее вопрос контроля. Какие tools можно вызывать? Что если в описании инструмента спрятана prompt-инъекция? Как не пропустить опасный ответ обратно в модель?
Microsoft предложила ответ в виде NuGet-пакета
Microsoft.AgentGovernance.Extensions.ModelContextProtocol. Это Public Preview расширение для официального MCP C# SDK, которое добавляет слой governance к вашему MCP-серверу одним вызовом.Что делает пакет
Пакет встраивается в стандартный
IMcpServerBuilder и добавляет четыре вещи. Сканирование инструментов при старте, проверку политик при каждом вызове, санитизацию ответов перед возвратом в модель и аудит с метриками.Установка стандартная:
dotnet add package Microsoft.AgentGovernance.Extensions.ModelContextProtocol
Подключение через один extension-метод:
using AgentGovernance.Extensions.ModelContextProtocol;
builder.Services
.AddMcpServer()
.WithGovernance(options =>
{
options.PolicyPaths.Add("policies/mcp.yaml");
options.DefaultAgentId = "did:mcp:server";
options.ServerName = "contoso-support";
});
Сканирование при запуске
До того как инструменты станут доступны клиентам, пакет проверяет их определения на угрозы. Среди детектируемых категорий: tool poisoning, тайпсквоттинг, скрытые инструкции в описаниях, schema abuse (например, поля вроде
password или system_prompt), cross-server атаки. Если инструмент не прошёл проверку, сервер по умолчанию не запустится. Это fail closed на этапе старта, а не рантайм-фильтр.Политики вызовов
Контроль доступа к инструментам описывается в YAML-файлах. Политики работают по модели allow/deny с приоритетами. Пример:
apiVersion: governance.toolkit/v1
version: "1.0"
name: mcp-governance-policy
default_action: deny
rules:
- name: allow-echo
condition: "tool_name == 'echo'"
action: allow
priority: 10
Если вызов запрещён, пакет вернёт governed error result вместо выполнения инструмента. Политики поддерживают identity: если есть аутентифицированный вызывающий, его идентификатор участвует в оценке. Если нет, используется fallback DID, например
did:mcp:anonymous.Санитизация ответов
Ответы инструментов проходят через санитайзер до возврата клиенту. Он ищет prompt-injection теги (
<system>...</system>), фразы переопределения вроде «ignore previous instructions», паттерны утечки credentials и URL для эксфильтрации данных. Опасные фрагменты вырезаются, остальной контент сохраняется.Дефолты из коробки
Пакет включает защиту по умолчанию без дополнительной настройки.
ScanToolsOnStartup, FailOnUnsafeTools, SanitizeResponses, GovernFallbackHandlers, EnableAudit, EnableMetrics — всё это true сразу после подключения.Итого
Пакет не требует форка SDK и не вводит отдельный прокси-процесс. Он оборачивает финальный
ToolCollection в стандартном builder-пайплайне и применяется ко всем инструментам, зарегистрированным до или после вызова .WithGovernance(). Работает с .NET 8+.Если вы строите MCP-серверы для внутренних копайлотов или корпоративных агентов, это готовый способ добавить контроль доступа, аудит и защиту от инъекций без ручной реализации в каждом сервисе.
📍 Навигация: Вакансии • Задачи • Собесы
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2❤1👏1🎉1
⚡️ Знакомьтесь с экспертом Proglib Academy: AI-архитектор Антон Будняк
Антон — мастер превращения сырых AI-идей в отказоустойчивые системы. Он знает, как запустить MVP за неделю и масштабировать его так, чтобы архитектура не рассыпалась под нагрузкой в сотни тысяч юзеров.
За что его ценит IT-комьюнити:
🟣 Опыт в финтехе и крупном бизнесе
🟣 Запуск продуктов на 6.000+ пользователей
🟣 Ускоряет разработку
📚 Где Антон черпает знания (рекомендации эксперта):
- X* — главный источник новостей. Рекомендую блог Бориса Черни (создателя Claude Code) — там база про использование ИИ в разработке.
- Нетворкинг в ТГ: чаты LLM под капотом и AI-чат — здесь можно найти ответ почти на любой технический вопрос.
- Новости AI: каналы Сиолошная и Denis Sexy IT.
На курсе Agentops Антон учит строить «неубиваемый» бэкенд: работать с очередями, таймаутами и балансировкой нагрузки, чтобы ваши агенты работали стабильно 24/7.
🎁 Майские СКИДКИ в Proglib Academy!
До конца мая на все курсы академии (включая AgentOps и разработку ИИ-агентов) действует скидка -40%. Это лучший момент, чтобы войти в AI-разработку под присмотром практиков.
Узнать больше о программе и обучении у Антона:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду подпишусь на каналы из списка Антона
🏃♀️ Proglib Academy
* - запрещен в рф
Антон — мастер превращения сырых AI-идей в отказоустойчивые системы. Он знает, как запустить MVP за неделю и масштабировать его так, чтобы архитектура не рассыпалась под нагрузкой в сотни тысяч юзеров.
За что его ценит IT-комьюнити:
Руководил разработкой ML-моделей в финтехе с экономическим эффектом более 100 млн ₽
Антон строит сервисы, которыми пользуются тысячи людей в реальном проде.
Оптимизировал ML-пайплайны и кратно сократил время от начала разработки до релиза
📚 Где Антон черпает знания (рекомендации эксперта):
- X* — главный источник новостей. Рекомендую блог Бориса Черни (создателя Claude Code) — там база про использование ИИ в разработке.
- Нетворкинг в ТГ: чаты LLM под капотом и AI-чат — здесь можно найти ответ почти на любой технический вопрос.
- Новости AI: каналы Сиолошная и Denis Sexy IT.
На курсе Agentops Антон учит строить «неубиваемый» бэкенд: работать с очередями, таймаутами и балансировкой нагрузки, чтобы ваши агенты работали стабильно 24/7.
🎁 Майские СКИДКИ в Proglib Academy!
До конца мая на все курсы академии (включая AgentOps и разработку ИИ-агентов) действует скидка -40%. Это лучший момент, чтобы войти в AI-разработку под присмотром практиков.
Узнать больше о программе и обучении у Антона:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду подпишусь на каналы из списка Антона
* - запрещен в рф
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱9🎉4❤2👍2
👀 Практический курс «Разработка AI-агентов для автоматизации задач, работы и собственных проектов» со скидкой 40% до конца мая!
Мы поговорили с десятками разработчиков, учли главные боли индустрии и запускаем полностью обновленный курс «ИИ-агенты 5.0». 🎉
Что вы узнаете?
- Как радикально оптимизировать траты на токены.
- Как на практике оценивать качество и точность работы агента.
- Как «докручивать» RAG-системы без потери качества.
- Как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы, и про многое-многое другое.
Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Сбер, Raft и Газпромбанк др.
Длительность: 6–12 недель в зависимости от тарифа.
👉 Занимайте место на главном агентском интенсиве по лучшей цене
Мы поговорили с десятками разработчиков, учли главные боли индустрии и запускаем полностью обновленный курс «ИИ-агенты 5.0». 🎉
Что вы узнаете?
- Как радикально оптимизировать траты на токены.
- Как на практике оценивать качество и точность работы агента.
- Как «докручивать» RAG-системы без потери качества.
- Как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы, и про многое-многое другое.
Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Сбер, Raft и Газпромбанк др.
Длительность: 6–12 недель в зависимости от тарифа.
👉 Занимайте место на главном агентском интенсиве по лучшей цене
🥱3👾2
🦾🧠🏋️ Качаем мозги к лету!
Все готовятся к пляжному сезону, а мы предлагаем прокачать хард-скилы, чтобы забрать крутой оффер, строить продукты будущего иработать из любой точки мира 😎
⚡️ Распродажа @proglib_academy: забирайте самые актуальные образовательные треки по сниженным ценам!
➡️ Разработка AI-агентов — от 49 000 ₽ (вместо 69 000 ₽).
➡️ Курс AgentOps — 129 000 ₽ (вместо 149 000 ₽).
➡️ Математика для разработки AI-моделей — 23 990 ₽ (вместо 31 990 ₽).
➡️ ML для старта в Data Science — 28 990 ₽ (вместо 38 990 ₽).
Почему мы?
⭐️ Учим для продакшена. Наши программы заточены под реальные задачи бизнеса: как не слить бюджет на токены, как заставить LLM работать стабильно в бэкенде и как выстроить отказоустойчивую архитектуру.
⭐️ Спикеры — суровые практики. Вы будете перенимать опыт у действующих AI-архитекторов, тимлидов и ML-инженеров из топовых IT-компаний.
⭐️ Комплексный подход. Мы даем как мощный математический фундамент для понимания моделей «под капотом», так и передовые инструменты оркестрации агентов.
⭐️ Много практики и фидбека. Вебинары, десятки практических заданий и живое общение с экспертами в чате Telegram на протяжении всего обучения.
⏳ Оставляйте заявку и бронируйте место со СКИДКОЙ 40%
Все готовятся к пляжному сезону, а мы предлагаем прокачать хард-скилы, чтобы забрать крутой оффер, строить продукты будущего и
⚡️ Распродажа @proglib_academy: забирайте самые актуальные образовательные треки по сниженным ценам!
Почему мы?
⏳ Оставляйте заявку и бронируйте место со СКИДКОЙ 40%
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱2😁1