Обновить
128K+

.NET *

Хаб со знаниями про .NET

67,81
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Как упростить тестирование ASP.NET Core API

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели4K

Разрабатывая приложения, мы стараемся не злоупотреблять дублированием кода. Из часто встречающегося кода мы формируем библиотеки, а для их соединения в инфраструктуре ASP.NET Core приложения используем DI-контейнер. Инфраструктура тестирования для ASP.NET Core API, как правило, тоже повторяется, но какие инструменты помогают нам переиспользовать тестовый код?
Разработчики Python решают эту задачу с помощью pytest.fixtures, однако в dotnet-экосистеме (xUnit) хорошего аналога пока нет.
В статье рассмотрим пример, как в несколько строк собрать полноценное интеграционное окружение с изолированной БД, фейковым временем и случайностью, а также как донастроить это окружение для отдельно взятого теста.

Для кого эта статья: для бэкенд-разработчиков (на .NET), технических лидов, QA-инженеров, которые пишут код, и всех, кто устал от бессмысленно повторяющегося кода в тестах.

Если вы пишете на C#, но хотите добавить тестам элегантности Python — добро пожаловать.

Читать далее

Новости

REDB изнутри, статья 1: 13 таблиц, на которых работает всё

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели11K

В предыдущей статье я разобрал что умеет REDB на практике: code-first схемы, LoadAsync без Include, LINQ с оконными функциями, деревья, redb.Route и redb.Tsak. Если не читали — начните с неё, она даёт общую картину.

Теперь начинаю цикл «REDB изнутри» — серия статей про устройство хранилища: как хранятся объекты и свойства, как работают схемы и кэш структур, как LINQ превращается в SQL, как устроены деревья, права, оконные функции. Всё с реальным SQL под капотом.

Первая статья цикла — про саму базу данных. Без понимания схемы таблиц всё остальное будет висеть в воздухе.

Читать далее

Ошибки и подозрительные места в исходниках .NET 10

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели11K

Чуть больше полугода назад состоялся релиз .NET 10. Остались ли дефекты в исходном коде проекта, спустя месяцы после релиза? Постараемся сегодня найти ответ на этот вопрос.

Читать далее

redb.Route 3.0.1 — плоская навигация по DSL, рефакторинг CRTP и тихий null

Уровень сложностиСредний
Время на прочтение3 мин
Охват и читатели9.4K

Продолжаем серию про redb.Route — вводная и разбор четырёх in-memory каналов уже вышли. Сегодня не статья серии, а релизная заметка: в 3.0.1 три конкретных изменения в DSL, каждое с боевым примером из демо.

До 3.0.1 глубоко вложенные scope-ы требовали закрывать себя в строго обратном порядке — утомительно и легко ошибиться. Три вещи изменились.

Читать далее

Rust внутри .NET: как упаковать native-библиотеку в один NuGet-пакет

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели11K

FFI, P/Invoke, EmbeddedResource, DllImportResolver и кроссплатформенная доставка без ручного копирования .dll.so и .dylib.

Когда .NET-коду нужно вызвать Rust-библиотеку, первый прототип обычно заводится быстро:

Rust собирается как cdylib;

функции экспортируются через extern "C";

C# вызывает их через DllImport;

результат возвращается через указатель.

Читать далее

Eventual Consistency: как мы починили тормоза апрува и сломали бюджет

Уровень сложностиСложный
Время на прочтение14 мин
Охват и читатели6.5K

Мы убрали одну блокировку, чтобы апрувы перестали тормозить. Через несколько недель из‑за этого клиент пробил квартальный бюджет — а наша система этого даже не заметила.

Полгода после MVP, первые крупные клиенты. B2B travel SaaS, конец 2016-го. Компании начали подключать не по 15–20 человек, а по 80–100.

Один из новых клиентов оказался кратно крупнее остальных — финансовый департамент почти на сотню человек с фиксированным квартальным бюджетом на командировки порядка нескольких сотен тысяч рублей. К середине квартала большая часть бюджета уже потрачена, остаток — заметно меньше половины. Два руководителя — в разных городах, в разных браузерах — одновременно открывают форму апрува командировок. Оба видят один и тот же остаток. Один одобряет крупную поездку, другой почти в то же время — ещё одну, сопоставимую по сумме; каждая по отдельности в остаток вписывалась. Оба получают подтверждение. Вместе две поездки пробили лимит — перерасход, которого ни один из руководителей в одиночку не допускал.

Обнаружили через 3–4 часа — когда финансовый менеджер клиента открыл квартальную сводку и позвонил нам.

Читать далее

redb.Route изнутри: четыре in-memory канала и Exchange, который их связывает

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели10K

Прошлая статья была обзорной — что такое redb.Route, зачем нам понадобился свой Apache Camel под .NET, как выглядит боевой маршрут. Если не читали, коротко: это fluent C# DSL для интеграции — 22 коннектора (~30 URI-схем, если считать https/wss/es-варианты), ~30 паттернов EIP нативно через 41 процессор8 in-process компонентов, компилируемый expression-движок. Сегодня заходим внутрь. Не список фич, а рабочий разбор.

Серия будет длинной, поэтому сразу скажу, что и в каком порядке:

Читать далее

Создаём DSL на C#: Пишем парсер

Уровень сложностиСредний
Время на прочтение38 мин
Охват и читатели9.1K

Создаю собственный DSL на C#: рассказываю о том, как написать парсер, и как его оптимизировать. Так же покажу как работает обещанный DFA.

Читать далее

redb.Route — Apache Camel для .NET, который мы написали потому что выхода другого не было

Уровень сложностиСредний
Время на прочтение38 мин
Охват и читатели10K

У вас не 5 микросервисов — у вас десятки. Бэкенд, который рос три года: монолит, расколотый на куски, GPS-фид от автопарка, мобильное приложение водителя, веб-кабинет диспетчера, интеграции с SAP / 1С / регуляторами / маркетплейсами, отдельный SMTP-воркер, отдельный PDF-генератор, отдельный шедулер ночных пересчётов. Между ними — Kafka (несколько кластеров, по топику на домен), RabbitMQ (RPC + pub/sub + DLQ), Redis (кэш, last-known-state, pub/sub-каналы), пара HTTP-эндпоинтов наружу, SFTP с поставщиком, SQL-polling outbox-таблицы старого монолита, MQTT с трекеров, IBM MQ для одного древнего банковского контура, SignalR-хабы для real-time-дашбордов. На каждом стыке — свой ретрай, свой DLQ (или нет DLQ), своя сериализация, свои метрики (или нет метрик), своя бойлерплейт-обвязка из консьюмеров и try/catch.

Каждый из этих стыков живёт своей жизнью в Program.cs соответствующего сервиса. Каждый — это hand-rolled цикл:

Читать далее

Убейте GC-спайки в играх и сервисах: коллекции без аллокаций на .NET

Время на прочтение8 мин
Охват и читатели10K

Каждый разработчик на .NET сталкивался с этим. Всё работает быстро, но иногда случается внезапный фриз. Игра проседает с 60 до 30 FPS на секунду. Сервис отвечает на запрос 100 мс вместо обычных 10. UI дёргается.

Виновник — Garbage Collector.

Когда GC решает собрать мусор, он останавливает все потоки приложения (Stop-The-World). Для игр и real-time сервисов это катастрофа.

Стандартные коллекции .NET создают мусор везде:

Читать далее

200 000 объектов за 2 мс: как выбирать топ-K без полной сортировки

Время на прочтение8 мин
Охват и читатели9.8K

В real-time играх и серверах часто возникает задача: из N объектов нужно выбрать K лучших, чтобы обновить их в этом кадре.

Читать далее

10 000 объектов за 0.083 мс: как распределить бюджет рендеринга без просадок FPS

Время на прочтение7 мин
Охват и читатели6.3K

Каждый игровой инженер сталкивался с этим. У вас есть 16.67 мс на кадр (60 FPS). В сцене 10 000+ объектов: враги, частицы, тени, декали, постыффекты. Нужно решить: на что потратить бюджет, чтобы игрок видел самое важное в максимальном качестве, а FPS не проседал?

Типичные подходы и их недостатки

1. Дистанционный LOD (расстояние до камеры)

Читать далее

redb — типизированное хранилище для .NET поверх Postgres/MSSQL: без миграций, без Include, с полным LINQ

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели6.7K

Типизированное хранилище для .NET поверх Postgres и MSSQL. C#-класс как схема — без миграций, без Include, с полным LINQ. Работает в проде.

LoadAsync вместо 40 Include →

Ближайшие события

Я дважды не смог собрать команду для pet-проекта. Потом за полгода закрыл всё с Claude

Уровень сложностиПростой
Время на прочтение15 мин
Охват и читатели8.2K

История о том, как Fleans — движок workflow на .NET Orleans и BPMN 2 — родился из упрямства, фрустрации, Camunda-которая-стала-платной и одного не самого очевидного разговора с ИИ.

Читать далее

Почему ваш Parallel.ForEach впустую сжигает CPU — ускоряем обработку данных до 600+ раз

Время на прочтение8 мин
Охват и читатели11K

Практически в каждом высоконагруженном .NET-проекте рано или поздно появляется один и тот же паттерн:

Есть коллекция данных.

Для каждого элемента нужно выполнить дорогую операцию.

Например:

вычислить хэш;

Читать далее

Видеонаблюдение на базе Android устройства за 3 недели

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели10K

Я начал замечать открытые щитки у себя на этаже, в голове пронеслись мысли про favourite guys в поисках запрещённых ресурсов, потому решил озаботиться круглосуточным видеонаблюдением лестничной площадки.

Заказал на Али недорогую рыбоглазую камеру и влепил её под потолок прямо над щитком. Но мой бюджет был ограничен, а в тумбочке лежит несколько неиспользуемых Андройд телефонов, их то я и решил применить в качестве NVR устройства, вместо покупки такового. А ещё телефон меньше жрут и совсем не шумят, в отличие от хардварных версий записывающих устройств. Встроенной карты памяти на камере нет, поэтому нужно внешнее устройство.

Загуглил, попробовал несколько программ и остановился на одной из них, которая выглядела как самая зрелая, с большим количеством функций, да ещё и платной версией. Платную версию конечно же купить у нас нельзя, но скачать её патченную сестру с 4pda можно, что я и сделал. Алексей (автор), прости, но другого варианта у меня не было.

Какие у неё функции достоинства:

Читать далее

KeyboardHook: кроссплатформенный глобальный перехват клавиатуры и мыши для .NET

Время на прочтение8 мин
Охват и читатели6.9K

Рассказываю, как написал кроссплатформенную .NET-библиотеку для глобального перехвата клавиатуры и мыши. Под капотом: WH_KEYBOARD_LL на Windows, CGEventTap на macOS и polling через XQueryKeymap на Linux. Один интерфейс, три реализации, ноль внешних зависимостей.

Читать далее

Реальный time series агрегатор: как обрабатывать 10 событий/сек на графе из 300k узлов

Время на прочтение7 мин
Охват и читатели9.1K

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

Ширина слоя — 5000 узлов. Количество слоёв — 60. Общее число узлов — 300 000.

Каждую секунду приходит 10 новых событий (изменений на входе). Наивный подход — пересчитать всё с нуля — будет перебирать все 300 000 узлов на каждое обновление. При 10 обновлениях в секунду это 3 млн вычислений узлов в секунду. А если ширина слоя 100 000 и слоёв 100? Получаем 10 млн узлов на пересчёт. Компьютер не справляется.

Читать далее

Микросекундные оценки опционов: как пересчитать портфель из 200k инструментов за 10 мс

Время на прочтение7 мин
Охват и читатели9K

Финансовые системы предъявляют жёсткие требования к производительности.

Риск-департамент запрашивает переоценку портфеля из 200 000 опционов. Маржинальная система требует пересчитать все позиции клиентов после сильного движения рынка. Алгоритмический трейдер хочет оценить Greeks для тысяч потенциальных сделок за миллисекунды.

Стандартные подходы на .NET дают сбой по трём причинам.

Причина 1: Объектная модель

Каждый опцион становится отдельным объектом в куче. Виртуальные методы, ссылки, разрозненное расположение в памяти. Для 200 000 объектов — миллионы байтов, GC-паузы на сборку, промахи кэша процессора.

Причина 2: Позлементные вычисления

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

Причина 3: Аллокации в горячем пути

Каждый вызов new double[100000] для хранения промежуточных результатов — это давление на GC. В 24/7 сервисе такие аллокации накапливаются и вызывают непредсказуемые паузы.

Требования к решению

Читать далее

Как обслуживать 10 000 NPC в кадре без просадок GC

Время на прочтение6 мин
Охват и читатели10K

Допустим, вы делаете симуляцию города. Или RTS. Или RPG с открытым миром. И у вас в сцене одновременно находится 5, 10, а то и 20 тысяч живых существ. У каждого свои цели, приоритеты, эмоции, социальные связи.

Ваша архитектура AI начинает трещать по швам.

Классический подход — дать каждому NPC компонент с методом Update() — перестаёт работать где-то после 500–1000 объектов. Дальше начинаются проблемы:

Читать далее
1
23 ...