csharpproglib | Unsorted

Telegram-канал csharpproglib - Библиотека шарписта | C#, F#, .NET, ASP.NET

23284

Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Subscribe to a channel

Библиотека шарписта | C#, F#, .NET, ASP.NET

За год мы провели три потока курса по ИИ-агентам, а теперь запускаем масштабное обновление!

В новом, четвёртом потоке мы учли все пожелания студентов, добавили большой блок про AgentOps и сместили фокус с базовых концепций на суровый инжиниринг. Сделать простую цепочку на C
легко, а вот интегрировать агентов в корпоративный контур, чтобы они не галлюцинировали и не сливали бюджет в проде — задача со звёздочкой.

В программе:

— интеграции по стандарту MCP и мультиагентные паттерны;
— оркестрация в LangGraph: human-in-the-loop и runbook для отказов;
— продвинутый RAG для промышленной эксплуатации и парсинг сложных документов;
— контроль экономики агентов: маршрутизация и кеширование;
— развёртывание локальных опенсорс-моделей в закрытых контурах по 152-ФЗ.

В честь старта продаж действует спецпредложение: 3 курса по цене 1 (два дополнительных курса в подарок).

Доступ к материалам для предварительной подготовки откроется сразу после оплаты.

По промокоду Agent забирайте скидку 10 000 ₽ (89 000 ₽ вместо 99 000 ₽). Успейте занять место до 28 февраля!

👉 Присоединиться к четвёртому потоку и вывести агентов в прод

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🔗 Идём в нативный мир

Иногда .NET-коду нужно выйти за пределы управляемого мира и напрямую поговорить с операционной системой, нативными библиотеками или COM-компонентами. Для этого существует Native Interop — набор механизмов, встроённых прямо в рантайм.

Зачем это вообще нужно

Три основных сценария: ОС предоставляет огромное количество API, которых нет в BCL, например, доступ к оборудованию, системные вызовы; интеграция с кодом на C/C++ или Java через JNI; и автоматизация Windows-приложений вроде Office через COM.

Platform Invoke — главный инструмент

Platform Invoke позволяет вызывать функции из нативных библиотек .dll / .so / .dylib. В .NET 7+ вместо старого [DllImport] рекомендуется использовать [LibraryImport]:

[LibraryImport("nativelib", EntryPoint = "to_lower",
StringMarshalling = StringMarshalling.Utf16)]
internal static partial string ToLower(string str);


LibraryImport запускает source-генератор, который формирует весь код маршалинга на этапе компиляции, а не в рантайме — это открывает возможность для Native AOT и инлайнинга P/Invoke-вызовов.

Маршалинг типов

Маршалинг необходим потому, что типы в управляемом и неуправляемом коде различаются. Например, в .NET строка одна, а в нативном коде их может быть множество: UTF-16, ANSI, UTF-8, null-terminated, ASCII и так далее.

Для управления маршалингом используются атрибуты [MarshalAs] и [StructLayout]. Для нативных структур нужно воспроизвести их в управляемом коде с точным совпадением порядка и размеров полей.

Blittable-типы — типы с одинаковым битовым представлением в managed и native коде. Они не требуют конвертации и просто закрепляются в памяти — используйте их везде, где возможно.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 TDD в больших проектах

Все слышали мантру: «пиши тесты сначала, код потом». Звучит разумно. Но когда проект уже большой, то TDD может занять куда больше сил.

Казалось бы, вот простая задача: добавить поле DeliveryComment к заказу. Бизнес просит, задача на час.

Давайте по TDD — сначала тест:

[Fact]
public void CreateOrder_WithDeliveryComment_ShouldPersistComment()
{
var service = new OrderService(...); // 6 зависимостей
var request = new OrderRequest { DeliveryComment = "Позвонить за 10 минут" };
var result = service.CreateOrder(request);
Assert.Equal("Позвонить за 10 минут", result.DeliveryComment);
}


Чтобы написать этот тест, вам нужно: поднять моки для всех зависимостей OrderService, разобраться, как устроен OrderRequest, понять, где вообще маппинг в entity. А сама фича — это три строки кода:
// OrderRequest.cs
public string? DeliveryComment { get; set; }

// OrderEntity.cs
public string? DeliveryComment { get; set; }

// OrderService.cs
entity.DeliveryComment = request.DeliveryComment;


Три строки. Тест к ним — тридцать. И это тест, который проверяет, что присвоение работает. То есть тест на то, что C# умеет присваивать строки.

Для сложной бизнес-логики с граничными случаями он работает отлично. Но когда вы добавляете поле к DTO или прокидываете значение через три слоя — писать тест до кода означает тратить время команды на церемонию ради церемонии.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 Задача, которую переписывают снова и снова

Каждый, кто работал с ASP.NET Core хоть на одном серьёзном проекте, знает этот момент: надо отправить письмо, SMS или пуш — и начинается. Подключаете SendGrid, пишете обёртку, потом прилетает задача «добавь ещё Slack», потом WhatsApp, потом Teams.

Каждый раз — новый провайдер, новый SDK, новый слой абстракции, который придумывается на ходу.

С такой болью была написана библиотека RecurPixel.Notify, которая закрывает эту проблему.

Идея простая: один интерфейс INotifyService — любой канал. Email, SMS, Push, WhatsApp, Slack, Discord, Teams, Telegram, Facebook, Viber и даже In-App нотификации. Всё через одну точку входа, всё через стандартный DI.

Подключается в одну строку:

dotnet add package RecurPixel.Notify.Sdk


Это чистая библиотека, никакого SaaS, никаких внешних серверов. Вы приносите свои API-ключи, сами решаете, куда логировать доставку — через OnDelivery() пишете в свою БД. Хотите поменять Twilio на Vonage — меняете конфиг, код не трогаете.

Провайдеров уже больше 30. Большинство покрыто юнит-тестами, часть — интеграционными.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 Блокнот теперь с картинками

Российские пользователи Notion, которых в 2022 году попросили на выход, могут выдохнуть — замена найдена.

Microsoft методично превращает Блокнот во всё то, за что люди платили подписку: таблицы уже есть, ИИ уже есть, Markdown уже есть, картинки вот-вот завезут.

Поддержка изображений тестируется во внутренних сборках, и по результатам тестов функция практически не влияет на производительность.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📰 Дайджест недели

Без лишних слов

Microsoft раскрыла на PowerShell и OpenSSH

Новая фича C#

Конец эпохи State Machine

Гендерный разрыв в IT

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤨 Переходить на .NET 10 или нет

.NET 10 вышел в ноябре 2025 года — и это LTS-релиз, то есть Microsoft будет поддерживать его несколько лет. Хорошая база для прода.

Основные изменения крутятся вокруг трёх вещей: производительность, язык и экосистема. JIT-компилятор стал агрессивнее инлайнить вызовы и оптимизировать аллокации, что на CPU-интенсивных и API-нагруженных сценариях даёт до 5–30% прироста на горячих путях.

C# 14 добавил extension members, field-backed properties и ряд мелких улучшений, которые заметно сократят бойлерплейт у авторов библиотек. EF Core тоже стал быстрее на ряде запросов.

Если у вас покрытый тестами прод, нормальный CI и необходимость в долгосрочной поддержке — мигрировать стоит.

План простой: сначала апгрейдите изолированный сервис или библиотеку, снимите замеры P95/P99 и аллокаций до и после, убедитесь что всё работает — и масштабируйте.

Для старта можно использовать официальный инструмент:

dotnet tool install -g upgrade-assistant
upgrade-assistant upgrade MySolution.sln


Он автоматически находит потенциальные проблемы и обновляет .csproj — но слепо доверять ему не стоит, результаты лучше перепроверить вручную.

Есть смысл повременить, если критические NuGet-пакеты ещё не выпустили совместимые версии, у команды нет ресурса на полноценный migration sprint, или впереди крупный релиз и незачем добавлять риски.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

LLM в корпоративном .NET: от хаоса к управляемой архитектуре

Бизнес массово требует внедрять ИИ в корпоративные системы. Но базовые боты ломаются о реальные задачи, уходят в бесконечные циклы и нарушают политики безопасности.

Мы обновили курс по AI-агентам, сделав упор на enterprise-стандарты 2026 года. Теперь это инженерный гайд по созданию стабильных, измеримых и безопасных систем, которые не страшно пускать в продакшн.

Что мы разбираем на курсе:

— хардкорный RAG: парсинг кривых корпоративных сканов, таблиц и улучшение поисковых запросов;
— оркестрация: маршрутизация, human-in-the-loop для критичных решений и восстановление состояний;
— контроль затрат: детальное управление токенами, кэшем и предотвращение перегрузок;
— автоматизация: управление браузером и интеграция с legacy-продуктами;
— правовой контур: разворачивание решений с соблюдением 152-ФЗ и подготовка документов.

Активируйте промокод Agent до 28 февраля и забирайте скидку 10 000 рублей.

Используя акцию «3 курса по цене 1», вы можете выбрать ещё два курса в подарок.

Построить надёжных AI-агентов

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📣 Если C# для вас — это уже не просто язык, а инструмент для построения систем, следующий шаг — научиться проектировать и разрабатывать так, как это делают сильные команды в продакшене.

Курс «C# Developer. Professional» — про Best Practices .NET-разработки и реальную инженерную работу. Вы углубитесь в работу с атрибутами, асинхронность и многопоточность, разберёте паттерны проектирования, работу с SQL и NoSQL, кэширование, CI/CD и тестирование.

Программа построена вокруг практики и командной разработки. Вы будете работать в Scrum-команде, проходя весь цикл: от постановки задач до итогового проекта. Преподаватели — практикующие эксперты, программа регулярно обновляется под требования рынка. Это обучение, которое повышает инженерную зрелость и ценность специалиста.

➡️Старт курса - 27 февраля. Курс доступен в рассрочку. Пройдите короткое вступительное тестирование и получите специальные условия на обучение: https://clc.to/bFJJ_g

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 Regex вместо while-loop

Классический паттерн очистки строк, который встречается в приложениях:

while (text.Contains(" "))
{
text = text.Replace(" ", "");
}


На первый взгляд — читаемо и предсказуемо. На практике — источник проблем под нагрузкой.

Строки в .NET иммутабельны. Каждый вызов Replace() — это полная аллокация новой строки, копирование содержимого и выброс старого объекта на съедение GC. При длинных прогонах повторяющихся символов цикл делает это многократно. Сложность — O(n²), давление на GC — ощутимое.

Правильная замена — Regex.Replace с квантификатором +:
text = Regex.Replace(text, @"-+", "-");


Один проход по строке, одна аллокация результата, линейная сложность.«+» означает одно или более вхождений подряд — именно то, что имелось в виду в цикле, но выражено декларативно.

Оптимальный вариант для .NET 8+ — Source-Generated Regex:
public partial class StringNormalizer
{
[GeneratedRegex(@"-+")]
private static partial Regex ConsecutiveDashRegex();

public static string NormalizeSlug(string input)
=> ConsecutiveDashRegex().Replace(input, "-");
}


Атрибут [GeneratedRegex] переносит компиляцию паттерна на этап сборки. В рантайме — никакого парсинга, никаких лишних аллокаций при инициализации, валидация паттерна прямо в IDE.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📎 Новая фича C#

В C# 15 появится возможность передавать аргументы в конструктор или фабричный метод коллекции прямо внутри выражения коллекции — через элемент with(...).

Раньше, если нужно было создать List<string> с заданной ёмкостью или HashSet<string> с нестандартным компаратором, приходилось делать это отдельно. Теперь всё пишется в одну строку:

// Задаём начальную ёмкость списка
List<string> names = [with(capacity: values.Length * 2), .. values];

// Передаём компаратор в HashSet
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO", "hello"];
// В set окажется один элемент — все строки равны при OrdinalIgnoreCase


with(...) должен быть первым элементом в выражении коллекции.

Фича полезна там, где важна производительность: можно сразу зарезервировать нужный размер буфера и избежать лишних реаллокаций.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📈 Подборка вакансий для шарпистов

.NET-разработчик — от 250 000 ₽, удалёнка

C#/.NET-разработчик — 265 000 ₽, Офис/Гибрид в Екатеринбурге

Middle/Senior .NET Developer — до 3 500 $, удалёнка

➡️ Еще больше топовых вакансий — в нашем канале C# Jobs

🐸 Библиотека шарписта

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📎 Парсим HTML в C#

FreeSpire.Doc для .NET — профессиональная библиотека для обработки документов. Она позволяет разработчикам на C# читать, анализировать и извлекать HTML-контент с минимальным количеством кода и без внешних зависимостей.

Установка через NuGet:

Install-Package FreeSpire.Doc


Необходимые неймспейсы:
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.IO;
using System.Text.RegularExpressions;


Кейс 1. Извлечение текста из HTML-строки

Библиотека справляется с обработкой динамически генерируемых HTML-фрагментов, например, контента из фронтенд-редакторов или HTML-строк, возвращаемых API.

string htmlContent = @"
<html>
<body>
<h2>Описание возможностей продукта</h2>
<p>Этот компонент поддерживает<span style='font-size:14px;'> парсинг HTML</span> и имеет следующие преимущества:</p>
<ul>
<li>Кроссплатформенная совместимость .NET</li>
<li>Не зависит от Office</li>
<li>Быстрое извлечение текста</li>
</ul>
</body>
</html>
";

Document parseDoc = new Document();
Section section = parseDoc.AddSection();
Paragraph paragraph = section.AddParagraph();

try
{
// Ключевой метод: загрузка и парсинг HTML
paragraph.AppendHTML(htmlContent);

// Извлечение чистого текста
string pureText = parseDoc.GetText();

// Очистка текста от лишних пробелов
pureText = Regex.Replace(pureText, @"\s+", " ").Trim();

Console.WriteLine("Извлечённый текст:");
Console.WriteLine(pureText);
}
finally
{
parseDoc.Dispose();
}


Кейс 2. Извлечение структурированного контента из файла

При работе с локально сохранёнными HTML-файлами чаще нужно извлечь конкретные структурированные данные: заголовки, списки, гиперссылки.

string htmlFilePath = "sample.html";

Document parseDoc = new Document();
parseDoc.LoadFromFile(htmlFilePath);

// Извлечение заголовков (h1-h6)
foreach (Section sec in parseDoc.Sections)
{
foreach (Paragraph para in sec.Paragraphs)
{
if (para.GetStyle().Name.StartsWith("Heading"))
{
Console.WriteLine(para.Text.Trim());
}
}
}

// Извлечение элементов списков
foreach (Section sec in parseDoc.Sections)
{
foreach (Paragraph para in sec.Paragraphs)
{
if (para.ListFormat.ListType != ListType.NoList)
{
Console.WriteLine(para.Text.Trim());
}
}
}

// Извлечение гиперссылок
foreach (Section sec in parseDoc.Sections)
{
foreach (Paragraph para in sec.Paragraphs)
{
foreach (DocumentObject docObj in para.ChildObjects)
{
if (docObj is Field field && field.Type == FieldType.FieldHyperlink)
{
string linkText = field.FieldText;
string linkUrl = field.GetFieldCode().Split('"')[1];
Console.WriteLine($"Текст: {linkText}, URL: {linkUrl}");
}
}
}
}


Лучшие практики:

• Всегда оборачивайте Document в using или вызывайте Dispose() для освобождения ресурсов

• Проверяйте существование файлов и обрабатывайте исключения парсинга

• Обрабатывайте извлечённый текст с помощью Regex.Replace для нормализации пробелов

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

💿 S.M.A.R.T. уже знает, что с вашим диском

Диск умирает тихо. Сначала один переназначенный сектор, потом десять, потом в один прекрасный день файлы просто не открываются. Хорошо, если это была музыка. Плохо, если рабочие документы за три года.

Как давно вы проверяли свои файловые хранилища?

Как раз вышла новая версия CrystalDiskInfo. Ничего революционного — но повод скачать актуальную сборку и наконец запустить её.

➡️ Проверить диск

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

💡 Подборка вакансий для шарпистов

Senior разработчик C# — удалёнка

Middle/Middle+ C#/.NET Developer — тоже удалёнка

.NET-разработчик — от 250 000 ₽ и снова удалёнка

➡️ Еще больше топовых вакансий — в нашем канале C# Jobs

🐸 Библиотека шарписта

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👀 YAGNI в реальной жизни

YAGNI (You Aren't Gonna Need It) — принцип из разработки: не делайте то, что может пригодиться когда-нибудь. Работает не только в коде.

Не покупайте инструмент на всякий случай. Нужна дрель — возьмите в аренду или одолжите. Купите перфоратор — будет пылиться 10 лет.

Не записывайтесь на 5 курсов параллельно, «пройду потом» может не случится — вдруг смените род деятельности, к примеру. Закончите один, потом решайте нужен ли следующий.

💬 Бывало такое, что нарушали YAGNI в реальной жизни? Или может наоборот трезво оценили ситуацию и не купились? Интересно будет почитать в комментах 👇

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#entry_point

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🧑‍💻 Юнит-тестирование F# с xUnit

Рассмотрим, как настроить юнит-тестирование F#-библиотеки с помощью xUnit и dotnet test.

Для чистоты разделим библиотеку и тесты на два отдельных проекта внутри одного solution:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService ← бизнес-логика
/MathService.Tests ← тесты


Создаём скелет проекта:
mkdir unit-testing-with-fsharp && cd unit-testing-with-fsharp
dotnet new sln

mkdir MathService && cd MathService
dotnet new classlib -lang "F#"
cd ..
dotnet sln add ./MathService/MathService.fsproj


Наша тестируемая функция:
module MyMath =
let private isOdd x = x % 2 <> 0
let private square x = x * x

let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square


Цель функции — принять последовательность целых чисел и вернуть квадраты всех нечётных элементов.

Настраиваем тестовый проект:
mkdir MathService.Tests && cd MathService.Tests
dotnet new xunit -lang "F#"
dotnet reference add ../MathService/MathService.fsproj
cd ..
dotnet sln add ./MathService.Tests/MathService.Tests.fsproj


Команда dotnet reference add доступна в .NET 10+. На более ранних SDK используйте dotnet add reference.

Тесты:
module MathService.Tests

open Xunit

[<Fact>]
let ``Sequence of Evens returns empty collection`` () =
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)

[<Fact>]
let ``Sequences of Ones and Evens returns Ones`` () =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)

[<Fact>]
let ``SquaresOfOdds works`` () =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.Equal(expected, actual)


➡️ Оригинальная документация

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤑 Мы ждали этого несколько месяцев

Что вы будете делать в этот дополнительный выходной?

Полная раскайфовка на кровати или жёсткий пет-проектинг?

💬 Пишите в комментах 👇

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#entry_point

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚡ AI-агенты в экосистеме .NET: строим надёжный Production в 2026 году

Интеграция нейросетей в корпоративные системы требует не только знания API, но и понимания процессов логирования, трассировки и юридической чистоты. Мы полностью обновили курс по AI-агентам, сделав упор на управляемость и архитектурный подход.

📚 В обновлённой программе:

— инжиниринг качества: измерение метрик производительности и устранение регрессий;
— промышленный RAG: продвинутые подходы к обработке разнородных документов;
human-in-the-loop: встраивание человека в критические узлы принятия решений;
— юридические аспекты: детальное руководство по использованию 152-ФЗ.

Начните учиться уже сейчас — материалы для предварительной подготовки доступны сразу после регистрации.

⏳ Специальные условия до 28 февраля:

— введите промокод Agent для получения скидки 10 000 рублей**;
— участвуйте в **акции «3 курса по цене 1» — выберите два любых курса в дополнение к основному.

👉 Получить доступ к курсу и подаркам

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Что не так с кодом

В коде спрятан намёк на обновление, которое принёс нам C# 10 версии. Может публичные поля? Или конструктор.. Явно что-то связанное со структурой.

👉 Ответ 👈

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#dotnet_challenge

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👩‍💻 Гендерный разрыв в IT

Женщины в IT получают на 40% меньше мужчин — и первый порыв объяснить это дискриминацией. Но если копнуть в данные, картина усложняется. Разрыв формируется ещё в вузе, продолжается в выборе специализации и усиливается декретом.

➡️ Разбираем, где именно ломается воронка

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

👨‍💻 Конец эпохи State Machine

Все мы знаем и любим async/await. Но знаете ли вы, что под капотом происходило всё это время?

Каждый раз когда вы писали async метод — компилятор переписывал его в большой конечный автомат. Вместо вашего чистого кода генерировался struct, реализующий IAsyncStateMachine, с MoveNext(), switch-блоками и кучей вспомогательных полей.

Microsoft перенесла управление async из компилятора прямо в рантайм. Теперь компилятор больше не генерирует конечный автомат — он просто помечает метод атрибутом [MethodImpl(MethodImplOptions.Async)] и делает шаг назад.

Рантайм сам перехватывает await-точки через AsyncHelpers.Await(...), сохраняет только нужные переменные и возобновляет выполнение когда Task готов.

Что это даёт:

• Zero allocation в happy path — никакого лишнего боксинга
• Читаемые стектрейсы с вашими именами методов, а не MoveNext
• Рантайм понимает async-семантику и может оптимизировать цепочки await
• Native AOT поддержка из коробки

Как включить сейчас:

<Features>$(Features); runtime-async=on</Features>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<TargetFramework>net11.0</TargetFramework>


Это самое крупное изменение в async-инфраструктуре .NET за последние годы.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🧩 API Gateway в .NET

API Gateway — это единая точка входа, которая берёт на себя маршрутизацию, аутентификацию, rate limiting и агрегацию запросов. Клиент общается с одним адресом — Gateway сам разбирается, куда слать запрос.

Ocelot vs YARP

Ocelot — классика жанра. Конфигурируется через JSON, прост в старте:

{
"Routes": [{
"UpstreamPathTemplate": "/api/orders/{id}",
"DownstreamPathTemplate": "/orders/{id}",
"DownstreamHostAndPorts": [{"Host": "orders-svc", "Port": 80}]
}]
}


YARP — от Microsoft, более гибкий. Конфигурируется и через JSON, и прямо в коде:
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));


Микросервисы не занимаются проверкой токенов — это задача Gateway. Один раз настроите JWT-валидацию:
app.MapReverseProxy(pipeline => {
pipeline.UseAuthentication();
pipeline.UseAuthorization();
});


И все сервисы за Gateway уже защищены.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

Интегрируем AI в .NET экосистему

Бизнес требует внедрения AI, но не в виде игрушки, а как надёжного сервиса. Мы пересобрали курс «Разработка AI-агентов», сделав упор на промышленные стандарты и архитектуру.

В программе:

🔹 От демо к инжинирингу. Управление ресурсами, кэширование, роутинг и контроль затрат (FinOps для AI).

🔹 RAG нового уровня. Пайплайны для работы с «грязными» данными, таблицами и корпоративными базами знаний.

🔹 LangGraph PRO. Управляемые графы состояний, time-travel для отладки и возможность отката действий.

🔹 Юридический контур. Развёртывание решений с учётом 152-ФЗ.

Стартуй сейчас!
Материалы пре-подготовки доступны сразу.

🎟 Промокод Agent — скидка 10 000 ₽ (до 28 февраля).

👉 Инженерный подход к AI

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🤩 Microsoft раскрыла планы по развитию PowerShell и OpenSSH

Пока Microsoft работает над устранением болевых точек Windows 11, компания параллельно вкладывается в инструменты для опытных пользователей.

PowerShell 7.7 станет центральным обновлением года. Среди ключевых изменений: профили и модули переедут из папки Documents в более подходящее место, появится возможность загружать модули без правки профиля, отложенные уведомления об обновлениях для пакетных менеджеров, поддержка псевдонимов и макросов в стиле Bash, а также собственный MCP-сервер.

Windows OpenSSH может получить поддержку аутентификации через EntraID.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

⚡️ Синхронная коммуникация: HTTP/REST и gRPC

Когда мы говорим о взаимодействии между сервисами, первое, что приходит в голову — синхронный вызов. Один сервис спрашивает, другой отвечает. Просто, понятно, привычно. Разберёмся, какие инструменты есть в .NET и когда каждый из них уместен.

HTTP/REST — разумный дефолт

Большинство проектов начинается именно с REST. Низкий порог входа, понятная отладка через браузер или Postman, огромная экосистема. В .NET для этого используют HttpClient через IHttpClientFactory.

Создание нового HttpClient на каждый запрос — классическая ошибка, которая приводит к исчерпанию сокетов под нагрузкой.

builder.Services.AddHttpClient<IOrderService, OrderService>(client =>
{
client.BaseAddress = new Uri("https://orders-api/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.Timeout = TimeSpan.FromSeconds(30);
});

public class OrderService(HttpClient client) : IOrderService
{
public async Task<Order?> GetAsync(Guid id, CancellationToken ct)
{
var response = await client.GetAsync($"orders/{id}", ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<Order>(ct);
}
}


Сразу добавляйте Polly для повторных попыток и circuit breaker. Без этого первый же временный сбой соседнего сервиса положит весь флоу.

Когда не стоит использовать: если между сервисами тысячи вызовов в секунду с жёсткими требованиями по latency — смотрите в сторону gRPC.

gRPC — когда миллисекунды на счету

gRPC работает поверх HTTP/2, использует бинарную сериализацию через Protocol Buffers и генерирует типизированный клиент из .proto-файла. Это означает меньше трафика, меньше CPU на сериализацию и строгий контракт, нарушение которого не скомпилируется.

// orders.proto
service Orders {
rpc GetOrder (OrderRequest) returns (OrderReply);
}
message OrderRequest { string id = 1; }
message OrderReply { string id = 1; string status = 2; }

// в сервисе
builder.Services.AddGrpcClient<OrdersClient>(o =>
o.Address = new Uri("https://orders-grpc-service"));

public class OrderHandler(OrdersClient grpc)
{
public async Task<OrderReply> Handle(GetOrderQuery q, CancellationToken ct)
=> await grpc.GetOrderAsync(
new OrderRequest { Id = q.Id.ToString() },
cancellationToken: ct);
}


Подводный камень: не тащите gRPC туда, где достаточно REST. Если у вас 10 запросов в минуту — вы просто добавите сложность без выигрыша в производительности.

Публичный API или фронтенд — REST без вариантов. Internal-сервисы с высокой нагрузкой и строгим контрактом — gRPC. Если сомневаетесь — начните с REST, профилируйте, и переходите на gRPC там, где это реально болит.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…

Библиотека шарписта | C#, F#, .NET, ASP.NET

🆚 Микросервисная архитектура vs Монолит

Монолит — это традиционный подход к разработке, где всё приложение представляет собой единое целое. Весь код, бизнес-логика, UI и доступ к данным находятся в одном проекте и деплоятся как единая единица.

Микросервисы — это архитектурный подход, при котором приложение разбивается на набор небольших, независимых сервисов.

Каждый сервис отвечает за конкретную бизнес-функцию, имеет свою базу данных и может разрабатываться, деплоиться и масштабироваться независимо.

Каждый сервис — это отдельное .NET приложение (мини-монолит) со своей БД, API и бизнес-логикой.

Ключевые отличия

➡️ Структура и организация кода

Монолит:

• Один репозиторий, один проект
• Общие зависимости для всех модулей
• Прямые вызовы методов между компонентами

Микросервисы:

• Множество репозиториев или монорепозиторий
• Независимые зависимости для каждого сервиса
• Коммуникация через API: HTTP, gRPC, сообщения

➡️ Развертывание

Монолит:

• Деплой всего приложения целиком
• Один сервер или кластер серверов
• Простая инфраструктура

Микросервисы:

• Независимый деплой каждого сервиса
• Контейнеризация и оркестрация
• Сложная инфраструктура с API Gateway, Service Discovery

➡️ Масштабирование

Монолит:

• Вертикальное масштабирование — увеличение ресурсов сервера
• Горизонтальное масштабирование всего приложения
• Неэффективно, если нагрузка только на одну функцию

Микросервисы:

• Горизонтальное масштабирование конкретных сервисов
• Масштабируются только те части, которым нужно
• Оптимизация затрат на инфраструктуру

➡️ База данных

Монолит:

• Одна общая база данных
• ACID транзакции работают нативно
• Простота в управлении данными

Микросервисы:

• База данных на каждый сервис
• Распределенные транзакции
• Eventual Consistency

➡️ Технологический стек

Монолит:

• Единый стек технологий
• Сложно внедрить новые технологии
• Один язык программирования

Микросервисы:

• Каждый сервис может использовать свой стек
• Гибкость в выборе технологий
• Можно смешивать .NET, Node.js, Python и др.

Микросервисы — не серебряная пуля, а инструмент для решения конкретных проблем масштаба и сложности.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор

Читать полностью…
Subscribe to a channel