From 0b673c8149264b9e06b0e41027015135ea37e350 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 14 Feb 2025 10:35:53 -0600 Subject: [PATCH] Add WithParentRelationship overload accepting an IResourceBuilder Fix #7594 --- playground/Redis/Redis.AppHost/Program.cs | 4 +-- .../AzureEventHubsExtensions.cs | 2 +- .../AzureServiceBusExtensions.cs | 2 +- .../MongoDBBuilderExtensions.cs | 2 +- .../ResourceBuilderExtensions.cs | 30 +++++++++++++++++++ .../ApplicationOrchestratorTests.cs | 18 +++++------ .../RelationshipEvaluatorTests.cs | 4 +-- 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/playground/Redis/Redis.AppHost/Program.cs b/playground/Redis/Redis.AppHost/Program.cs index 4ccd9473676..1466fb3cb27 100644 --- a/playground/Redis/Redis.AppHost/Program.cs +++ b/playground/Redis/Redis.AppHost/Program.cs @@ -2,8 +2,8 @@ var redis = builder.AddRedis("redis"); redis.WithDataVolume() - .WithRedisCommander(c => c.WithHostPort(33803).WithParentRelationship(redis.Resource)) - .WithRedisInsight(c => c.WithHostPort(41567).WithParentRelationship(redis.Resource)); + .WithRedisCommander(c => c.WithHostPort(33803).WithParentRelationship(redis)) + .WithRedisInsight(c => c.WithHostPort(41567).WithParentRelationship(redis)); var garnet = builder.AddGarnet("garnet") .WithDataVolume(); diff --git a/src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsExtensions.cs b/src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsExtensions.cs index 481861a0aa4..19054b3d3b9 100644 --- a/src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsExtensions.cs +++ b/src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsExtensions.cs @@ -213,7 +213,7 @@ public static IResourceBuilder RunAsEmulator(this IResou // Create a separate storage emulator for the Event Hub one var storageResource = builder.ApplicationBuilder .AddAzureStorage($"{builder.Resource.Name}-storage") - .WithParentRelationship(builder.Resource); + .WithParentRelationship(builder); var lifetime = ContainerLifetime.Session; diff --git a/src/Aspire.Hosting.Azure.ServiceBus/AzureServiceBusExtensions.cs b/src/Aspire.Hosting.Azure.ServiceBus/AzureServiceBusExtensions.cs index 11ffd2262b5..dfbbeb4bad3 100644 --- a/src/Aspire.Hosting.Azure.ServiceBus/AzureServiceBusExtensions.cs +++ b/src/Aspire.Hosting.Azure.ServiceBus/AzureServiceBusExtensions.cs @@ -347,7 +347,7 @@ public static IResourceBuilder RunAsEmulator(this IReso { context.EnvironmentVariables["MSSQL_SA_PASSWORD"] = passwordParameter; }) - .WithParentRelationship(builder.Resource); + .WithParentRelationship(builder); builder.WithAnnotation(new EnvironmentCallbackAnnotation((EnvironmentCallbackContext context) => { diff --git a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs index 335c58c5e98..b411df699a7 100644 --- a/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs +++ b/src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs @@ -156,7 +156,7 @@ public static IResourceBuilder WithMongoExpress(this IResourceBuilder b .WithImageRegistry(MongoDBContainerImageTags.MongoExpressRegistry) .WithEnvironment(context => ConfigureMongoExpressContainer(context, builder.Resource)) .WithHttpEndpoint(targetPort: 8081, name: "http") - .WithParentRelationship(builder.Resource) + .WithParentRelationship(builder) .ExcludeFromManifest(); configureContainer?.Invoke(resourceBuilder); diff --git a/src/Aspire.Hosting/ResourceBuilderExtensions.cs b/src/Aspire.Hosting/ResourceBuilderExtensions.cs index 67f189a9162..caae0ea5cef 100644 --- a/src/Aspire.Hosting/ResourceBuilderExtensions.cs +++ b/src/Aspire.Hosting/ResourceBuilderExtensions.cs @@ -1138,6 +1138,36 @@ public static IResourceBuilder WithRelationship( return builder.WithAnnotation(new ResourceRelationshipAnnotation(resource, type)); } + /// + /// Adds a to the resource annotations to add a parent-child relationship. + /// + /// The type of the resource. + /// The resource builder. + /// The parent of . + /// A resource builder. + /// + /// + /// The WithParentRelationship method is used to add parent relationships to the resource. Relationships are used to link + /// resources together in UI. + /// + /// + /// + /// This example shows adding a relationship between two resources. + /// + /// var builder = DistributedApplication.CreateBuilder(args); + /// var backend = builder.AddProject<Projects.Backend>("backend"); + /// + /// var frontend = builder.AddProject<Projects.Manager>("frontend") + /// .WithParentRelationship(backend); + /// + /// + public static IResourceBuilder WithParentRelationship( + this IResourceBuilder builder, + IResourceBuilder parent) where T : IResource + { + return builder.WithParentRelationship(parent.Resource); + } + /// /// Adds a to the resource annotations to add a parent-child relationship. /// diff --git a/tests/Aspire.Hosting.Tests/Orchestrator/ApplicationOrchestratorTests.cs b/tests/Aspire.Hosting.Tests/Orchestrator/ApplicationOrchestratorTests.cs index 9569a8f5b2d..1c98cdb2d65 100644 --- a/tests/Aspire.Hosting.Tests/Orchestrator/ApplicationOrchestratorTests.cs +++ b/tests/Aspire.Hosting.Tests/Orchestrator/ApplicationOrchestratorTests.cs @@ -68,10 +68,10 @@ public async Task WithParentRelationshipSetsParentPropertyCorrectly() var builder = DistributedApplication.CreateBuilder(); var parent = builder.AddContainer("parent", "image"); - var child = builder.AddContainer("child", "image").WithParentRelationship(parent.Resource); - var child2 = builder.AddContainer("child2", "image").WithParentRelationship(parent.Resource); + var child = builder.AddContainer("child", "image").WithParentRelationship(parent); + var child2 = builder.AddContainer("child2", "image").WithParentRelationship(parent); - var nestedChild = builder.AddContainer("nested-child", "image").WithParentRelationship(child.Resource); + var nestedChild = builder.AddContainer("nested-child", "image").WithParentRelationship(child); using var app = builder.Build(); var distributedAppModel = app.Services.GetRequiredService(); @@ -137,8 +137,8 @@ public async Task LastWithParentRelationshipWins() var child = builder.AddContainer("child", "image"); - child.WithParentRelationship(firstParent.Resource); - child.WithParentRelationship(secondParent.Resource); + child.WithParentRelationship(firstParent); + child.WithParentRelationship(secondParent); using var app = builder.Build(); var distributedAppModel = app.Services.GetRequiredService(); @@ -191,7 +191,7 @@ public async Task WithParentRelationshipWorksWithProjects() var builder = DistributedApplication.CreateBuilder(); var projectA = builder.AddProject("projecta"); - var projectB = builder.AddProject("projectb").WithParentRelationship(projectA.Resource); + var projectB = builder.AddProject("projectb").WithParentRelationship(projectA); using var app = builder.Build(); var distributedAppModel = app.Services.GetRequiredService(); @@ -241,9 +241,9 @@ public void DetectsCircularDependency() var container2 = builder.AddContainer("container2", "image2"); var container3 = builder.AddContainer("container3", "image3"); - container1.WithParentRelationship(container2.Resource); - container2.WithParentRelationship(container3.Resource); - container3.WithParentRelationship(container1.Resource); + container1.WithParentRelationship(container2); + container2.WithParentRelationship(container3); + container3.WithParentRelationship(container1); using var app = builder.Build(); diff --git a/tests/Aspire.Hosting.Tests/Orchestrator/RelationshipEvaluatorTests.cs b/tests/Aspire.Hosting.Tests/Orchestrator/RelationshipEvaluatorTests.cs index 786a2e42aed..b14844ab8f2 100644 --- a/tests/Aspire.Hosting.Tests/Orchestrator/RelationshipEvaluatorTests.cs +++ b/tests/Aspire.Hosting.Tests/Orchestrator/RelationshipEvaluatorTests.cs @@ -20,10 +20,10 @@ public void HandlesNestedChildren() var greatGrandChildResource = builder.AddResource(new CustomChildResource("greatgrandchild", grandChildResource.Resource)); var childWithAnnotationsResource = builder.AddContainer("child-with-annotations", "image") - .WithParentRelationship(parentResource.Resource); + .WithParentRelationship(parentResource); var grandChildWithAnnotationsResource = builder.AddContainer("grandchild-with-annotations", "image") - .WithParentRelationship(childWithAnnotationsResource.Resource); + .WithParentRelationship(childWithAnnotationsResource); using var app = builder.Build(); var appModel = app.Services.GetRequiredService();