diff --git a/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs index 8630cb6c6c6..27f76e905a2 100644 --- a/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs +++ b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs @@ -301,7 +301,15 @@ public static FusionGatewayBuilder ModifyFusionOptions( throw new ArgumentNullException(nameof(modify)); } - builder.Services.AddSingleton(modify); + builder.CoreBuilder.Configure( + c => + { + c.OnConfigureSchemaServicesHooks.Add( + (ctx, sc) => + { + sc.AddSingleton(modify); + }); + }); return builder; } @@ -547,8 +555,7 @@ internal static ValueTask BuildSchemaAsync( private static FusionOptions GetFusionOptions(IServiceProvider sp) { - var appSp = sp.GetApplicationServices(); - var configures = appSp.GetServices>(); + var configures = sp.GetServices>(); var options = new FusionOptions(); foreach (var configure in configures) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/OptionsTests.cs b/src/HotChocolate/Fusion/test/Core.Tests/OptionsTests.cs new file mode 100644 index 00000000000..440a97efffa --- /dev/null +++ b/src/HotChocolate/Fusion/test/Core.Tests/OptionsTests.cs @@ -0,0 +1,73 @@ +using HotChocolate.Fusion.Composition; +using HotChocolate.Fusion.Composition.Features; +using HotChocolate.Fusion.Metadata; +using HotChocolate.Fusion.Shared; +using HotChocolate.Skimmed.Serialization; +using Microsoft.Extensions.DependencyInjection; + +namespace HotChocolate.Fusion; + +public class OptionsTests +{ + [Fact] + public async Task Options_Are_Scoped_To_Particular_Gateway_Builder() + { + using var demoProject = await DemoProject.CreateAsync(); + + var fusionGraph = await FusionGraphComposer.ComposeAsync( + new[] + { + demoProject.Appointment.ToConfiguration(), + }, + new FusionFeatureCollection(FusionFeatures.NodeField)); + + var services = new ServiceCollection() + .AddSingleton(demoProject.HttpClientFactory); + + var executor1 = await services + .AddFusionGatewayServer("graph1") + .ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph)) + .ModifyFusionOptions(options => options.AllowFusionQueryPlan = !options.AllowFusionQueryPlan) + .BuildRequestExecutorAsync("graph1"); + + var executor2 = await services.AddFusionGatewayServer("graph2") + .ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph)) + .BuildRequestExecutorAsync("graph2"); + + var options1 = executor1.Services.GetRequiredService(); + var options2 = executor2.Services.GetRequiredService(); + var defaultOptions = new FusionOptions(); + + Assert.Equal(options1.AllowFusionQueryPlan, !defaultOptions.AllowFusionQueryPlan); + Assert.Equal(options2.AllowFusionQueryPlan, defaultOptions.AllowFusionQueryPlan); + } + + [Fact] + public async Task Multiple_Option_Modifications_Are_Applied() + { + using var demoProject = await DemoProject.CreateAsync(); + + var fusionGraph = await FusionGraphComposer.ComposeAsync( + new[] + { + demoProject.Appointment.ToConfiguration(), + }, + new FusionFeatureCollection(FusionFeatures.NodeField)); + + var services = new ServiceCollection() + .AddSingleton(demoProject.HttpClientFactory); + + var executor = await services + .AddFusionGatewayServer() + .ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph)) + .ModifyFusionOptions(options => options.AllowFusionQueryPlan = !options.AllowFusionQueryPlan) + .ModifyFusionOptions(options => options.IncludeFusionDebugInfo = !options.IncludeFusionDebugInfo) + .BuildRequestExecutorAsync(); + + var options = executor.Services.GetRequiredService(); + var defaultOptions = new FusionOptions(); + + Assert.Equal(options.AllowFusionQueryPlan, !defaultOptions.AllowFusionQueryPlan); + Assert.Equal(options.IncludeFusionDebugInfo, !defaultOptions.IncludeFusionDebugInfo); + } +}