Repository navigation
Add keyed service support to DataLoaders - #10314
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends HotChocolate’s DataLoader source generator/analyzers to support resolving keyed services (via [Service("key")] and [FromKeyedServices(...)]), adds new diagnostics (HC0130–HC0133) and code fixes for keyed-service misuse, and updates docs plus unit/integration test coverage to validate the new behavior.
Changes:
- Add keyed service detection/formatting to DataLoader parameter modeling and generation (emitting
GetRequiredKeyedService/GetKeyedServicewhere appropriate). - Introduce analyzers + code fixes for keyed-service attribute conflicts/invalid usage (HC0130–HC0133), including derived
ServiceAttributekey extraction. - Add documentation and comprehensive test coverage (unit snapshots + integration tests) for keyed DataLoader services.
Reviewed changes
Copilot reviewed 34 out of 35 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| website/content/docs/hotchocolate/fetching-data/batching/dataloader.md | Documents keyed services usage and new diagnostics for DataLoaders. |
| src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs | Adds analyzer error code constants HC0130–HC0133. |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/TestHelper.cs | Registers new keyed-service analyzers in test harness. |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/ServiceAttributeInfoTests.cs | Adds unit tests for service attribute key extraction (direct/derived/metadata/from-keyed-services). |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderTests.cs | Adds snapshot-based generator test covering keyed service emission. |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderKeyedServiceOnConstructorParameterAnalyzerTests.cs | Adds tests for constructor-parameter keyed [Service] detection. |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderKeyedServiceKeyNotDeterminableAnalyzerTests.cs | Adds tests for undeterminable derived ServiceAttribute keys (HC0133). |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderKeyedServiceConflictAnalyzerTests.cs | Adds tests for conflicting keyed service attributes (HC0130). |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderKeyedServiceAttributeIgnoredAnalyzerTests.cs | Adds tests for keyed-service attributes applied to non-service parameters (HC0131). |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/DataLoaderCodeFixTests.cs | Adds tests for new keyed-service code fixes (remove/replace attribute while preserving trivia). |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/snapshots/DataLoaderTests.GenerateSource_DataLoaderKeyedServices_MatchesSnapshot.md | Adds expected generated source snapshot for keyed service DataLoader emission. |
| src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/KeyedDataLoaderIntegrationTests.cs | Adds end-to-end integration tests for keyed DataLoader resolution in execution. |
| src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/snapshots/IntegrationTests.Schema_Snapshot.snap | Updates integration schema snapshot with new keyed DataLoader fields. |
| src/HotChocolate/Core/test/Types.Analyzers.Integration.Tests/snapshots/IntegrationTests.Schema_Snapshot_Without_ConnectionName_Inference.snap | Updates alternate schema snapshot with new keyed DataLoader fields. |
| src/HotChocolate/Core/test/Execution.Tests/DependencyInjectionTests.cs | Adds execution tests validating keyed DataLoader resolution and inspector identity behavior. |
| src/HotChocolate/Core/src/Types/Fetching/ExecutionDataLoaderScope.cs | Makes the DataLoader service provider keyed-aware (IKeyedServiceProvider + keyed inspector passthrough). |
| src/HotChocolate/Core/src/Types.Analyzers/WellKnownAttributes.cs | Adds well-known type name for FromKeyedServicesAttribute. |
| src/HotChocolate/Core/src/Types.Analyzers/Properties/SourceGenResources.resx | Adds localized messages for HC0130–HC0133 diagnostics. |
| src/HotChocolate/Core/src/Types.Analyzers/Properties/SourceGenResources.Designer.cs | Adds strongly-typed accessors for keyed-service diagnostic messages. |
| src/HotChocolate/Core/src/Types.Analyzers/Models/GenericDataLoaderInfo.cs | Threads Compilation into parameter creation for keyed service analysis. |
| src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderParameterInfo.cs | Adds keyed-service Key and nullability metadata to parameter model. |
| src/HotChocolate/Core/src/Types.Analyzers/Models/DataLoaderInfo.cs | Adds keyed service key extraction and formatting for service parameters. |
| src/HotChocolate/Core/src/Types.Analyzers/Inspectors/DataLoaderInspector.cs | Passes compilation to DataLoaderInfo for keyed service key computation. |
| src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs | Adds GetServiceAttributeInfo + derived key extraction logic for ServiceAttribute. |
| src/HotChocolate/Core/src/Types.Analyzers/Helpers/ServiceAttributeInfo.cs | Introduces a structured result for service attribute analysis. |
| src/HotChocolate/Core/src/Types.Analyzers/Helpers/CSharpLiteralFormatter.cs | Centralizes formatting of TypedConstants into valid C# literals. |
| src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/TypeFileBuilderBase.cs | Switches attribute instantiation to use the shared C# literal formatter. |
| src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/DataLoaderFileBuilder.cs | Emits keyed service resolution calls when a keyed service key is present. |
| src/HotChocolate/Core/src/Types.Analyzers/Errors.cs | Adds diagnostic descriptors for HC0130–HC0133. |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceOnConstructorParameterCodeFixProvider.cs | Adds code fix to replace keyed [Service] with [FromKeyedServices] for constructors. |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceOnConstructorParameterAnalyzer.cs | Adds analyzer to detect keyed [Service] on hand-written DataLoader constructors (HC0132). |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceKeyNotDeterminableAnalyzer.cs | Adds analyzer to flag undeterminable derived service keys (HC0133). |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceConflictAnalyzer.cs | Adds analyzer to flag conflicting keyed-service attributes (HC0130). |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceAttributeIgnoredCodeFixProvider.cs | Adds code fix to remove keyed-service attributes that have no effect (HC0131). |
| src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceAttributeIgnoredAnalyzer.cs | Adds analyzer to detect keyed-service attributes applied to non-service DataLoader parameters (HC0131). |
Files not reviewed (1)
- src/HotChocolate/Core/src/Types.Analyzers/Properties/SourceGenResources.Designer.cs: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+249
to
+259
| var serviceAttributeInfo = parameter.GetServiceAttributeInfo(compilation); | ||
| var key = serviceAttributeInfo.HasServiceAttribute | ||
| ? serviceAttributeInfo.ServiceKey is { } serviceKey | ||
| ? CSharpLiteralFormatter.FormatTypedConstant(serviceKey) | ||
| : serviceAttributeInfo.SourceDerivedServiceKey is { } sourceDerivedServiceKey | ||
| ? CSharpLiteralFormatter.FormatPrimitive(sourceDerivedServiceKey) | ||
| : null | ||
| : serviceAttributeInfo.HasFromKeyedServicesAttribute | ||
| && serviceAttributeInfo.FromKeyedServicesKey is { } fromKeyedServicesKey | ||
| ? CSharpLiteralFormatter.FormatTypedConstant(fromKeyedServicesKey) | ||
| : null; |
Comment on lines
+98
to
+110
| if (attributeType.ToDisplayString() == WellKnownAttributes.ServiceAttribute) | ||
| { | ||
| return attributeConstructor.Parameters.Length == 1; | ||
| } | ||
|
|
||
| var attributeData = parameter.GetAttributes().FirstOrDefault(t => | ||
| t.ApplicationSyntaxReference is { } syntaxReference | ||
| && syntaxReference.SyntaxTree == attribute.SyntaxTree | ||
| && syntaxReference.Span == attribute.Span); | ||
|
|
||
| return attributeData?.GetDerivedServiceKey(compilation, out _) | ||
| == SymbolExtensions.ServiceKeyExtractionResult.Key; | ||
| } |
| } | ||
| ``` | ||
|
|
||
| For attributes derived from `ServiceAttribute`, the constructor chain must be available in source and the string passed to the `ServiceAttribute` base constructor must be statically determinable. If `HC0133` remains, apply the key directly with `[Service("key")]` or `[FromKeyedServices(key)]`. Keys can be any constant, including strings, enum values, and integers. `KeyedService.AnyKey` is not supported. |
Contributor
Patch coverage84.6% of changed lines covered (703/831) Uncovered changed lines (JSON){
"sha": "3f42145f622f7581753d601692965baa7913d60e",
"files": [
{ "path": "src/HotChocolate/Core/src/Types/Resolvers/Expressions/Parameters/ServiceParameterExpressionBuilder.cs", "ranges": [[56, 56], [60, 60], [71, 71], [74, 75]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/Helpers/CSharpLiteralFormatter.cs", "ranges": [[19, 20], [27, 28], [34, 34], [36, 40], [56, 62], [65, 67], [72, 73], [108, 118]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/FileBuilders/TypeFileBuilderBase.cs", "ranges": [[1819, 1819]] },
{ "path": "src/HotChocolate/Core/src/Types/Fetching/ExecutionDataLoaderScope.cs", "ranges": [[104, 109], [144, 145], [147, 148]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs", "ranges": [[857, 860], [939, 940], [961, 962], [983, 991], [994, 994], [1013, 1014], [1045, 1046], [1070, 1071], [1083, 1086], [1125, 1127], [1161, 1162], [1171, 1172], [1183, 1184], [1214, 1221], [1223, 1225], [1250, 1252], [1279, 1281], [1304, 1308], [1316, 1318]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceAttributeIgnoredCodeFixProvider.cs", "ranges": [[27, 28], [37, 38], [57, 58]] },
{ "path": "src/HotChocolate/Core/src/Abstractions/ServiceAttribute.cs", "ranges": [[45, 45]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceOnConstructorParameterCodeFixProvider.cs", "ranges": [[17, 17], [21, 21], [29, 30], [75, 76]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceKeyNotDeterminableAnalyzer.cs", "ranges": [[64, 65]] },
{ "path": "src/HotChocolate/Core/src/Types.Analyzers/DataLoaderKeyedServiceAttributeIgnoredAnalyzer.cs", "ranges": [[82, 83]] }
]
}Project coverage: 57.7% (285877/495692 lines) |
This was referenced Oct 25, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #8513