diff --git a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.DataLoader.cs b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.DataLoader.cs index a93cb3dd994..dc7cd587228 100644 --- a/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.DataLoader.cs +++ b/src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.DataLoader.cs @@ -37,6 +37,18 @@ public static IRequestExecutorBuilder AddDataLoader( builder.Services.TryAddScoped(sp => sp.GetDataLoader()); return builder; } + + public static IRequestExecutorBuilder AddDataLoader( + this IRequestExecutorBuilder builder, + Func factory) + where TService : class, IDataLoader + where TImplementation : class, TService + { + builder.Services.AddSingleton(new DataLoaderRegistration(typeof(TService), typeof(TImplementation), sp => factory(sp))); + builder.Services.TryAddScoped(sp => sp.GetDataLoader()); + builder.Services.TryAddScoped(sp => sp.GetDataLoader()); + return builder; + } } file static class DataLoaderServiceProviderExtensions diff --git a/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/DataLoaderTests.cs b/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/DataLoaderTests.cs index 79c48dad239..1a43ca5ac86 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/DataLoaderTests.cs +++ b/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/DataLoaderTests.cs @@ -472,6 +472,67 @@ await executor.ExecuteAsync( await snapshot.MatchMarkdownAsync(); } + [Fact] + public async Task ClassDataLoader_Resolve_From_DependencyInjection_Using_Factory() + { + var snapshot = new Snapshot(); + + // arrange + var executor = await CreateExecutorAsync( + c => c + .AddQueryType() + .AddDataLoader(sp => + new TestDataLoader( + sp.GetRequiredService(), + new DataLoaderOptions())) + .ModifyRequestOptions(o => o.IncludeExceptionDetails = true) + .UseRequest( + next => async context => + { + await next(context); + + var dataLoader = (TestDataLoader)context.Services.GetRequiredService(); + + context.Result = OperationResultBuilder + .FromResult(((IOperationResult)context.Result!)) + .AddExtension("loads", dataLoader.Loads) + .Build(); + }) + .UseDefaultPipeline()); + + // act + snapshot.Add( + await executor.ExecuteAsync( + OperationRequestBuilder.New() + .SetDocument( + @"{ + a: dataLoaderWithInterface(key: ""a"") + b: dataLoaderWithInterface(key: ""b"") + }") + .Build())); + + snapshot.Add( + await executor.ExecuteAsync( + OperationRequestBuilder.New() + .SetDocument( + @"{ + a: dataLoaderWithInterface(key: ""a"") + }") + .Build())); + + snapshot.Add( + await executor.ExecuteAsync( + OperationRequestBuilder.New() + .SetDocument( + @"{ + c: dataLoaderWithInterface(key: ""c"") + }") + .Build())); + + // assert + await snapshot.MatchMarkdownAsync(); + } + [LocalFact] public async Task NestedDataLoader() { diff --git a/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/__snapshots__/DataLoaderTests.ClassDataLoader_Resolve_From_DependencyInjection_Using_Factory.md b/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/__snapshots__/DataLoaderTests.ClassDataLoader_Resolve_From_DependencyInjection_Using_Factory.md new file mode 100644 index 00000000000..5782eeba4de --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/Integration/DataLoader/__snapshots__/DataLoaderTests.ClassDataLoader_Resolve_From_DependencyInjection_Using_Factory.md @@ -0,0 +1,55 @@ +# ClassDataLoader_Resolve_From_DependencyInjection_Using_Factory + +## Result 1 + +```json +{ + "data": { + "a": "a", + "b": "b" + }, + "extensions": { + "loads": [ + [ + "a", + "b" + ] + ] + } +} +``` + +## Result 2 + +```json +{ + "data": { + "a": "a" + }, + "extensions": { + "loads": [ + [ + "a" + ] + ] + } +} +``` + +## Result 3 + +```json +{ + "data": { + "c": "c" + }, + "extensions": { + "loads": [ + [ + "c" + ] + ] + } +} +``` +