diff --git a/src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs b/src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs index 4836d473b9a..fec5e55d6c7 100644 --- a/src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs +++ b/src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs @@ -1416,7 +1416,6 @@ private static void CollectDependenciesFromValue(object? value, HashSet("server", launchProfileName: null) + .WithHttpEndpoint() + .WithExternalHttpEndpoints() + .WithReference(cache) + .WaitFor(cache); + + builder.AddProject("webfrontend", launchProfileName: null) + .WithReference(server) + .WaitFor(server); + + var app = builder.Build(); + var model = app.Services.GetRequiredService(); + + await ExecuteBeforeStartHooksAsync(app, default); + + // The server should have a role assignment to the cache since it directly references it + Assert.Single(model.Resources.OfType(), r => r.Name == "server-roles-cache"); + + // The webfrontend should NOT have a role assignment to the cache since it only references the server + Assert.DoesNotContain(model.Resources, r => r.Name == "webfrontend-roles-cache"); + } + private static async Task RoleAssignmentTest( string azureResourceName, Action configureBuilder, diff --git a/tests/Aspire.Hosting.Tests/ResourceDependencyTests.cs b/tests/Aspire.Hosting.Tests/ResourceDependencyTests.cs index 65ae7925b24..0688a07e352 100644 --- a/tests/Aspire.Hosting.Tests/ResourceDependencyTests.cs +++ b/tests/Aspire.Hosting.Tests/ResourceDependencyTests.cs @@ -545,6 +545,31 @@ public async Task DirectOnlyIncludesReferencedResourcesFromConnectionString() Assert.Contains(postgres.Resource, dependencies); } + [Fact] + public async Task DirectOnlyDoesNotIncludeWaitForDependenciesFromReferencedResources() + { + using var builder = TestDistributedApplicationBuilder.Create(); + + // Chain: A -> (ref) B -> (waitfor) C + // A has WithReference(B) and WaitFor(B) + // B has WaitFor(C) but A does NOT reference C directly + var c = builder.AddRedis("c"); + var b = builder.AddContainer("b", "alpine") + .WithHttpEndpoint(5000, 5000, "http") + .WaitFor(c); + var a = builder.AddContainer("a", "alpine") + .WithReference(b.GetEndpoint("http")) + .WaitFor(b); + + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var dependencies = await a.Resource.GetResourceDependenciesAsync(executionContext, ResourceDependencyDiscoveryMode.DirectOnly); + + // A depends on B (via WithReference and WaitFor) + Assert.Contains(b.Resource, dependencies); + // A should NOT depend on C because C is only a WaitFor dependency of B, not of A + Assert.DoesNotContain(c.Resource, dependencies); + } + [Fact] public async Task DefaultOverloadUsesTransitiveClosure() {