Repository navigation
Conversation
Design options consideredRoot cause: the source-generated resolver binding path ( Option A — make Option B — widen Option C — surface Sub-decision — custom Drafted by Claude (Anthropic AI assistant). |
There was a problem hiding this comment.
Pull request overview
This PR aligns source-generated resolver parameter binding with the reflection-based path by ensuring custom parameter expression builders registered via AddParameterExpressionBuilder participate in the source-gen ParameterBindingResolver. It also adds explicit failure behavior when a custom builder relies on a ParameterInfo predicate that the source generator cannot evaluate.
Changes:
- Update
CustomParameterExpressionBuilderto implementIParameterBindingFactoryso custom builders are considered during source-generated parameter binding. - Add a guard in
ParameterBindingResolverto throw a clearSchemaExceptionwhen aParameterInfo-predicate custom builder would otherwise be silently misclassified. - Add unit + end-to-end source generator tests to validate correct classification/injection and the new failure mode.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/HotChocolate/Data/src/EntityFramework/ContextFactoryParameterExpressionBuilder.cs | Updates overrides to match new virtual ParameterDescriptor binding API in custom builder base. |
| src/HotChocolate/Data/src/Data/PagingArgumentsParameterExpressionBuilder.cs | Same as above, ensures paging argument binding participates correctly on source-gen path. |
| src/HotChocolate/Core/src/Types/Resolvers/ParameterBindingResolver.cs | Adds EnsureParameterInfoNotRequired to fail loudly when a ParameterInfo predicate is required. |
| src/HotChocolate/Core/src/Types/Internal/CustomParameterExpressionBuilder.cs | Implements IParameterBindingFactory and adds descriptor-based handling + runtime binding creation for source-gen. |
| src/HotChocolate/Core/test/Types.Tests/Resolvers/ParameterBindingResolverTests.cs | Unit coverage for classification, execution, and predicate-based failure behavior. |
| src/HotChocolate/Core/test/Types.Analyzers.Tests/SourceGeneratorReproTests.cs | End-to-end coverage for source-gen injection (not argument) and loud failure for predicate builder cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Patch coverage95.3% of changed lines covered (41/43)
Uncovered changed lines (JSON){
"sha": "c06d35238ca3b7017082ecf9d42641d7d911cce6",
"files": [
{ "path": "src/HotChocolate/Data/src/EntityFramework/ContextFactoryParameterExpressionBuilder.cs", "ranges": [[23, 23]] },
{ "path": "src/HotChocolate/Core/src/Types/Internal/CustomParameterExpressionBuilder.cs", "ranges": [[71, 71]] }
]
}Project coverage: 52.5% (217149/413306 lines) |
|
Superseded by #10041, which fixes the same root cause with a cleaner, less invasive change: a single file, with explicit interface implementations on the generic The only behavior this PR added that #10041 does not: a custom Drafted by Claude (Anthropic AI assistant). |
Summary
AddParameterExpressionBuilderare now honored on the source-generated resolver binding path, matching the reflection path.CustomParameterExpressionBuilderparticipates in the source-genParameterBindingResolver(it now implementsIParameterBindingFactory), like the built-in builders.partial)[QueryType]/[MutationType]/[ObjectType]resolver taking a context-supplied parameter could fail schema build when that CLR type was not a valid input type.ParameterInfopredicate (which the source generator cannot evaluate), schema build now fails with a clear, actionable error instead of silently misclassifying the parameter.Test plan
ParameterBindingResolver: a custom builder is classified asCustom(notArgument), its binding executes the registered delegate, and aParameterInfo-predicate builder throws for a matching parameter.partial [MutationType]with a custom parameter builds and executes with the parameter injected and absent from the schema as an argument; an interface/base parameter matched by a predicate builder fails loudly.