Когда я первый раз услышал про .NET Aspire, я подумал что это какая-то очередная лажа от Майкрософта, про которую все забудут через неделю.
Особенно, учитывая какую дичь часто завозят в шарп (например те же ужасно спроектированные Primary Constructor'ы про которые я писал, или вот прикол-пропозал от самого Тоуба). Так что ожидания у меня, честно говоря, были ниже нуля.
Но попробовав его лично, я был, честно говоря, шокирован. Трепещите, жависты!! Трепещите гошники! Трепещите питонисты - такого вы еще точно не видели.
Я даже представить не мог, что DevEx можно сделать настолько офигительным.

Собственно, о чем это я
Так вот, что же такое .NET Aspire?
> .NET Aspire is an opinionated, cloud ready stack for building observable, production ready, distributed applications. .NET Aspire is delivered through a collection of NuGet packages that handle specific cloud-native concerns. Cloud-native apps often consist of small, interconnected pieces or microservices rather than a single, monolithic code base.
Aspire - это темплейт + opinionated стек для микросервисных приложений. Он предоставляет следующие фичи:
Оркестрация - Aspire делает простым запуск и подключение многопроектных приложений и их зависимостей к локальным средам разработки. Он сам поднимает все апи, динамически генерирует докерфайлы, реплицирует сервисы при необходимости, сам поднимает нужную инфраструктуру - докер или подман контейнеры с базой, брокерами и кешом
Готовый тулинг - в темплейте, Aspire по умолчанию генерит код и настройки для OpenTelemetry - логи, метрики и трейсы - трех столбов observability. Не нужно возиться с секретами, каким-то своим поднятием Prometheus'а - Aspire сам коллектит всю телеметрию с сервисов, чтобы затем показывать это все в админке
Крутой локальный дашборд - все метрики, список контейнеров, логи, трейсы - в одной готовой админке, причем смотрящейся достаточно неплохо. Не надо ничего поднимать локально в докер композах - ни графану ни прометеус. Коллектор .NET Aspire'а получит все самостоятельно
Легкий деплой в Azure/k8s - по словам команды которая работает над Aspire, на релизе можно будет в одну кнопку запубликовать весь проект на облако в Azure, либо сгенерировать k8s манифесты чтобы разворачивать на своей/чужой инфраструктуре
Например - у вас есть продукт который находится в монорепе на 30 сервисов. Как правило, в микросервисах про локальное тестирование работы нескольких сервисов одновременно можно забыть - самому это настраивать как правило очень больно. С Aspire - вы сможете без проблем локально потестить то что вам надо, например сценарии failover'ов.
Хотя Aspire и ориентирован в первую очередь на распределенные приложения, его можно применять даже если у вас всего один сервис - например чтобы локально продебажить observability - посмотреть собираются ли локально метрики и трейсы. На мой взгяд - достаточно полезно.
Простота интеграции в существующие проекты
Одним из моих самых больших concern'ов было то, что Aspire будет очень сложно прикрутить в существующие проекты. Но тут Майки это смогли очень неплохо обыграть.
На на самом деле, все невероятно просто. Надо сделать всего две вещи:
Создать отдельный проект AppHost, и в нём зареферить проекты которые ты хочешь запустить, в
DistributedApplicationBuilderзарегистрировать соответствующие проектыДля нужных фичей, которые идут в Aspire из коробки (например OpenTelemetry, Service Discovery, коннект в PostgeSQL), нужно поставить отдельный Nuget и просто заменить регистрацию в Startup, либо вызвать Extension метод из ServiceDefaults
Всё! Aspire настроен.
Погнали тестить
Давайте теперь гл��нем на примере. Возьмем стандартный Starter Application темплейт.
Для начала, надо поставить Aspire. Для этого выполняем две команды:
dotnet workload update dotnet workload install aspire
Если вы используете Rider, так же как и я, то нужно дополнительно поставить плагин: https://blog.jetbrains.com/dotnet/2024/02/19/jetbrains-rider-and-the-net-aspire-plugin/
Если используете Preview версию Visual Studio, насколько я помню там Aspire поставлен по умолчанию.
Итак, генерируем проект в нашей IDE, получаем следующую структуру:

Быстренько пробежимся по проектам:
TestAspire.AppHost- основной проект где мы описываем наше распределенное приложение - какие контейнеры поднимать (База, Брокер, Кэш), что от чего зависит, и так далее.TestAspire.ServiceDefaults- проект, содержащий extension method'ы для телеметрии, Service Discovery и другие настройки. Этот проект подключается во все остальныеTestAspire.ApiService- API на ASP.NET Core, обычный WeatherApi из темплейта для webapiTestAspire.Web- Blazor фронтенд приложение, тоже дефолтный темплейт для блазора
AppHost
Данный проект является ядром всего Aspire. По сути, чтобы Aspire подключить и воспользоваться его фишками, достаточно только добавить этот проект, и прикрутить нужные нам зависимости. Сам проект состоит всего из одного файла (не считая appsettings.json), со следующим содержимым:
// Program.cs var builder = DistributedApplication.CreateBuilder(args); var apiService = builder .AddProject<Projects.TestAspire_ApiService>("apiservice"); builder.AddProject<Projects.TestAspire_Web>("webfrontend") .WithExternalHttpEndpoints() .WithReference(apiService); builder.Build().Run();
Недурно, верно? За плату в 10 строк и 1 проект, мы получаем набор невероятных фичей, работающих из коробки, про которые я писал ранее (админка, телеметрия, и т.д).
Здесь важна именно регистрация сервисов:
var apiService = builder .AddProject<Projects.TestAspire_ApiService>("apiservice"); builder.AddProject<Projects.TestAspire_Web>("webfrontend") .WithExternalHttpEndpoints() .WithReference(apiService);
Чтобы добавить проект, достаточно вызвать одни метод расширения. Строка в методе - это название сервиса либо контейнера если приложение будет докеризированно. Для Api мы просто добавляем проект, но для Blazor - мы дополнительно добавляем референс на apiService - я покажу это дальше, это будет использоваться для Service Discovery .
Что меня достаточно впечатлило, это возможность легкого поднятия нужной инфраструктуры. Например:
// Качаем доп нугет пакет - Aspire.Host.Postgres // Есть еще подобные для Kafka, Redis, и другой инфры builder.AddPostgres("database").WithPgAdmin();
Т.е фактически, теперь не надо хранить кучу docker-compose.yaml с инфраструктурой. Не надо писать shell скрипты или makefile'ы чтобы их запускать. Не нужно ничего запускать вручную. Не надо париться насчет volume'ов, network'ов и прочих вещей между контейнерами, когда ты к примеру подключаешь локально тот же Postgres. Не нужно настраивать env переменные контейнеров. Захотел к постгресу подключить pgadmin - сделал это в одну строку, без конфигурации с оригинальным докером.
И все работает мать его локально. Из коробки. С докером и инфрой.
Это. Просто. Топ.
ServiceDefaults
Этот проект - добавляет некие "платформенные" extension методы, которые подключают одинаковые инфраструктурные библиотеки во все проекты внутри Solution'а. По умолчанию при генерации темплейта, там настроен сбор телеметрии. В случае, если надо добавить какой-то особый коллектор (например Prometheus), то этот код добавляется именно туда.
Метод builder.AddServiceDefaults(); добавляет все нужные зависимости в executable проекты.
ApiService
Обычное webapi приложение для погоды, из темплейта. Не отличается вообще ничем от дефолтного, кроме как добавлением ServiceDefaults:
// Program.cs -> ApiService ... ... builder.AddServiceDefaults(); ... ...
Web
Обычное Blazor приложение. Точно также, как и для ApiService, все что в проекте меняется по отношению к дефолтному такому же темплейту но без Aspire это следующие детали:
// Program.cs // 1 builder.AddServiceDefaults(); // 2 builder.Services.AddHttpClient<WeatherApiClient>(client => { // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP. // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes. client.BaseAddress = new("https+http://apiservice"); });
Здесь изменение не одно, а два:
Добавляем дефолтные сервисы (телеметрию, настройки) из
ServiceDefaultsДобавляем http клиента на ApiService, но в особом формате адреса -
https+http://apiservice. Это позволит воспользоваться Service Discovery - не хардкодить url'ы между проектами. Aspire сделает это автоматически.

Дашборд Aspire
Больше всего в разработке я обожаю две вещи: Developer Experience и красивый визуал. В обоих этих пунктах я всегда стараюсь дотошно выстраивать мой флоу разработки - я сильно запариваюсь на ранних стадиях проектов, чтобы их можно было легко тестировать и дебажить локально.
И готовая админка, которую тебе не надо поднимать и как-то там настраивать - это прям бальзам на душу.
Покажу основные страницы куда точно стоит зайти. Начнем с основной:
Resources

Здесь у нас список всех контейнеризованных приложений. Тут могут быть как .NET приложения, так и обычные имаджи, например тот же Postgres или Kafka. Тажке можно фронт запускать, все что запускается через npm - например тот же Vue на vite или Next.js.
У каждого приложения есть статус, описание, а также ссылки на просмотр логов, деталей по контейнерам и на endpoint (например на swagger). Достаточно удобно.
Сюда еще много что хотят прикрутить, например видел пропозал на кнопку для рестарта сервисов, если они упали. (Ссыль на issue)
Traces

Есть страница с тресами - причем заметьте, оно отлично работает в совокупе! На скрине как раз показан пример с трейсами покрывающими сразу два сервиса - фронт и вебапи. Причем хочу заметить, сама страница выглядит неплохо, на мой личный взгляд сильно красивее чем дефолтная страница Jaeger'а.
Structured logs

Точно также есть инфа по логам - плюс хочу обратить внимание, в проекте по умолчанию настроена привязка логов к трейсам - и по некоторым логам, которые относятся к запросам можно вытянуть и посмотреть на трейс
Metrics

Метрики могут быть как свои, так и дефолтные. Дефолтных метрик достаточно много - и данные по GC, и по локам, по kestrel'у, много по чему.
Это только начало...
То что меня поразило больше всего - это только Preview проекта. Он еще даже не в релизе! Сам проект развивается очень активно, сторонние контрибьюторы во всю активно предлагают улучшения.
Если это всего лишь превью, то мне даже страшно представить чего ждать от релиза. И я если честно не представляю, как другие платформы собираются конкурировать с дотнетом по удобству разработки (кроме наверное разве что Vercel - они тоже невероятно крутые штуки делают, там удобство разработке как минимум не уступает)
В любом случае, настоятельно рекомендую попробовать Aspire. Это одна их тех вещей, которая реально получилась хорошо, и мне кажется сможет сильно поменять взгляд на то, как должна выглядеть платформенная разработка.
(UPD: Добрые люди в комментах подсказали, что оказывается он уже релизнулся, 2 недели назад, первый GA релиз можно найти здесь)
