TimeSpan StartupTimeout { get; init; }
Source
Gets the finite positive budget for creation through successful HTTP readiness.
Configures the shared deadline and HTTP condition for one typed Aspire fixture.
Values and delegate references are snapshotted before the factory runs. The default startup budget is two minutes. The default HTTP condition requires exact status 200, with a three-second request maximum and 250-millisecond retry delay. A custom client factory must return a new client whose lifetime transfers to the fixture; the default client uses Aspire's native resource-specific testing helper. The fixture owns application lifecycle and client cleanup.
TimeSpan StartupTimeout { get; init; }
Source
Gets the finite positive budget for creation through successful HTTP readiness.
HttpReadinessOptions Http { get; init; }
Source
Gets status, request-timeout, retry-delay, and optional attempt-cap settings.
Func<Uri, HttpClient>? CreateProbeClient { get; init; }
Source
Gets an optional factory invoked once after endpoint resolution. It must return a fresh client, which the fixture disposes after probing, including when probing fails.
Creates deterministic Aspire testing builders from AppSurface profile types.
This factory activates the selected profile through AppSurface dependency injection but never starts the activation host or invokes the AppHost entry point. The selected profile must not declare CliFx option or positional-parameter bindings because this typed path intentionally has no command-line binding phase.
Task<AppSurfaceAspireProfileTestingBuilder> CreateAsync<TAppHost, TModule, TProfile>(CancellationToken cancellationToken = default)
Creates a configurable Aspire testing builder for a typed AppSurface profile.
TAppHost
Projects.*
marker for the AppHost project.TModule
TProfile
cancellationToken
A builder that the caller may customize once before calling BuildAsync
.
InvalidOperationException
OperationCanceledException
Task<AppSurfaceAspireProfileTestingBuilder> CreateConfiguredAsync<TAppHost, TModule, TProfile>(AppSurfaceAspireTestingOptions options, CancellationToken cancellationToken = default)
Creates a typed Aspire testing graph with per-call customization before profile activation and composition.
TAppHost
TModule
TProfile
options
cancellationToken
An Active testing builder with the completed graph, ready for one explicit BuildAsync call.
ArgumentNullException
OperationCanceledException
InvalidOperationException
Delegate references are snapshotted at entry. Final module configuration precedes the activation configuration hook, all module/framework service registrations precede the activation services hook, and the selected provider creates the profile before the Aspire hook. The Aspire hook and profile composition receive the same Preparing wrapper: access and mutations are permitted, but build and disposal are rejected without changing ownership. Escaping errors abort unbuilt Aspire resources before activation services. The factory never starts a host or resource. Synchronous callbacks are not preempted by cancellation. Use immutable captures and keep activation services separate from Aspire's application services; later container registrations retain their own precedence. Existing CreateAsync remains available with its original composition behavior.
Supplies synchronous, per-call customization before typed profile activation and graph composition.
All delegates default to null and are snapshotted when CreateConfiguredAsync is called. Each runs once when its phase is reached; later delegates do not run after failure or cancellation. Capture immutable scenario values. Mutable captures, thread safety and objects created inside a callback remain the caller's responsibility. Do not use async-void delegates, build a separate service provider, run the AppHost entry point or start resources here. These hooks do not replace the module's parameterless constructor or the profile's command-line binding.
Action<IConfigurationBuilder>? ConfigureActivationConfiguration { get; init; }
Source
Gets the application-configuration callback applied after module callbacks and before activation services.
Defaults to null. Add a per-call overlay here when profile or component constructors consume IConfiguration. The callback receives the activation configuration builder, not Aspire's ConfigurationManager. Later sources have normal configuration precedence. Configuration built explicitly by the callback is caller-owned.
Action<IServiceCollection>? ConfigureActivationServices { get; init; }
Source
Gets the service-collection callback applied after module and framework registrations and before provider creation.
Defaults to null. Use this hook to inject immutable scenario services or replace constructor dependencies. The selected service-provider factory is retained. Later ConfigureContainer registrations, including Autofac modules, still follow that container's precedence; this hook is not a universal final override. Singleton instances supplied by the caller retain normal container ownership policy. Aspire builder services belong to a different provider and cannot affect profile activation.
Action<IDistributedApplicationBuilder>? ConfigureAspireBuilder { get; init; }
Source
Gets the Aspire-builder callback applied after profile activation and before composition on the same guarded builder.
Defaults to null. Configuration, services, resources and resource-builder creation are available during this callback and composition. Build, BuildAsync, Dispose and DisposeAsync throw InvalidOperationException while factory preparation is in progress. Catching that rejection permits preparation to continue. An escaping exception aborts the factory and invalidates captured builder references. Use the returned builder for its single explicit build after CreateConfiguredAsync completes; no resource is started by this factory.
Owns one typed Aspire testing builder through native health and HTTP readiness.
Use StartAsync(Func{CancellationToken, Task{AppSurfaceAspireProfileTestingBuilder}}, AspireHttpReadinessTarget, AppSurfaceAspireStartupOptions?, CancellationToken)
when both native resource health and an explicit HTTP condition must pass. The builder factory runs once under one startup deadline and must return an exclusive active, unbuilt builder. The fixture owns and disposes that builder; Application
and Endpoint
are borrowed values. Do not independently build or dispose the application. Builder cleanup remains its single lifecycle owner and disposes the application before activation services. The deadline covers cooperative asynchronous operations; synchronous creation/build and awaited cleanup can outlast it.
Task<AppSurfaceAspireTestFixture> StartAsync(Func<CancellationToken, Task<AppSurfaceAspireProfileTestingBuilder>> createBuilder, AspireHttpReadinessTarget target, AppSurfaceAspireStartupOptions? options = null, CancellationToken cancellationToken = default)
Creates the typed builder once, builds and starts its application, waits for native resource health, resolves the named endpoint, and waits for the configured HTTP status condition under one startup deadline.
createBuilder
target
options
cancellationToken
A fixture that owns the builder and exposes its borrowed application and selected endpoint.
ArgumentNullException
ArgumentException
ArgumentOutOfRangeException
InvalidOperationException
ReadinessException
OperationCanceledException
A factory that allocates resources but fails to return a builder remains responsible for those resources. Once a builder is returned, the fixture takes ownership before checking cancellation or deadline again and cleans it on every unsuccessful startup path unless process-fatal cleanup interrupts it. Original factory/build/start exceptions remain primary if nonfatal cleanup also fails; process-fatal cleanup exceptions propagate unchanged. For nonfatal cleanup failures, Exception.Data
may contain only the fixed key AppSurface.Readiness.CleanupFailure
with value ReadinessFailureCategory.CleanupFailure
.
Task<AppSurfaceAspireTestFixture> StartAsync(Func<CancellationToken, Task<AppSurfaceAspireProfileTestingBuilder>> createBuilder, AspireHttpReadinessTarget target, AppSurfaceAspireStartupOptions? options, CancellationToken cancellationToken, TimeProvider timeProvider, FixtureOperations operations)
Clock and operation seam for deterministic lifecycle tests.
ValueTask DisposeAsync()
Joins builder-owned application and activation cleanup; concurrent callers observe the same result.
DistributedApplication Application { get; }
Source
Gets the application borrowed from the fixture's owned builder.
Uri Endpoint { get; }
Source
Gets the selected absolute HTTP(S) endpoint after both readiness conditions have passed.
Internal operation seam for deterministic start, health, endpoint, probe, and cleanup tests.
FixtureOperations Native { get; }
Source
Gets the production operations backed by the typed builder and Aspire 13.4.4 helpers.
Func<AppSurfaceAspireProfileTestingBuilder, CancellationToken, Task<DistributedApplication>> BuildAsync { get; init; }
Source
Builds the application through the builder's sole lifecycle owner.
Func<DistributedApplication, CancellationToken, Task> StartAsync { get; init; }
Source
Starts the application with the shared cooperative deadline token.
Func<DistributedApplication, string, CancellationToken, Task> WaitForResourceHealthyAsync { get; init; }
Source
Waits for the named Aspire resource's native healthy notification.
Func<DistributedApplication, string, string, Uri> GetEndpoint { get; init; }
Source
Resolves the exact native resource and endpoint name to its allocated URI.
Func<DistributedApplication, string, string, HttpClient> CreateDefaultProbeClient { get; init; }
Source
Creates the native resource-specific Aspire testing client when the caller supplied no factory.
Func<HttpClient, Uri, string, HttpReadinessSettings, ReadinessDeadline, Task> WaitForHttpAsync { get; init; }
Source
Runs the shared neutral HTTP probe using the original deadline and validated settings.
Func<AppSurfaceAspireProfileTestingBuilder, ValueTask> CleanupAsync { get; init; }
Source
Disposes the transferred builder once; the builder remains the sole application cleanup owner.
Identifies one Aspire resource endpoint and its HTTP readiness path.
ResourceName
EndpointName
ProbePath
This target checks native Aspire resource health followed by one declared status-only HTTP condition. The path is validated before the builder factory is invoked. The probe does not read a response body or constrain redirects selected by the supplied client.
Captures the root service provider created while Aspire resolves its host so a failed build can release it.
Aspire 13.4.4 registers IHost
as a singleton factory. The factory receives the root provider before host construction can fail, while DistributedApplicationBuilder.Build()
does not otherwise expose that partial provider. This lease decorates the verified unkeyed registration shape when it is present and ignores unrelated keyed IHost
registrations. If a consumer-selected Aspire version changes that shape, installation warns and yields to Aspire without the additional failed-build cleanup. A successful build transfers provider ownership to the returned distributed application by calling Release
. Non-process-fatal failures dispose the lease immediately; process-fatal failures retain it for best-effort cleanup when the testing builder is later disposed.
AspireBuildServiceProviderLease? TryInstall(IServiceCollection services, Action<string>? warningSink = null)
Attempts to decorate Aspire's verified host factory and returns the lease that will capture its root provider.
services
warningSink
A lease that owns a captured provider until released after a successful build, or null
when the consumer-selected Aspire version does not expose the verified registration shape.
void Release()
Transfers ownership of any captured provider to the successfully built distributed application.
ValueTask DisposeAsync()
Releases a provider captured before host construction failed.
A value task that completes after asynchronous or synchronous provider cleanup.
Emits best-effort compatibility and cleanup warnings without changing primary build behavior.
void TryWrite(Action<string>? warningSink, string message)
Writes a warning through the supplied sink and suppresses non-process-fatal diagnostic failures.
warningSink
message
void TryWrite(Action<string>? warningSink, Func<string> messageFactory)
Creates and writes a warning inside the diagnostic boundary, suppressing non-process-fatal formatting and sink failures.
warningSink
messageFactory
void TraceWarning(string message)
Adapts a composed AppSurface profile to Aspire's configurable testing-builder contract.
The configured factory and profile composition first receive this builder in Preparing state. Graph access and mutations are available then, while build and disposal are rejected until the factory returns. Customize the returned builder before its single BuildAsync(CancellationToken)
call. After a successful build, direct builder access and a second build are rejected. Configured resource builders retain the native Aspire context for deferred SDK callbacks after the application is built; post-build graph mutation is unsupported. Dispose the returned DistributedApplication
before disposing this builder so stop and disposal failures remain at the application call site. As a fallback, builder disposal disposes the application before profile activation services. After a process-fatal build failure, builder disposal also makes a best effort to release any captured partial Aspire provider. Both disposal methods are idempotent; concurrent callers join cleanup, while reentrant disposal from that same cleanup flow returns without waiting on itself. Disposal during a build is rejected.
Task<DistributedApplication> BuildAsync(CancellationToken cancellationToken = default)
Builds the composed distributed application exactly once.
cancellationToken
The built application. The caller controls starting, stopping, and primary disposal.
InvalidOperationException
ObjectDisposedException
OperationCanceledException
Immediately before delegating to Aspire, this method attempts to install an internal ownership lease around Aspire's root-provider host factory. A successful build transfers provider ownership to the returned application. A non-process-fatal host-construction failure disposes the captured partial provider before profile activation services, without replacing the original failure with non-fatal cleanup errors. A process-fatal failure retains the captured provider for best-effort cleanup when this builder is later disposed. A consumer-selected Aspire version with an unfamiliar host registration continues without this additional cleanup and emits a trace warning.
void Dispose()
Releases the profile activation host synchronously.
InvalidOperationException
After a successful build, this method disposes the application before profile activation services. After a process-fatal build failure, it instead attempts to dispose the captured partial provider before activation.
ValueTask DisposeAsync()
Releases the profile activation host asynchronously.
A value task that completes after activation services are disposed.
InvalidOperationException
After a successful build, this method disposes the application before profile activation services. After a process-fatal build failure, it instead attempts to dispose the captured partial provider before activation.
void CompletePreparation()
Transfers a fully composed configured factory result from Preparing to Active.
Only the factory may call this; callback-rejected lifecycle operations leave Preparing unchanged.
void EnsureActiveUnbuilt()
Verifies that ownership was transferred while the builder is active and before its single build.
InvalidOperationException
ObjectDisposedException
Task AbortPreparationAsync()
Aborts factory preparation through the internal ownership path and invalidates captured references.
A task joining cleanup of unbuilt Aspire resources before activation services.
The factory preserves its primary error if cleanup fails; public disposal cannot enter this path.