Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,11 @@ Custom value objects defer evaluation and allow the framework to discover depend
|--|--|--|--|
| `IValueProvider` | `ValueTask<string?> GetValueAsync(CancellationToken)` | Run | Resolve live values at runtime |
| `IManifestExpressionProvider` | `string ValueExpression { get; }` | Publish | Emit structured expressions in manifests |
| `IExpressionValue` | Inherits `IValueProvider` and `IManifestExpressionProvider` | Run and publish | Mark a value object as usable wherever an expression-backed value is accepted |
| `IValueWithReferences` _(opt.)_ | `IEnumerable<object> References { get; }` | Both (if needed) | Declare dependencies on other resources |

- **Implement** `IValueProvider` and `IManifestExpressionProvider` on all structured value types.
- **Implement** `IExpressionValue` when a structured value type should be accepted by APIs such as `WithEnvironment(...)`.
- **Implement** `IValueWithReferences` only when your type holds resource references.

### Attaching to resources
Expand Down Expand Up @@ -198,5 +200,6 @@ public static IResourceBuilder<T> WithEnvironment<T>(
|--|--|--|
| `IValueProvider` | `GetValueAsync(...)` | Deferred runtime resolution |
| `IManifestExpressionProvider` | `ValueExpression` | Structured publish-time expression |
| `IExpressionValue` | `IValueProvider` + `IManifestExpressionProvider` | Reusable expression-backed value |
| `IValueWithReferences` _(opt.)_ | `References` | Declare resource dependencies |
| `WithEnvironment(...)` | `new("NAME", valueProvider)` | Attach structured values unflattened |
| `WithEnvironment(...)` | `new("NAME", valueProvider)` | Attach structured values unflattened |
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,13 @@ When a parameter accepts multiple types, use `[AspireUnion]` to declare the vali
public static IResourceBuilder<T> WithEnvironment<T>(
this IResourceBuilder<T> builder,
string name,
[AspireUnion(typeof(string), typeof(ReferenceExpression), typeof(EndpointReference))]
[AspireUnion(
Comment thread
sebastienros marked this conversation as resolved.
typeof(string),
typeof(ReferenceExpression),
typeof(EndpointReference),
typeof(IResourceBuilder<ParameterResource>),
typeof(IResourceBuilder<IResourceWithConnectionString>),
typeof(IExpressionValue))]
object value)
where T : IResourceWithEnvironment
{
Expand Down Expand Up @@ -596,7 +602,7 @@ The following types are ATS-compatible and can be used in exported method signat
| **Collections** | `List<T>`, `Dictionary<string, T>`, arrays — where `T` is ATS-compatible |
| **Delegates** | `Action<T>`, `Func<T>`, and other delegate types (use `RunSyncOnBackgroundThread = true` for synchronous delegates invoked inline) |
| **Services** | `ILogger`, `IServiceProvider`, `IConfiguration` (already exported by the core framework) |
| **Special** | `ParameterResource`, `ReferenceExpression`, `EndpointReference`, `CancellationToken` |
| **Special** | `ParameterResource`, `ReferenceExpression`, `EndpointReference`, `IExpressionValue`, `CancellationToken` |
| **Nullable** | Any of the above as nullable (`T?`) |

Types that are **not** ATS-compatible include: interpolated string handlers and custom complex types without `[AspireExport]` or `[AspireDto]`.
Expand Down
30 changes: 30 additions & 0 deletions src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,36 @@ You can also disable it in `launchSettings.json`:
For more details on container networking, see [Inner-loop networking overview](/fundamentals/networking-overview/).
</LearnMore>

## 🔀 Unified withEnvironment API for multi-language AppHosts

Aspire 13.3 introduces a unified `withEnvironment(name, value)` API for polyglot AppHosts (TypeScript, Java, Python, Go, Rust). Previously, environment variable injection required separate methods for each value kind (`withEnvironmentEndpoint`, `withEnvironmentParameter`, `withEnvironmentConnectionString`, and so on). Now, a single call handles all value types:

```typescript title="TypeScript — apphost.ts"
const api = await builder.addApi("api")
.withEnvironment("SERVICE_URL", cache.primaryEndpoint)
.withEnvironment("API_KEY", apiKeyParam)
.withEnvironment("DB", database);
```

The `value` argument accepts any of: a plain `string`, a `ReferenceExpression`, an `EndpointReference`, a parameter builder, a connection string resource builder, or an `IExpressionValue` — a new public interface that any type implementing both `IValueProvider` and `IManifestExpressionProvider` can implement to plug into this unified path.

### Deprecation of old withEnvironment* aliases

The previous per-kind aliases are still generated for backward compatibility but are marked `@deprecated` in the SDK. Migrate to `withEnvironment(name, value)` at your convenience:

| Deprecated | Replacement |
|---|---|
| `withEnvironmentExpression` | `withEnvironment` |
| `withEnvironmentEndpoint` | `withEnvironment` |
| `withEnvironmentParameter` | `withEnvironment` |
| `withEnvironmentConnectionString` | `withEnvironment` |
| `withEnvironmentFromOutput` | `withEnvironment` |
| `withEnvironmentFromKeyVaultSecret` | `withEnvironment` |

<LearnMore>
For integration authors, see [Multi-language integrations](/extensibility/multi-language-integration-authoring/#union-types) for union-type parameter annotations.
</LearnMore>

## 🐍 Python starter template migrated to TypeScript AppHost

The `aspire-py-starter` template (Starter App with FastAPI and React) has moved from the `dotnet new` template system to the Aspire CLI template system and now uses a **TypeScript AppHost** instead of a C# AppHost. This aligns it with the same pattern as the `aspire-ts-starter` template.
Expand Down