Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/Aspire.Hosting/Orchestrator/ParameterProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,14 @@ public async Task InitializeParametersAsync(DistributedApplicationModel model, b

private async Task CollectDependentParameterResourcesAsync(DistributedApplicationModel model, Dictionary<string, ParameterResource> referencedParameters, HashSet<object?> currentDependencySet, CancellationToken cancellationToken)
{
var publishExecutionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Publish);

foreach (var resource in model.Resources)
{
await ProcessResourceDependenciesAsync(resource, publishExecutionContext, referencedParameters, currentDependencySet, cancellationToken).ConfigureAwait(false);
if (resource.IsExcludedFromPublish())
{
continue;
}

await ProcessResourceDependenciesAsync(resource, executionContext, referencedParameters, currentDependencySet, cancellationToken).ConfigureAwait(false);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,81 @@ public async Task InitializeParametersAsync_WithDistributedApplicationModel_Hand
}
}

[Fact]
public async Task InitializeParametersAsync_UsesExecutionContextOptions_DoesNotThrow()
{
// Arrange
using var builder = TestDistributedApplicationBuilder.Create();
var param = builder.AddParameter("testParam", () => "testValue");

var serviceProviderAccessed = false;
builder.AddContainer("testContainer", "nginx")
.WithEnvironment(context =>
{
// This should not throw InvalidOperationException
// when using the proper execution context constructor
var sp = context.ExecutionContext.ServiceProvider;
serviceProviderAccessed = sp is not null;
context.EnvironmentVariables["TEST_ENV"] = param;
});

using var app = builder.Build();
var model = app.Services.GetRequiredService<DistributedApplicationModel>();

// Get the ParameterProcessor from the built app's service provider
// This ensures it has the proper execution context with ServiceProvider
var parameterProcessor = app.Services.GetRequiredService<ParameterProcessor>();

// Act - Should not throw InvalidOperationException about IServiceProvider not being available
await parameterProcessor.InitializeParametersAsync(model);

// Assert
Assert.True(serviceProviderAccessed);
var parameterResource = model.Resources.OfType<ParameterResource>().Single();
Assert.NotNull(parameterResource.WaitForValueTcs);
Assert.True(parameterResource.WaitForValueTcs.Task.IsCompletedSuccessfully);
}

[Fact]
public async Task InitializeParametersAsync_SkipsResourcesExcludedFromPublish()
{
// Arrange
using var builder = TestDistributedApplicationBuilder.Create();
var param = builder.AddParameter("excludedParam", () => "excludedValue");

var excludedContainer = builder.AddContainer("excludedContainer", "nginx")
.WithEnvironment(context =>
{
context.EnvironmentVariables["EXCLUDED_ENV"] = param;
});

// Mark the container as excluded from publish
excludedContainer.WithAnnotation(ApplicationModel.ManifestPublishingCallbackAnnotation.Ignore);

using var app = builder.Build();
var model = app.Services.GetRequiredService<DistributedApplicationModel>();

var parameterProcessor = CreateParameterProcessor();

// Act - The excluded container should be skipped during parameter collection
await parameterProcessor.InitializeParametersAsync(model);

// Assert
// The environment callback should have been invoked during parameter collection
// because we now create a publish execution context to collect dependent parameters
// However, since we filter out excluded resources, the parameter should not be initialized
// unless it's explicitly in the model
var parameters = model.Resources.OfType<ParameterResource>().ToList();
Assert.Single(parameters);

var parameterResource = parameters[0];
Assert.Equal("excludedParam", parameterResource.Name);

// The parameter should be initialized since it's explicitly in the model
Assert.NotNull(parameterResource.WaitForValueTcs);
Assert.True(parameterResource.WaitForValueTcs.Task.IsCompletedSuccessfully);
}

private static ParameterProcessor CreateParameterProcessor(
ResourceNotificationService? notificationService = null,
ResourceLoggerService? loggerService = null,
Expand Down
Loading