Description
When a project resource has both:
.WithReference(someLogicalService) — e.g. an Orleans service added via AddOrleans(...)
.WaitForCompletion(migrationsResource), where migrationsResource comes from AddEFMigrations(...).RunDatabaseUpdateOnStart() (Aspire.Hosting.EntityFrameworkCore, currently preview)
...the environment variables that WithReference should inject onto the project (in our case, the Orleans__* block: Orleans__ClusterId, Orleans__Clustering__ProviderType, Orleans__Endpoints__*, Orleans__GrainStorage__*, etc.) are silently absent from the resulting process's environment. No error, no warning — the project just starts without them, which in our case meant Orleans could never resolve IMembershipTable and the silo crashed on startup:
System.InvalidOperationException: Unable to resolve service for type 'Orleans.IMembershipTable'
while attempting to activate 'Orleans.Runtime.MembershipService.MembershipTableManager'.
Environment variables set via plain .WithEnvironment("Key", "value") on the same resource are not affected — only the computed/reference-derived ones.
Repro
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("pg").AddDatabase("appdb");
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator();
var grainStorage = storage.AddBlobs("grainstate");
var orleans = builder.AddOrleans("default")
.WithGrainStorage("Default", grainStorage)
.WithDevelopmentClustering()
.WithMemoryReminders();
var api = builder.AddProject<Projects.Api>("api")
.WithReference(orleans)
.WithReference(db);
// Adding this — a migrations resource the project waits on — is what
// makes api's Orleans__* environment variables disappear.
var migrations = api.AddEFMigrations("api-migrations")
.WithReference(db)
.WaitFor(db)
.RunDatabaseUpdateOnStart();
api.WaitForCompletion(migrations);
builder.Build().Run();
Inspecting api's Environment tab in the Aspire dashboard shows none of the Orleans__* keys present, only whatever was set via literal .WithEnvironment() calls elsewhere. Removing api.WaitForCompletion(migrations) (while keeping everything else, including the AddEFMigrations resource itself) restores the Orleans__* variables.
Confirmed via git bisect
We bisected our own repo's history and found the exact commit that introduced this: the only change in that commit affecting the api project was adding the AddEFMigrations(...).WaitFor(db).RunDatabaseUpdateOnStart() resource and the api.WaitForCompletion(migrations) call shown above. No other change to api, the Orleans wiring, or storage wiring was made in that commit.
Versions
Aspire.Hosting.Orleans: 13.4.6
Aspire.Hosting.EntityFrameworkCore: 13.4.6-preview.1.26319.6 — still a preview package, see note below
Microsoft.Orleans.Server / Clustering.AzureStorage / Reminders.AzureStorage / Persistence.AzureStorage: 10.2.1
- .NET 10, Aspire AppHost SDK 13.4.6
- Reproduced both via
aspire start (CLI) and via Visual Studio's own AppHost debug launch — same result either way, so this isn't launcher-specific.
Notes
We haven't tested whether this is specific to AddEFMigrations/WaitForCompletion as a general pattern, or specific to Aspire.Hosting.EntityFrameworkCore itself (still a preview package). We'd guess it's more likely the latter, since AddEFMigrations builds its own derived resource and env var wiring around the target project (api in our repro), and it seems more plausible that this preview integration interferes with api's own environment computation than that WaitForCompletion alone (a much more widely used, non-preview API) has this effect. Worth checking whether the same WithReference + WaitForCompletion pattern reproduces with a plain custom resource in place of AddEFMigrations, to rule that in or out — we haven't had a chance to isolate it that far yet.
Description
When a project resource has both:
.WithReference(someLogicalService)— e.g. an Orleans service added viaAddOrleans(...).WaitForCompletion(migrationsResource), wheremigrationsResourcecomes fromAddEFMigrations(...).RunDatabaseUpdateOnStart()(Aspire.Hosting.EntityFrameworkCore, currently preview)...the environment variables that
WithReferenceshould inject onto the project (in our case, theOrleans__*block:Orleans__ClusterId,Orleans__Clustering__ProviderType,Orleans__Endpoints__*,Orleans__GrainStorage__*, etc.) are silently absent from the resulting process's environment. No error, no warning — the project just starts without them, which in our case meant Orleans could never resolveIMembershipTableand the silo crashed on startup:Environment variables set via plain
.WithEnvironment("Key", "value")on the same resource are not affected — only the computed/reference-derived ones.Repro
Inspecting
api's Environment tab in the Aspire dashboard shows none of theOrleans__*keys present, only whatever was set via literal.WithEnvironment()calls elsewhere. Removingapi.WaitForCompletion(migrations)(while keeping everything else, including theAddEFMigrationsresource itself) restores theOrleans__*variables.Confirmed via git bisect
We bisected our own repo's history and found the exact commit that introduced this: the only change in that commit affecting the
apiproject was adding theAddEFMigrations(...).WaitFor(db).RunDatabaseUpdateOnStart()resource and theapi.WaitForCompletion(migrations)call shown above. No other change toapi, the Orleans wiring, or storage wiring was made in that commit.Versions
Aspire.Hosting.Orleans: 13.4.6Aspire.Hosting.EntityFrameworkCore: 13.4.6-preview.1.26319.6 — still a preview package, see note belowMicrosoft.Orleans.Server/Clustering.AzureStorage/Reminders.AzureStorage/Persistence.AzureStorage: 10.2.1aspire start(CLI) and via Visual Studio's own AppHost debug launch — same result either way, so this isn't launcher-specific.Notes
We haven't tested whether this is specific to
AddEFMigrations/WaitForCompletionas a general pattern, or specific toAspire.Hosting.EntityFrameworkCoreitself (still a preview package). We'd guess it's more likely the latter, sinceAddEFMigrationsbuilds its own derived resource and env var wiring around the target project (apiin our repro), and it seems more plausible that this preview integration interferes withapi's own environment computation than thatWaitForCompletionalone (a much more widely used, non-preview API) has this effect. Worth checking whether the sameWithReference+WaitForCompletionpattern reproduces with a plain custom resource in place ofAddEFMigrations, to rule that in or out — we haven't had a chance to isolate it that far yet.