diff --git a/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Http.cs b/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Http.cs index 74c2a410d39..a25b3e94caa 100644 --- a/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Http.cs +++ b/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Http.cs @@ -31,8 +31,7 @@ public static IRequestExecutorBuilder AddHttpRequestInterceptor( return builder.ConfigureSchemaServices(s => s .RemoveAll() - .AddSingleton(sp => - ActivatorUtilities.GetServiceOrCreateInstance(sp.GetCombinedServices()))); + .AddSingleton()); } /// @@ -60,7 +59,7 @@ public static IRequestExecutorBuilder AddHttpRequestInterceptor( return builder.ConfigureSchemaServices(s => s .RemoveAll() - .AddSingleton(sp => factory(sp.GetCombinedServices()))); + .AddSingleton(factory)); } /// diff --git a/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Subscriptions.cs b/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Subscriptions.cs index cbacdb1360e..8b63e85b247 100644 --- a/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Subscriptions.cs +++ b/src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.Subscriptions.cs @@ -28,8 +28,7 @@ public static IRequestExecutorBuilder AddSocketSessionInterceptor( where T : class, ISocketSessionInterceptor => builder.ConfigureSchemaServices(s => s .RemoveAll() - .AddSingleton( - sp => ActivatorUtilities.GetServiceOrCreateInstance(sp.GetCombinedServices()))); + .AddSingleton()); /// /// Adds an interceptor for GraphQL socket sessions to the GraphQL configuration. @@ -52,7 +51,7 @@ public static IRequestExecutorBuilder AddSocketSessionInterceptor( where T : class, ISocketSessionInterceptor => builder.ConfigureSchemaServices(s => s .RemoveAll() - .AddSingleton(sp => factory(sp.GetCombinedServices()))); + .AddSingleton(factory)); private static IRequestExecutorBuilder AddSubscriptionServices( this IRequestExecutorBuilder builder) diff --git a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.ErrorFilter.cs b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.ErrorFilter.cs index 884e22ba0fc..b447809afa6 100644 --- a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.ErrorFilter.cs +++ b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.ErrorFilter.cs @@ -30,8 +30,7 @@ public static IRequestExecutorBuilder AddErrorFilter( ArgumentNullException.ThrowIfNull(factory); return builder.ConfigureSchemaServices( - s => s.AddSingleton( - sp => factory(sp.GetCombinedServices()))); + s => s.AddSingleton(factory)); } public static IRequestExecutorBuilder AddErrorFilter( @@ -42,8 +41,7 @@ public static IRequestExecutorBuilder AddErrorFilter( builder.Services.TryAddSingleton(); return builder.ConfigureSchemaServices( - s => s.AddSingleton( - sp => sp.GetRootServiceProvider().GetRequiredService())); + s => s.AddSingleton()); } public static IServiceCollection AddErrorFilter( diff --git a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Instrumentation.cs b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Instrumentation.cs index b49f7dad36c..0d05e7ee04b 100644 --- a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Instrumentation.cs +++ b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Instrumentation.cs @@ -19,13 +19,14 @@ public static IRequestExecutorBuilder AddDiagnosticEventListener( { builder.Services.TryAddSingleton(); builder.ConfigureSchemaServices( - s => s.AddSingleton( - sp => (IExecutionDiagnosticEventListener)sp.GetRootServiceProvider().GetRequiredService())); + static s => s.AddSingleton( + static sp => (IExecutionDiagnosticEventListener)sp.GetRequiredService())); } else if (typeof(IDataLoaderDiagnosticEventListener).IsAssignableFrom(typeof(T))) { builder.Services.TryAddSingleton(); - builder.Services.AddSingleton(s => (IDataLoaderDiagnosticEventListener)s.GetRequiredService()); + builder.Services.AddSingleton( + static s => (IDataLoaderDiagnosticEventListener)s.GetRequiredService()); } else if (typeof(T).IsDefined(typeof(DiagnosticEventSourceAttribute), true)) { @@ -35,7 +36,7 @@ public static IRequestExecutorBuilder AddDiagnosticEventListener( { var attribute = typeof(T).GetCustomAttributes(typeof(DiagnosticEventSourceAttribute), true).First(); var listener = ((DiagnosticEventSourceAttribute)attribute).Listener; - s.AddSingleton(listener, sp => sp.GetRootServiceProvider().GetRequiredService()); + s.AddSingleton(listener, sp => sp.GetRequiredService()); }); } else @@ -48,23 +49,21 @@ public static IRequestExecutorBuilder AddDiagnosticEventListener( public static IRequestExecutorBuilder AddDiagnosticEventListener( this IRequestExecutorBuilder builder, - Func diagnosticEventListener) + Func factory) where T : class { ArgumentNullException.ThrowIfNull(builder); - ArgumentNullException.ThrowIfNull(diagnosticEventListener); + ArgumentNullException.ThrowIfNull(factory); if (typeof(IExecutionDiagnosticEventListener).IsAssignableFrom(typeof(T))) { builder.ConfigureSchemaServices( - s => s.AddSingleton( - sp => (IExecutionDiagnosticEventListener)diagnosticEventListener( - sp.GetCombinedServices()))); + s => s.AddSingleton(sp => (IExecutionDiagnosticEventListener)factory(sp))); } else if (typeof(IDataLoaderDiagnosticEventListener).IsAssignableFrom(typeof(T))) { builder.Services.AddSingleton( - s => (IDataLoaderDiagnosticEventListener)diagnosticEventListener(s)); + s => (IDataLoaderDiagnosticEventListener)factory(s)); } else if (typeof(T).IsDefined(typeof(DiagnosticEventSourceAttribute), true)) { @@ -78,13 +77,13 @@ public static IRequestExecutorBuilder AddDiagnosticEventListener( builder.ConfigureSchemaServices(s => { var listener = attribute.Listener; - s.AddSingleton(listener, sp => diagnosticEventListener(sp.GetCombinedServices())); + s.AddSingleton(listener, factory); }); } else { var listener = attribute.Listener; - builder.Services.AddSingleton(listener, diagnosticEventListener); + builder.Services.AddSingleton(listener, factory); } } else diff --git a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Optimizer.cs b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Optimizer.cs index e3e45cbc800..0d83d3c6e03 100644 --- a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Optimizer.cs +++ b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.Optimizer.cs @@ -24,8 +24,7 @@ public static IRequestExecutorBuilder AddOperationCompilerOptimizer( ArgumentNullException.ThrowIfNull(builder); builder.ConfigureSchemaServices( - sc => sc.AddSingleton( - sp => factory(sp.GetCombinedServices()))); + sc => sc.AddSingleton(factory)); return builder; } } diff --git a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.TransactionScope.cs b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.TransactionScope.cs index a058b313d41..f274846faf3 100644 --- a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.TransactionScope.cs +++ b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.TransactionScope.cs @@ -33,14 +33,10 @@ public static IRequestExecutorBuilder AddTransactionScopeHandler( return ConfigureSchemaServices( builder, - services => + static services => { - // we remove all handlers from the schema DI - services.RemoveAll(typeof(ITransactionScopeHandler)); - - // and then reference the transaction scope handler from the global DI. - services.AddSingleton( - s => s.GetRootServiceProvider().GetRequiredService()); + services.RemoveAll(); + services.AddSingleton(); }); } @@ -50,7 +46,7 @@ public static IRequestExecutorBuilder AddTransactionScopeHandler( /// /// The request executor builder. /// - /// + /// /// A factory to create the transaction scope. /// /// @@ -59,17 +55,17 @@ public static IRequestExecutorBuilder AddTransactionScopeHandler( /// public static IRequestExecutorBuilder AddTransactionScopeHandler( this IRequestExecutorBuilder builder, - Func create) + Func factory) { ArgumentNullException.ThrowIfNull(builder); - ArgumentNullException.ThrowIfNull(create); + ArgumentNullException.ThrowIfNull(factory); return ConfigureSchemaServices( builder, services => { - services.RemoveAll(typeof(ITransactionScopeHandler)); - services.AddSingleton(sp => create(sp.GetCombinedServices())); + services.RemoveAll(); + services.AddSingleton(factory); }); } @@ -101,10 +97,7 @@ internal static IRequestExecutorBuilder TryAddNoOpTransactionScopeHandler( return ConfigureSchemaServices( builder, - services => - { - services.TryAddSingleton( - sp => sp.GetRootServiceProvider().GetRequiredService()); - }); + static services => + services.TryAddSingleton()); } } diff --git a/src/HotChocolate/Core/src/Types/SchemaBuilder.cs b/src/HotChocolate/Core/src/Types/SchemaBuilder.cs index f835cf902ae..dcc01cdad52 100644 --- a/src/HotChocolate/Core/src/Types/SchemaBuilder.cs +++ b/src/HotChocolate/Core/src/Types/SchemaBuilder.cs @@ -225,11 +225,12 @@ public ISchemaBuilder SetTypeResolver(IsOfTypeFallback isOfType) } /// + // TODO: Should this be just SetServices? public ISchemaBuilder AddServices(IServiceProvider services) { ArgumentNullException.ThrowIfNull(services); - _services = _services is null ? services : new CombinedServiceProvider(_services, services); + _services = services; return this; } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Configuration/RootServiceProviderAccessor.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Configuration/RootServiceProviderAccessor.cs deleted file mode 100644 index f03289369bd..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Configuration/RootServiceProviderAccessor.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace HotChocolate.Fusion.Configuration; - -internal sealed class RootServiceProviderAccessor : IRootServiceProviderAccessor -{ - public RootServiceProviderAccessor(IServiceProvider serviceProvider) - { - ArgumentNullException.ThrowIfNull(serviceProvider); - - ServiceProvider = serviceProvider; - } - - public IServiceProvider ServiceProvider { get; } -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/CoreFusionGatewayBuilderExtensions.Services.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/CoreFusionGatewayBuilderExtensions.Services.cs new file mode 100644 index 00000000000..72ea99ebe98 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/CoreFusionGatewayBuilderExtensions.Services.cs @@ -0,0 +1,22 @@ +using HotChocolate.Fusion.Configuration; + +namespace Microsoft.Extensions.DependencyInjection; + +public static partial class CoreFusionGatewayBuilderExtensions +{ + /// + /// Resolves an instance of from the application + /// service provider and makes it available as a singleton through the schema + /// service provider. + /// + /// + /// The type of service. + /// + public static IFusionGatewayBuilder AddApplicationService( + this IFusionGatewayBuilder builder) + where TService : class + { + return builder.ConfigureSchemaServices( + static (sp, sc) => sc.AddSingleton(sp.GetRequiredService())); + } +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/InternalServiceProviderExtensions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/InternalServiceProviderExtensions.cs deleted file mode 100644 index 2ff165275af..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/InternalServiceProviderExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using HotChocolate; - -namespace Microsoft.Extensions.DependencyInjection; - -internal static class InternalServiceProviderExtensions -{ - public static T GetRequiredRootService(this IServiceProvider services) where T : notnull - => services.GetRequiredService().ServiceProvider.GetRequiredService(); -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Execution/FusionRequestExecutorManager.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Execution/FusionRequestExecutorManager.cs index 4b8ad1b3afc..fb08719546e 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Execution/FusionRequestExecutorManager.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Execution/FusionRequestExecutorManager.cs @@ -363,9 +363,6 @@ private void AddCoreServices( FusionOptions options, FusionRequestOptions requestOptions) { - services.AddSingleton( - new RootServiceProviderAccessor(_applicationServices)); - services.AddSingleton(static _ => new RequestExecutorAccessor()); services.AddSingleton(static sp => sp.GetRequiredService().RequestExecutor); services.AddSingleton(sp => sp.GetRequiredService()); diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Execution/FusionRequestExecutorManagerTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Execution/FusionRequestExecutorManagerTests.cs index 82319ec4e84..9a963c9faa3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Execution/FusionRequestExecutorManagerTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Execution/FusionRequestExecutorManagerTests.cs @@ -387,7 +387,7 @@ public async Task Executor_Resolution_Should_Be_Parallel() cts.Dispose(); } - [Fact(Skip = "SomeService needs to be registered with the schema services")] + [Fact] public async Task WarmupTask_Should_Be_Able_To_Access_Schema_And_Regular_Services() { // arrange @@ -398,6 +398,7 @@ public async Task WarmupTask_Should_Be_Able_To_Access_Schema_And_Regular_Service services .AddGraphQLGateway() .AddInMemoryConfiguration(CreateConfiguration().Schema) + .AddApplicationService() .AddWarmupTask(); var provider = services.BuildServiceProvider(); var manager = provider.GetRequiredService(); diff --git a/src/HotChocolate/PersistedOperations/src/PersistedOperations.AzureBlobStorage/Extensions/HotChocolateAzureBlobStoragePersistedOperationsRequestExecutorBuilderExtensions.cs b/src/HotChocolate/PersistedOperations/src/PersistedOperations.AzureBlobStorage/Extensions/HotChocolateAzureBlobStoragePersistedOperationsRequestExecutorBuilderExtensions.cs index 7162292cfad..19e7568a908 100644 --- a/src/HotChocolate/PersistedOperations/src/PersistedOperations.AzureBlobStorage/Extensions/HotChocolateAzureBlobStoragePersistedOperationsRequestExecutorBuilderExtensions.cs +++ b/src/HotChocolate/PersistedOperations/src/PersistedOperations.AzureBlobStorage/Extensions/HotChocolateAzureBlobStoragePersistedOperationsRequestExecutorBuilderExtensions.cs @@ -27,7 +27,6 @@ public static IRequestExecutorBuilder AddAzureBlobStorageOperationDocumentStorag ArgumentNullException.ThrowIfNull(containerClientFactory); return builder.ConfigureSchemaServices( - s => s.AddAzureBlobStorageOperationDocumentStorage( - sp => containerClientFactory(sp.GetCombinedServices()))); + s => s.AddAzureBlobStorageOperationDocumentStorage(containerClientFactory)); } } diff --git a/src/HotChocolate/PersistedOperations/src/PersistedOperations.Redis/Extensions/HotChocolateRedisPersistedOperationsRequestExecutorBuilderExtensions.cs b/src/HotChocolate/PersistedOperations/src/PersistedOperations.Redis/Extensions/HotChocolateRedisPersistedOperationsRequestExecutorBuilderExtensions.cs index f95141d9ffa..3b753f0e836 100644 --- a/src/HotChocolate/PersistedOperations/src/PersistedOperations.Redis/Extensions/HotChocolateRedisPersistedOperationsRequestExecutorBuilderExtensions.cs +++ b/src/HotChocolate/PersistedOperations/src/PersistedOperations.Redis/Extensions/HotChocolateRedisPersistedOperationsRequestExecutorBuilderExtensions.cs @@ -31,9 +31,7 @@ public static IRequestExecutorBuilder AddRedisOperationDocumentStorage( ArgumentNullException.ThrowIfNull(databaseFactory); return builder.ConfigureSchemaServices( - s => s.AddRedisOperationDocumentStorage( - sp => databaseFactory(sp.GetCombinedServices()), - queryExpiration)); + s => s.AddRedisOperationDocumentStorage(databaseFactory, queryExpiration)); } /// @@ -58,7 +56,7 @@ public static IRequestExecutorBuilder AddRedisOperationDocumentStorage( return builder.ConfigureSchemaServices( s => s.AddRedisOperationDocumentStorage( - sp => multiplexerFactory(sp.GetCombinedServices()).GetDatabase(), + sp => multiplexerFactory(sp).GetDatabase(), queryExpiration)); }