Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using HotChocolate;

namespace Microsoft.Extensions.DependencyInjection;

public static class ExecutionServiceProviderExtensions
{
/// <summary>
/// Gets the root service provider from the schema services. This allows
/// schema services to access application level services.
/// </summary>
/// <param name="schema">
/// The schema.
/// </param>
/// <returns>
/// The root service provider.
/// </returns>
public static IServiceProvider GetRootServiceProvider(this ISchemaDefinition schema)
=> schema.Services.GetRequiredService<IRootServiceProviderAccessor>().ServiceProvider;

/// <summary>
/// Gets the root service provider from the schema services. This allows
/// schema services to access application level services.
/// </summary>
/// <param name="services">
/// The schema services.
/// </param>
/// <returns>
/// The root service provider.
/// </returns>
public static IServiceProvider GetRootServiceProvider(this IServiceProvider services)
=> services.GetRequiredService<IRootServiceProviderAccessor>().ServiceProvider;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<PackageReference Include="System.IO.Pipelines" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Language\src\Language.SyntaxTree\HotChocolate.Language.SyntaxTree.csproj" />
<ProjectReference Include="..\..\..\Language\src\Language.Web\HotChocolate.Language.Web.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,4 @@ internal static IServiceCollection TryAddDiagnosticEvents(

return services;
}

/// <summary>
/// Gets the root service provider from the schema services. This allows
/// schema services to access application level services.
/// </summary>
/// <param name="schema">
/// The schema.
/// </param>
/// <returns>
/// The root service provider.
/// </returns>
public static IServiceProvider GetRootServiceProvider(this Schema schema)
=> schema.Services.GetRequiredService<IRootServiceProviderAccessor>().ServiceProvider;

/// <summary>
/// Gets the root service provider from the schema services. This allows
/// schema services to access application level services.
/// </summary>
/// <param name="services">
/// The schema services.
/// </param>
/// <returns>
/// The root service provider.
/// </returns>
public static IServiceProvider GetRootServiceProvider(this IServiceProvider services)
=> services.GetRequiredService<IRootServiceProviderAccessor>().ServiceProvider;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using HotChocolate.Execution;
using HotChocolate.Fusion.Configuration;

namespace Microsoft.Extensions.DependencyInjection;
Expand All @@ -19,4 +20,14 @@ public static IFusionGatewayBuilder AddApplicationService<TService>(
return builder.ConfigureSchemaServices(
static (sp, sc) => sc.AddSingleton(sp.GetRequiredService<TService>()));
}

public static ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default) =>
Comment on lines +24 to +27
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is missing XML documentation comments. Based on the existing pattern in the codebase (see RequestExecutorServiceProviderExtensions.cs lines 93-109), this method should include XML documentation describing its purpose, parameters, and return value.

Copilot uses AI. Check for mistakes.
builder
.Services
.BuildServiceProvider()
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
Comment on lines +31 to +32
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is a duplicate of the existing BuildRequestExecutorAsync extension method found in src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorServiceProviderExtensions.cs (lines 109-117). Both IFusionGatewayBuilder and IRequestExecutorBuilder have identical structure (Name and Services properties), so this duplication could be avoided by either: 1) extracting a common interface, 2) creating a shared helper method, or 3) using a generic extension method that works with any type that has a Services property of type IServiceCollection.

Suggested change
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
.BuildRequestExecutorAsync(schemaName, cancellationToken);

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +32
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling BuildServiceProvider() creates a new service provider instance that is not disposed. This can lead to resource leaks, especially if the service provider contains disposable services. The existing implementation in RequestExecutorServiceProviderExtensions.cs has the same issue, but adding another instance of this pattern compounds the problem. Consider documenting this limitation or using a using statement to ensure proper disposal.

Suggested change
public static ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default) =>
builder
.Services
.BuildServiceProvider()
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
public static async ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default)
{
using var serviceProvider = builder.Services.BuildServiceProvider();
var executorProvider = serviceProvider.GetRequiredService<IRequestExecutorProvider>();
return await executorProvider
.GetExecutorAsync(schemaName, cancellationToken)
.ConfigureAwait(false);
}

Copilot uses AI. Check for mistakes.
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,6 @@ public static IFusionGatewayBuilder AddGraphQLGateway(
return CreateBuilder(services, name);
}

/// <summary>
/// Gets the root service provider from the schema services. This allows
/// schema services to access application level services.
/// </summary>
/// <param name="services">
/// The schema services.
/// </param>
/// <returns>
/// The root service provider.
/// </returns>
public static IServiceProvider GetRootServiceProvider(this IServiceProvider services)
=> services.GetRequiredService<IRootServiceProviderAccessor>().ServiceProvider;

private static void AddRequestExecutorManager(
IServiceCollection services)
{
Expand Down
Loading