產業新聞

Aspire 13.2:.NET服務開發者需要知道的事項

分享一些Iron Software工程團隊在Aspire 13.2版本釋出的筆記。 我們發佈.NET程式庫(IronPDFIronOCRIronXLIronWordIronBarcode,等等),幾乎每位客戶的電話都會涉及到分佈式應用程式編排。 這就是為什麼我們關注Aspire發佈的原因。 13.2是第一個讓CLI感覺可以實際替代儀表板進行日常工作的版本,並且有一些會在升級時影響到您的重大變更。

這不是發佈筆記的重複。 官方的最新消息頁面有詳盡的清單。這是那些在工作代碼庫中真正有用的東西,外加需要注意的陷阱。

概要

  • CLI 現在真的是可編寫指令碼的:分離模式、aspire 停止、隔離模式、JSON輸出
  • 如果您想放棄編排層的.csproj,TypeScript AppHost正在預覽中
  • 配置文件合併到aspire.config.json(舊文件自動遷移)
  • Foundry取代了Azure AI Foundry。 這會讓您的構建失敗
  • WithSecretBuildArg 重命名為 WithBuildSecret
  • 服務發現環境變量現在使用方案,而不是端點名稱(存在靜默中斷風險)
  • 客戶端集成中的默認Azure憑證行為已更改

CLI終於真正成為CLI

這是重要的。一度於13.2之前,aspire run阻塞您的終端,儀表板是管理運行中的apphost唯一現實的表面。適合單人開發,對於CI、集成測試或任何由代理驅動的工作流都很尷尬。

13.2解決了這個問題:

# Run in the background
aspire run --detach

# Or the new shortcut
aspire start

# See what's running
aspire ps

# Stop it
aspire 停止
aspire 停止 --all
# Run in the background
aspire run --detach

# Or the new shortcut
aspire start

# See what's running
aspire ps

# Stop it
aspire 停止
aspire 停止 --all
SHELL

結合--format json(輸出到stdout同時狀態消息發送到stderr,這對於您要發送到其他地方時很重要),您可以圍繞此構建真正的自動化。 aspire ps --resources --format json是編輯器集成和指令碼的堅固構建塊。

隔離模式是未被讚譽的英雄

--isolated是我們一直等待的。 它運行apphost,使用隨機端口和隔離用戶機密,防止端口衝突和配置衝突:

aspire run --isolated
aspire start --isolated
aspire run --isolated
aspire start --isolated
SHELL

如果您曾經嘗試同時運行兩個相同apphost的檢出版本,例如主分支對功能分支、並行集成測試或代理驅動工作流,您就會感受到這種痛苦。 隨機端口加上分離機密意味著您可以終於只需啟動N個副本而不必擔心。

單就git工作樹而言,這就值得升級。 對於引入真實服務和本機依賴項(如Chrome渲染PDF生成、Tesseract用于OCR,常用的重量級應用)的集成測試套件來說,這將是波動與可靠之間的區別。

aspire doctor 和 aspire describe

aspire doctor運行在您的環境中:開發者憑證狀態、容器運行時版本、.NET SDK、WSL2配置、代理配置。 這是每個框架都應具備的特性,但大多數都不會采用。 輸出是可執行的。 當出現問題時,它告訴您該怎麼做。

aspire describe --follow給您從終端流的資源狀態視圖。 與儀表板顯示的數據相同,但可以進行管道處理。 將其放入tmux窗格,您就能在80列中獲得大部分儀表板的價值。

資源命令更整潔了

舊的resource-start / resource-停止 / resource-restart 命令已棄用,取而代之的是更整潔的子命令形式:

aspire resource api restart
aspire resource api rebuild
aspire resource api restart
aspire resource api rebuild
SHELL

rebuild是新的。 它可以停止、構建並重新啟動單個 .NET 項目資源,而不會拆除整個apphost會話。 如果您曾經在12個資源圖中更改了一項服務並煩惱於必須重新啟動所有內容,這就是解決方案。 我們自己也有這種感受:當您在PDF渲染模板上進行迭代或調整OCR預處理時,僅僅為了重新加載一個項目而重新啟動整個圖形會很快變得陳舊。

在不離開CLI的情況下管理機密和憑證

兩個新的專用命令組:

aspire certs clean
aspire certs trust

aspire secret set ApiKey super-secret-value
aspire secret list --format json
aspire certs clean
aspire certs trust

aspire secret set ApiKey super-secret-value
aspire secret list --format json
SHELL

aspire secret是更大的一個勝利。 它映射到後台的用戶機密存儲與應用模型中的AddParameter(..., secret: true)相同,但您不需要安裝 .NET CLI 即可管理它們。 在一個多語言的apphost中,不是每個開發人員都有.NET SDK,這很重要。

aspire wait for CI

aspire wait api --status healthy --timeout 120
aspire wait api --status healthy --timeout 120
SHELL

阻止一個資源狀態。 結合sleep 30 && hope

配置:一個文件統治所有

Aspire正在整合其配置文件。 舊的apphost.run.json之間的分化已經消失,由項目根目錄下的單一aspire.config.json取代:

{
  "appHost": {
    "path": "apphost.ts",
    "language": "typescript/nodejs"
  },
  "sdk": { "version": "13.2.0" },
  "channel": "stable",
  "profiles": {
    "default": {
      "applicationUrl": "https://localhost:17000;http://localhost:15000"
    }
  }
}

遷移是自動的。 當你在現有項目中第一次運行任何aspire命令時,舊的文件被合併到新格式中,路徑重新基於項目根目錄。 舊文件被保留下來,因此您仍然可以同時使用舊的CLI版本。全局設置(globalsettings.json)也會被遷移。

如果您有自動化程序直接使用apphost.run.json,請計劃將其移動。

TypeScript AppHost(預覽)

即便您在第一天不會用上,這仍然很有趣。 您現在可以用 TypeScript 編寫您的apphost而不是C#:

import { createBuilder } from './.modules/aspire.js';

const builder = await createBuilder();

const cache = await builder.addRedis("cache");

const api = await builder.addProject("api", "../api")
    .withReference(cache)
    .waitFor(cache);

await builder.build().run();

在內部,TS apphost作為一個訪客過程運行,通過JSON-RPC在本地傳輸上與Aspire的.NET編排主機進行通信。 同樣的資源模型,同樣的儀表板,同樣的集成,只是用TypeScript表示。

有趣的部分是代碼生成。 當您運行aspire add時,CLI會檢查集成的.NET程序集並生成一個TypeScript SDK到.modules/中。 aspire run自動運行)。 13.2的生成器還增加了Go、Java和Rust測試目標,這暗示了方向。

對於像我們這樣以.NET為首的團隊來說,這更多是"觀看這個"而不是"實際發佈這個",但代碼生成模式意味著未來的多語言apphost語言都遵循相同的模式。 查看多語言架構文檔以了解主機橋接是如何工作的。

儀表板:遙測導出/導入是新的玩具

儀表板獲得了真正的導出/導入工作流程。 在設置→管理中,選擇資源和遙測類型並將其作為JSON在zip中導出。稍後重新導入儀表板,或者將其交給其他人(或者一個LLM)進行分析。

aspire export CLI命令產生相同的捆綁:

aspire export --output .\artifacts\aspire-export.zip
aspire export <resource>
aspire export --output .\artifacts\aspire-export.zip
aspire export <resource>
SHELL

對於bug報告非常有用。 而不是"這裡有一些截圖和一個日誌文件",您可以附上實際遙測狀態的快照。

其他儀表板方面的筆記:

  • 現在可以直接從儀表板UI設置資源參數,並選擇持久保存到用戶機密中
  • 環境變量可以從資源詳細視圖中作為.env文件導出
  • 資源圖布局使用自適應力導向的定位。 複雜的圖形顯著地不再那麼混亂
  • /api/telemetry上的遙測HTTP API返回OTLP JSON; 支持?follow=true進行NDJSON流。 端點涵蓋資源、跨度、日誌和跟踪(包括/traces/{traceId}用於完全跟踪查找)

獨立儀表板現在將遙測API默認設置為關閉。 如果您自己托管儀表板並且依賴於API,您需要DASHBOARD__API__PRIMARYAPIKEY)。 AppHost集成場景仍然有效,因為Aspire.Hosting會自動將API連接好以用於工具化。

應用模型值得注意的地方

WithMcpServer

您可以在應用模型中聲明一個資源託管MCP端點:

var api = builder.AddProject<Projects.MyApi>("api")
    .WithMcpServer("/mcp");
var api = builder.AddProject<Projects.MyApi>("api")
    .WithMcpServer("/mcp");
Dim api = builder.AddProject(Of Projects.MyApi)("api") _
    .WithMcpServer("/mcp")
$vbLabelText   $csharpLabel

Aspire工具化然後可以發現並代理那個端點。 如果您正在發佈任何向編碼代理暴露工具的內容,這是將其接入最乾淨的方法。 支持通過選項提供自定義路徑或端點名稱。

上下文端點解析

這是直到您需要時才會注意到的東西。 端點現在可以從特定的呼叫者或網絡的角度解析:

var endpoint = redis.GetEndpoint("tcp");

var url = await endpoint.GetValueAsync(new ValueProviderContext {
    Caller = containerApp.Resource,
});
var endpoint = redis.GetEndpoint("tcp");

var url = await endpoint.GetValueAsync(new ValueProviderContext {
    Caller = containerApp.Resource,
});
Dim endpoint = redis.GetEndpoint("tcp")

Dim url = Await endpoint.GetValueAsync(New ValueProviderContext With {
    .Caller = containerApp.Resource
})
$vbLabelText   $csharpLabel

相同的Redis端點會根據上下文從主機進程解析到cache:6379PublicInternet,如果您更願意選擇一個網絡而不是呼叫者。

發佈說明明確指出這些API在13.1版本中存在,但未正確運行。 所以如果您在13.1中對它們進行了任何編程,請重新測試。詳細信息請參見資源層次結構文檔

容器構建機密

WithSecretBuildArg 重命名為 WithBuildSecret。 新的名稱更明確。 這些通過Docker/Podman作為正確的構建機密而不是構建參數(泄露到映像歷史中)。

builder.AddContainer("worker", "contoso/worker")
    .WithDockerfile("../worker")
    .WithBuildSecret("ACCESS_TOKEN", accessToken);
builder.AddContainer("worker", "contoso/worker")
    .WithDockerfile("../worker")
    .WithBuildSecret("ACCESS_TOKEN", accessToken);
$vbLabelText   $csharpLabel

構建機密現在也可以是文件(例如,.npmrc 用於容器構建中的私有註冊表身份驗證),涵蓋大多數現實世界的用例。

集成:重要的那些

完整清單很長。 以下是我會標註的:

  • Docker Compose 發佈 現在已穩定(以往是預發佈)。 AddDockerComposeEnvironment 在發佈時會從您的應用模型中生成 docker-compose.yaml。當 "部署到 Azure" 不是答案時,這是一個有用的逃生口。 值得一提的是,如果您正在推出包含本機依賴項的容器,IronPDF、IronOCR 和 IronXL 都支持Linux容器和Docker,因此生成的compose文件通常可以正常運行而不需要手動修改。
  • Azure Virtual Network 集成(Aspire.Hosting.Azure.Network)允許您在apphost中聲明VNet,子網,NSG,NAT網關和私有端點。在目標上自動創建私有DNS區域,虛擬網絡鏈接並禁用公眾訪問。 這是以前需要維護單獨的Bicep文件的類型。
  • Azure Data Lake Storage 獲得了託管和客戶端支持:AddAzureDataLakeServiceClient / AddAzureDataLakeFileSystemClient。DI註冊、重試、健康檢查、遙測,通常的Aspire堆棧。
  • MongoDB EF Core 有了一個新的客戶端集成(Aspire.MongoDB.EntityFrameworkCore)。 AddMongoDbContext<TContext> 適用於典型案例,或者如果您自己註冊DbContext則使用EnrichMongoDbContext<TContext>()
  • Azure AI推理 現在支持嵌入,不僅僅限於聊天。 註冊AddAzureEmbeddingsClient("embeddings").AddEmbeddingGenerator() 並注入IEmbeddingGenerator<string, Embedding<float>>。 有鍵變種也可用。
  • Azure Container Registry 獲得了WithPurgeTask("0 1 * * *", ago: TimeSpan.FromDays(7), keep: 5),這根據計畫調度周期執行一項ACR清除任務。
  • Bun支持 對 JavaScript 資源通過 WithBun()。 使用AddViteApp的Yarn可靠性。
  • Microsoft Foundry 取代了 Azure AI Foundry。 Aspire.Hosting.Foundry 取代了 Aspire.Hosting.Azure.AIFoundry。 重大變更; 詳情如下。

組合:在Aspire 13.2中的文件服務

以下是我們內部運行使用我們程式庫測試分佈式場景的模式。 值得展示的是,因為大多數新的13.2功能在這種多服務設置中發揮作用,而不是在試驗性演示中。

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

// A worker service that uses IronPDF for HTML to PDF rendering
var renderer = builder.AddProject<Projects.PdfRenderer>("renderer")
    .WithReference(cache)
    .WaitFor(cache)
    .WithMcpServer("/mcp");

// An OCR worker that uses IronOCR for image and PDF text extraction
var ocr = builder.AddProject<Projects.OcrWorker>("ocr-worker")
    .WithReference(cache);

// API gateway that fans out to both
builder.AddProject<Projects.Api>("api")
    .WithReference(renderer)
    .WithReference(ocr)
    .WaitFor(renderer)
    .WaitFor(ocr);

builder.Build().Run();
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

// A worker service that uses IronPDF for HTML to PDF rendering
var renderer = builder.AddProject<Projects.PdfRenderer>("renderer")
    .WithReference(cache)
    .WaitFor(cache)
    .WithMcpServer("/mcp");

// An OCR worker that uses IronOCR for image and PDF text extraction
var ocr = builder.AddProject<Projects.OcrWorker>("ocr-worker")
    .WithReference(cache);

// API gateway that fans out to both
builder.AddProject<Projects.Api>("api")
    .WithReference(renderer)
    .WithReference(ocr)
    .WaitFor(renderer)
    .WaitFor(ocr);

builder.Build().Run();
Imports DistributedApplication

Dim builder = DistributedApplication.CreateBuilder(args)

Dim cache = builder.AddRedis("cache")

' A worker service that uses IronPDF for HTML to PDF rendering
Dim renderer = builder.AddProject(Of Projects.PdfRenderer)("renderer") _
    .WithReference(cache) _
    .WaitFor(cache) _
    .WithMcpServer("/mcp")

' An OCR worker that uses IronOCR for image and PDF text extraction
Dim ocr = builder.AddProject(Of Projects.OcrWorker)("ocr-worker") _
    .WithReference(cache)

' API gateway that fans out to both
builder.AddProject(Of Projects.Api)("api") _
    .WithReference(renderer) _
    .WithReference(ocr) _
    .WaitFor(renderer) _
    .WaitFor(ocr)

builder.Build().Run()
$vbLabelText   $csharpLabel

13.2 專門提供了以下內容:

  • aspire start --isolated 允許您並排運行此圖的兩個副本,而不會發生端口衝突。 在比較分支或對渲染器執行並行集成測試時非常有用
  • 當您更改 Razor 模板時,aspire resource renderer rebuild 只重載 PDF 渲染器,而不是彈跳整個圖表
  • aspire wait renderer --status healthy --timeout 120 允許您的 CI 在 Chrome 渲染初始化之前阻止,然後再運行 PDF 生成測試
  • 遙測HTTP API 和 aspire export 為每次渲染調用提供OTLP格式的跨度,這就是您在生產流量中實際注意到緩慢的CSS規則的方法
  • WithMcpServer 允許您將渲染器作為MCP工具公開給編碼代理的工作流,這對於您正在構建任何程序生成文檔的東西非常有用

如果您想構建像上面渲染器一樣的服務,IronPDF的HTML to PDF教程將引導您了解C#側面。對於OCR工作者,IronOCR入門指南涵蓋了基礎知識。

會真正困擾您的重大變更

粗略說明您最有可能遇到的問題順序:

服務發現環境變量命名

# Before (13.0/13.1)
services__myservice__myendpoint__0 = https://localhost:5001

# After (13.2)
services__myservice__https__0 = https://localhost:5001
# Before (13.0/13.1)
services__myservice__myendpoint__0 = https://localhost:5001

# After (13.2)
services__myservice__https__0 = https://localhost:5001
SHELL

使用端點方案而不是端點名稱。 如果您有任何匹配這些環境變量名稱的代碼或配置,請更新它。 這是最有可能的靜默中斷:沒有拋出錯誤,變量只是有不同的鍵。

BeforeResourceStartedEvent

以前更廣泛地觸發; 現在只有在實際啟動資源時才觸發,而不是在每次狀態變更時。 如果您的處理程序依賴於以前的行為,它將悄無聲息地停止運行。

由 AIFoundry 到 Foundry

包和API名稱更改。 更新包引用和調用:

<PackageReference Include="Aspire.Hosting.Foundry" Version="13.2.0" />
<PackageReference Include="Aspire.Hosting.Foundry" Version="13.2.0" />
XML
// Before
var ai = builder.AddAzureAIFoundry("ai");

// After
var foundry = builder.AddFoundry("ai");
var project = foundry.AddProject("agents");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
// Before
var ai = builder.AddAzureAIFoundry("ai");

// After
var foundry = builder.AddFoundry("ai");
var project = foundry.AddProject("agents");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
' Before
Dim ai = builder.AddAzureAIFoundry("ai")

' After
Dim foundry = builder.AddFoundry("ai")
Dim project = foundry.AddProject("agents")
Dim chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini)
$vbLabelText   $csharpLabel

RunAsFoundryLocal仍適用於本地模型開發,但Foundry專案不支持當父資源配置為Foundry Local時。

默認Azure憑證

Aspire Azure客戶端集成不再使用無參的DefaultAzureCredential構造函數。 如果您依賴於其他而非ManagedIdentityCredential的憑證在Azure服務中工作,行為會發生變化。 在升級生產前閱讀Default Azure credential文檔。

資源命令重命名

resource-start / resource-停止 / resource-restart 現在是 aspire resource <name> start|停止|重啟。 更新所有腳本。--project`(仍然可以接受)。

連接屬性後綴

添加了一個連接屬性後綴。 如果您直接訪問連接屬性(而不是通過WithReference),請檢查您的代碼是否仍能解析它們。

WithSecretBuildArg 到 WithBuildSecret

已在上方提及。 直接重命名。

IAzureContainerRegistry 廢棄

使用在計算環境上的ContainerRegistry屬性。

儀表板遙測API現在是自選的(獨立)

已在上方涵蓋,但值得重複說:獨立儀表板部署現在需顯式啟用API。

您應該升級嗎?

對於一個在本地運行多服務應用程式的.NET工作室,是的,假設您已經清點了上述重大變更。 單是CLI的改進就已值得。 獨立模式和隔離模式尤其解決了實際的工作流問題。

對於Foundry用戶:如果您想從此版本中獲得任何新功能,重命名是一個強制遷移,因此請相應計劃。

對於對TypeScript感興趣的人來說:13.2 是第一次發布使TS apphost足夠成熟來評估。 仍然是預覽,但值得一個周五下午。

如果您已經在13.x上,升級本身就是一行程式。

aspire update --self
aspire update
aspire update --self
aspire update
SHELL

如果您是在12.x或更早版本,請首先查看升級指南。13.0的步驟無法跳過。

補丁說明:13.2.1

自原始版本以來,13.2.1已發布了可靠性修復。 有一個小的TypeScript SDK重命名值得注意,僅在您已在TS apphost預覽中時才重要:

舊版新版
runAsExistingFromParameters(name, resourceGroup)runAsExisting(name, { resourceGroup })
publishAsExistingFromParameters(name, resourceGroup)publishAsExisting(name, { resourceGroup })
withConnectionPropertyValue(name, value)withConnectionProperty(name, value)
withParameterBuildArg(name, parameter)withBuildArg(name, parameter)

withConnectionPropertyValue 作為生成的SDK中的兼容別名保留,因此不會造成運行時中斷。

建置包含文件工作負載的分佈式.NET應用程序嗎?

如果您的服務進行PDF生成、OCR、Excel處理、條形碼或我們涵蓋的任何其他格式,我們的程式庫設計正是為了Aspire編排的這種多服務、容器友好的設定。 所有支持.NET 10、9、8、7、6、、Framework 和 Core,並可在Linux容器、Azure、AWS和內部運行。

幾個可以開始的地方:

  • IronPDF 用於HTML 到PDF、PDF 編輯、簽名和表單。 教程中心 是通向一個有效渲染服務的最快途徑
  • IronOCR 適用於超過125種語言的圖像和PDF文本提取
  • IronXL 用於Excel讀取/寫入而無需Office互操作
  • IronWord 用於DOCX生成和編輯
  • IronBarcodeIronQR 用於條形碼和QR生成與掃描
  • 如果您需要不止一個上述程式庫,Iron Suite

您可以申請一個30天試用鑰匙,並在不到一小時內在Aspire apphost中運行一個有效的PDF或OCR服務。 如果您遇到任何奇怪的事情,我們的支援團隊是實際的工程師,而不是票務三部曲。

就是這樣。 在下次發佈中見。