Resource API Patterns
Aspire’s resource model allows you to define and configure resources in a structured way, enabling seamless integration and management of your application’s components. This guide provides details the common patterns for adding and configuring resources in Aspire.
API Patterns
Section titled “API Patterns”Aspire separates resource data models from behavior using fluent extension methods.
- Resource classes define only constructors and properties.
- Extension methods implement resource creation, configuration, and runtime wiring.
This guide describes each pattern and shows a verbatim Redis example at the end. It also covers how to publish manifests via custom resources.
Adding Resources with AddX(...)
Section titled “Adding Resources with AddX(...)”An AddX(...)
method executes:
- Validate inputs (
builder
,name
, required arguments). - Instantiate the data-only resource (
new TResource(...)
). - Register it with
builder.AddResource(resource)
. - Optional wiring of endpoints, health checks, container settings, environment variables, command-line arguments, and event subscriptions.
Signature Pattern
Section titled “Signature Pattern”public static IResourceBuilder<TResource> AddX( this IDistributedApplicationBuilder builder, [ResourceName] string name, /* optional parameters */){ // 1. Validate inputs // 2. Instantiate resource // 3. builder.AddResource(resource) // 4. Optional wiring: // .WithEndpoint(...) // .WithHealthCheck(...) // .WithImage(...) // .WithEnvironment(...) // .WithArgs(...) // Eventing.Subscribe<...>(...)}
Optional Wiring Examples
Section titled “Optional Wiring Examples”Endpoints:
.WithEndpoint(port: hostPort, targetPort: containerPort, name: endpointName)
Health checks:
.WithHealthCheck(healthCheckKey)
Container images / registries:
.WithImage(imageName, imageTag).WithImageRegistry(registryUrl)
Entrypoint and args:
.WithEntrypoint("/bin/sh").WithArgs(context => { /* build args */ return Task.CompletedTask; })
Environment variables:
.WithEnvironment(context => new("ENV_VAR", valueProvider))
Event subscriptions:
builder.Eventing.Subscribe<EventType>(resource, handler);
Summary Table
Section titled “Summary Table”Step | Call/Method | Purpose |
---|---|---|
Validate | ArgumentNullException.ThrowIfNull(...) | Ensure non-null builder, name, and args |
Instantiate | new TResource(name, …) | Create data-only instance |
Register | builder.AddResource(resource) | Add resource to the application model |
Optional wiring | .WithEndpoint(…) , .WithHealthCheck(…) , .WithImage(…) , .WithEnvironment(…) , .WithArgs(…) , Eventing.Subscribe(…) | Configure container details, wiring, and runtime hooks |
Configuring Resources with WithX(...)
Section titled “Configuring Resources with WithX(...)”WithX(...)
methods attach annotations to resource builders.
Signature Pattern
Section titled “Signature Pattern”public static IResourceBuilder<TResource> WithX( this IResourceBuilder<TResource> builder, FooOptions options) => builder.WithAnnotation(new FooAnnotation(options));
- Target:
IResourceBuilder<TResource>
. - Action:
WithAnnotation(...)
. - Returns:
IResourceBuilder<TResource>
.
Summary Table
Section titled “Summary Table”Method | Target | Action |
---|---|---|
WithX(...) | IResourceBuilder<TResource> | Attaches XAnnotation using the WithAnnotation API. |
Returns | IResourceBuilder<TResource> | Enables fluent chaining . |
Annotations
Section titled “Annotations”Annotations are public metadata types implementing IResourceAnnotation
. They can be added or removed dynamically at runtime via hooks or events. Consumers can query annotations using TryGetLastAnnotation<T>()
when necessary.
Definition and Attachment
Section titled “Definition and Attachment”public sealed record PersistenceAnnotation( TimeSpan? Interval, int KeysChangedThreshold) : IResourceAnnotation;
builder.WithAnnotation(new PersistenceAnnotation( TimeSpan.FromSeconds(60), 100));
Summary Table
Section titled “Summary Table”Concept | Pattern | Notes |
---|---|---|
Annotation Type | public record XAnnotation(...) : IResourceAnnotation | Public to support dynamic runtime use. |
Attach | builder.WithAnnotation(new XAnnotation(...)) | Adds metadata to resource builder. |
Query | resource.TryGetLastAnnotation<XAnnotation>(out var a) | Consumers inspect annotations as needed. |
Custom Value Objects
Section titled “Custom Value Objects”Custom value objects defer evaluation and allow the framework to discover dependencies between resources.
Core Interfaces
Section titled “Core Interfaces”Interface | Member | Mode | Purpose |
---|---|---|---|
IValueProvider | ValueTask<string?> GetValueAsync(CancellationToken) | Run | Resolve live values at runtime |
IManifestExpressionProvider | string ValueExpression { get; } | Publish | Emit structured expressions in manifests |
IValueWithReferences (opt.) | IEnumerable<object> References { get; } | Both (if needed) | Declare dependencies on other resources |
- Implement
IValueProvider
andIManifestExpressionProvider
on all structured value types. - Implement
IValueWithReferences
only when your type holds resource references.
Attaching to Resources
Section titled “Attaching to Resources”builder.WithEnvironment(context => new("REDIS_CONNECTION_STRING", redis.GetConnectionStringAsync));
public sealed partial class BicepOutputReference : IManifestExpressionProvider, IValueProvider, IValueWithReferences{ public string ValueExpression { get; } public ValueTask<string?> GetValueAsync(CancellationToken cancellationToken = default); IEnumerable<object> IValueWithReferences.References { get; }}
public static IResourceBuilder<T> WithEnvironment<T>( this IResourceBuilder<T> builder, string name, BicepOutputReference bicepOutputReference) where T : IResourceWithEnvironment{ return builder.WithAnnotation( new EnvironmentVariableAnnotation(name, bicepOutputReference));}
Summary Table
Section titled “Summary Table”Concept | Pattern | Purpose |
---|---|---|
IValueProvider | GetValueAsync(...) | Deferred runtime resolution |
IManifestExpressionProvider | ValueExpression | Structured publish-time expression |
IValueWithReferences (opt.) | References | Declare resource dependencies |
WithEnvironment(...) | new("NAME", valueProvider) | Attach structured values unflattened |