Build 2025:Iron Software 客户的 AI 和 .NET 展望
分享一些关于来自Iron Software工程团队的Aspire 13.2版本的笔记。 我们发布.NET库(IronPDF、IronOCR、IronXL、IronWord、IronBarcode和其他),几乎每个客户电话最终都会涉及分布式应用程序编排。 这就是为什么我们关注Aspire发布。 13.2是第一个让CLI感觉可以实际替代仪表板进行大多数日常工作的版本,并且有一些会在升级时让你吃瘪的重大变化。
这不是发布说明的复述。 官方新增功能页面有详细列表。这是工作代码库中真正有用的东西,以及需要注意的陷阱。
简而言之
- CLI现在真正支持脚本化:分离模式,
aspire stop,隔离模式,JSON输出 - 如果您想为编排层移除
.csproj,TypeScript AppHost目前正处于预览状态 - 配置文件已合并至
aspire.config.json(旧文件会自动迁移) - Foundry替代Azure AI Foundry。 这项变更会导致您的构建失败
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 stop
aspire stop --all# Run in the background
aspire run --detach
# Or the new shortcut
aspire start
# See what's running
aspire ps
# Stop it
aspire stop
aspire stop --all结合--format json(其将输出标准输出流而状态消息将输出到标准错误流,这在您将其管道传输到某处时很重要),您可以围绕此实现真正的自动化。 aspire ps --resources --format json是编辑器集成和脚本的坚实构件。
隔离模式是未被赞美的英雄
--isolated是我们一直等待的。 它以随机化端口和隔离用户秘密运行一个apphost,防止端口冲突和配置冲突:
aspire run --isolated
aspire start --isolatedaspire run --isolated
aspire start --isolated如果您曾尝试同时运行同一个apphost的两个结帐,而不论是主分支对功能分支、并行集成测试,或代理驱动的工作流,您一定感受过这种痛苦。 随机端口加上分离的秘密意味着您终于可以随意启动N个副本而无需担心。
仅就git工作树而言,这就值得升级。 对于带有本地依赖的真实服务的集成测试套件(用于PDF生成的Chrome渲染、用于OCR的Tesseract、通常的重量级选手),这就是从不稳定到可靠的区别。
aspire doctor和aspire describe
aspire doctor运行通过您的环境:开发证书状态、容器运行时版本、.NET SDK、WSL2配置、代理配置。 这是每个框架都应该拥有的功能,而大多数框架并没有费心去做。 输出是可操作的。 当出现问题时,它会告诉您该怎么做。
aspire describe --follow让您可以从终端查看资源状态的流式更新。 与仪表板显示的数据相同,但可以管道传输。 将其放入tmux窗格中,您将在80列中获得仪表板的大部分价值。
资源命令变得更整洁
旧的resource-start / resource-stop / resource-restart命令不再使用,改为使用更清晰的子命令形式:
aspire resource api restart
aspire resource api rebuildaspire resource api restart
aspire resource api rebuildrebuild是新的。 它停止、构建并重新启动单个.NET项目资源,而无需拆除整个apphost会话。 如果您曾在12个资源图中更改了一个服务并抱怨重新启动一切,这就是解决方案。 我们自己也有这样的感受:当您对PDF渲染模板进行迭代或调整OCR预处理时,只为重新加载一个项目而重启整图非常耗时。
在不离开CLI的情况下处理秘密和证书
两个新的专用命令组:
aspire certs clean
aspire certs trust
aspire secret set ApiKey super-secret-value
aspire secret list --format jsonaspire certs clean
aspire certs trust
aspire secret set ApiKey super-secret-value
aspire secret list --format jsonaspire secret是更大的胜利。 它映射到应用程序模型中支持AddParameter(..., secret: true)的同一个用户机密存储,但您不需要安装.NET CLI来管理它们。 在一个多语言apphost中,并非每个开发人员都有.NET SDK,这一点很重要。
aspire等待CI
aspire wait api --status healthy --timeout 120aspire wait api --status healthy --timeout 120阻止资源状态。 结合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而不是C#编写您的apphost:
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语言都遵循相同的模型。 查看多语言架构文档以了解主机桥是如何工作的。
仪表板:遥测导入/导出是新的玩具
仪表板获得了真正的导入/导出工作流程。 从设置 → 管理中,选择资源和遥测类型,将它们导出为zip中的JSON文件。稍后重新导入到仪表板中,或将其交给其他人(或LLM)进行分析。
aspire export CLI命令生成相同的捆绑包:
aspire export --output .\artifacts\aspire-export.zip
aspire export <resource>aspire export --output .\artifacts\aspire-export.zip
aspire export <resource>对于错误报告非常有用。 不再是"这是一些截图和一个日志文件",您可以附上实际的遥测状态快照。
其他仪表板方面的注意事项:
- 您现在可以直接从仪表板界面设置资源参数,并有一个选项可以将其持久保存到用户秘密中
- 环境变量可以作为
.env文件从资源详细信息视图导出 - 资源图布局使用自适应力导向定位。 复杂的图形明显更整洁
- Telemetry HTTP API在
/api/telemetry返回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")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
})相同的Redis端点将根据上下文从宿主进程解析为cache:6379。 PublicInternet,如果您更愿意选择网络而不是呼叫者。
发布说明明确指出这些API在13.1中存在,但没有正确行为。 因此,如果您在13.1中编写了任何针对它们的内容,请重新测试。在资源层次结构文档中查看完整详细信息。
容器构建秘密
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);构建机密现在也可以是文件(例如,在容器构建中用于私有注册表身份验证的.npmrc),涵盖了大多数实际使用情况。
集成:重要的那些
完整列表很长。 这些是我会标记的:
- Docker Compose发布现在稳定(此前是预发布)。
docker-compose.yaml。当'部署到Azure'不是答案时,这是个有用的跳板。 值得注意的是,如果您正在提供包含本机依赖项的容器,因为IronPDF、IronOCR和IronXL都支持Linux容器和Docker,因此生成的编排文件通常无需手动调整即可正常工作。 - Azure虚拟网络集成(
AddPrivateEndpoint自动创建私有DNS区域、虚拟网络链接并禁用目标上的公共访问。 这是以前维护一个单独的Bicep文件所必需的那种东西。 - Azure数据湖存储既拥有主机支持也拥有客户端支持:
AddAzureDataLakeServiceClient/AddAzureDataLakeFileSystemClient。DI注册、重试、健康检查、遥测,有Aspire的那些堆栈。 - MongoDB EF Core有一个新的客户端集成(
Aspire.MongoDB.EntityFrameworkCore)。 对于典型情况使用EnrichMongoDbContext<TContext>()。 - Azure AI推理现在支持嵌入,而不仅仅是聊天。 注册
IEmbeddingGenerator<string, Embedding<float>>。 也提供了键控变体。 - Azure容器注册表获得
WithPurgeTask("0 1 * * *", ago: TimeSpan.FromDays(7), keep: 5),其在cron调度上安排一个ACR清除任务。 - 通过
WithBun()为JavaScript资源提供对Bun的支持。 通过AddViteApp的Yarn可靠性。 - Microsoft Foundry替代Azure AI 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()您从13.2中具体获得的内容:
aspire start --isolated允许您并排运行该图形的两个副本而不会端口冲突。 在比较分支或对渲染器运行并行集成测试时非常有用aspire resource renderer rebuild在您更改Razor模板时仅重新加载PDF渲染器,而不是整个图形aspire wait renderer --status healthy --timeout 120允许您的CI阻塞,直到Chrome渲染初始化后再运行PDF生成测试- telemetery HTTP API和
aspire export为您提供每个渲染调用的OTLP格式跨度,这是在生产流量中捕捉到缓慢CSS规则的方法 WithMcpServer允许您将渲染器作为MCP工具暴露,对于编码代理工作流很有用,如果您正在建设任何以编程方式生成文档的东西
如果您想构建上述渲染器这样的服务,IronPDF的HTML到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使用端点方案替代端点名称。 如果您在代码或配置中匹配这些环境变量名称,请更新它。 这最有可能是无声的中断:没有抛出错误,变量只是拥有不同的键。
BeforeResourceStartedEvent
以前更广泛地触发; 现在仅在实际启动资源时触发,而不是在每个状态变化时触发。 如果您的处理程序依赖于以前的行为,它将静默停止运行。
从AIFoundry到Foundry
包和API重命名。 更新包引用和调用:
<PackageReference Include="Aspire.Hosting.Foundry" Version="13.2.0" /><PackageReference Include="Aspire.Hosting.Foundry" Version="13.2.0" />// 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)RunAsFoundryLocal对于本地模型开发仍然有效,但当父资源配置为Foundry Local时不支持Foundry Projects。
默认Azure凭证
Aspire Azure客户端集成不再使用无参数的DefaultAzureCredential构造函数。 如果您依赖于Azure服务中ManagedIdentityCredential之外的凭证,行为会发生变化。 在将生产升级之前,请阅读默认Azure凭证文档。
资源命令重命名
resource-start / resource-stop / resource-restart现在是aspire resource <name> start'|stop|restart。 更新所有脚本。--project(仍然接受)。
连接属性后缀
添加了一个连接属性后缀。 如果您是直接访问连接属性(而不是通过WithReference),请检查您的代码是否仍然能解析它们。
将 WithSecretBuildArg 重命名为 WithBuildSecret
如上所述。 直接重命名。
IAzureContainerRegistry 过时
请在计算环境上使用ContainerRegistry属性。
仪表板遥测 API 现在为选择性加入(独立)
已经在上面提到,但值得重复:现在需要明确启用独立仪表板部署的 API。
您应该升级吗?
对于在本地运行多服务应用程序的 .NET 商店,假设您已经清点上述中断更改,那么是的。 仅 CLI 的改进就值得。 尤其是分离模式和隔离模式修复了实际的工作流程问题。
对于 Foundry 用户:如果您想要此版本的新功能,则重命名是强制迁移,因此请做好相应的计划。
对于对 TypeScript 感兴趣的人:13.2 是第一个值得评估 TS apphost 的发布。 仍然是预览版,但值得一个周五下午。
如果您已经在 13.x 上,那么升级本身是一行代码:
aspire update --self
aspire updateaspire update --self
aspire update如果您在 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 用于不使用 Office Interop 的 Excel 读写
- IronWord 用于 DOCX 生成和编辑
- IronBarcode 和 IronQR 用于条码和 QR 生成及扫描
- Iron Suite 如果您需要上述多个
您可以获取 30 天试用密钥,并在不到一小时内在 Aspire apphost 内运行 PDF 或 OCR 服务。 如果您遇到任何问题,我们的支持团队是真正的工程师,而不是工单分诊队列。
就这样。 下次发布再见。
