1
1
using System . Collections ;
2
+ using System . Collections . Concurrent ;
2
3
using System . Collections . Immutable ;
3
4
using GraphQL . Execution ;
4
5
using GraphQL . SystemTextJson ;
@@ -58,6 +59,60 @@ public async Task VariableModification_ShouldReflectInSecondField()
58
59
""" ) ;
59
60
}
60
61
62
+ [ Fact ]
63
+ public async Task SampleCodeWorksWhenMergingSelectionSets ( )
64
+ {
65
+ var heroType = new ObjectGraphType ( ) { Name = "Hero" } ;
66
+ heroType . Field < IntGraphType > ( "id" ) ;
67
+ heroType . Field < StringGraphType > ( "name" ) ;
68
+ var query = new ObjectGraphType ( ) { Name = "Query" } ;
69
+ query . Field ( "hero" , heroType )
70
+ . Argument < IntGraphType > ( "id" )
71
+ . Resolve ( context => new { id = context . GetArgument < int > ( "id" ) , name = "John Doe" } ) ;
72
+ var schema = new Schema { Query = query } ;
73
+ schema . Initialize ( ) ;
74
+ var options = new ExecutionOptions
75
+ {
76
+ Schema = schema ,
77
+ Query = """
78
+ query heroQuery($id: Int!) {
79
+ ...fragment1
80
+ ...fragment2
81
+ }
82
+ fragment fragment1 on Query {
83
+ hero(id: $id) {
84
+ id
85
+ }
86
+ }
87
+ fragment fragment2 on Query {
88
+ hero(id: $id) {
89
+ name
90
+ }
91
+ }
92
+ """ ,
93
+ Variables = new Inputs ( new Dictionary < string , object ? >
94
+ {
95
+ { "id" , 123 }
96
+ } ) ,
97
+ ValidationRules = DocumentValidator . CoreRules . Append ( new FieldMappingValidationRule ( ) ) ,
98
+ } ;
99
+ options . Listeners . Add ( new DynamicVariableExecutionListener ( ) ) ;
100
+
101
+ var result = await new DocumentExecuter ( ) . ExecuteAsync ( options ) ;
102
+ var resultJson = new GraphQLSerializer ( ) . Serialize ( result ) ;
103
+
104
+ resultJson . ShouldBeCrossPlatJson ( """
105
+ {
106
+ "data": {
107
+ "hero": {
108
+ "id": 123,
109
+ "name": "John Doe"
110
+ }
111
+ }
112
+ }
113
+ """ ) ;
114
+ }
115
+
61
116
public class FieldMappingValidationRule : ValidationRuleBase
62
117
{
63
118
public override ValueTask < INodeVisitor ? > GetPostNodeVisitorAsync ( ValidationContext context ) => new ( new MyVisitor ( ) ) ;
@@ -97,13 +152,14 @@ public override Task BeforeExecutionAsync(IExecutionContext context)
97
152
return Task . CompletedTask ;
98
153
}
99
154
100
- private class FieldArgumentDictionary : IReadOnlyDictionary < GraphQLField , IDictionary < string , ArgumentValue > >
155
+ private class FieldArgumentDictionary : IReadOnlyDictionary < GraphQLField , IDictionary < string , ArgumentValue > > , IDictionary < GraphQLField , IDictionary < string , ArgumentValue > >
101
156
{
102
157
private readonly IExecutionContext _executionContext ;
103
158
private readonly IDictionary < GraphQLField , FieldType > _fieldMappings ;
104
159
private GraphQLField ? _lastField ;
105
160
private IDictionary < string , ArgumentValue > ? _lastArgs ;
106
161
private readonly object _lastFieldLock = new ( ) ;
162
+ private ConcurrentDictionary < GraphQLField , IDictionary < string , ArgumentValue > > ? _overrideDictionary ;
107
163
108
164
public FieldArgumentDictionary ( IExecutionContext executionContext , IDictionary < GraphQLField , FieldType > fieldMappings )
109
165
{
@@ -119,18 +175,28 @@ public IDictionary<string, ArgumentValue> this[GraphQLField key]
119
175
return value ;
120
176
throw new ArgumentOutOfRangeException ( nameof ( key ) ) ;
121
177
}
178
+ set => ( _overrideDictionary ??= new ( ) ) [ key ] = value ;
122
179
}
123
180
124
181
public IEnumerable < GraphQLField > Keys => throw new NotImplementedException ( ) ;
125
182
public IEnumerable < IDictionary < string , ArgumentValue > > Values => throw new NotImplementedException ( ) ;
126
183
public int Count => throw new NotImplementedException ( ) ;
127
184
185
+ ICollection < GraphQLField > IDictionary < GraphQLField , IDictionary < string , ArgumentValue > > . Keys => throw new NotImplementedException ( ) ;
186
+
187
+ ICollection < IDictionary < string , ArgumentValue > > IDictionary < GraphQLField , IDictionary < string , ArgumentValue > > . Values => throw new NotImplementedException ( ) ;
188
+
189
+ bool ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . IsReadOnly => throw new NotImplementedException ( ) ;
190
+
128
191
public bool ContainsKey ( GraphQLField key ) => _fieldMappings . ContainsKey ( key ) ;
129
192
130
193
public IEnumerator < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > GetEnumerator ( ) => throw new NotImplementedException ( ) ;
131
194
132
195
public bool TryGetValue ( GraphQLField key , out IDictionary < string , ArgumentValue > value )
133
196
{
197
+ if ( _overrideDictionary ? . TryGetValue ( key , out value ! ) == true )
198
+ return true ;
199
+
134
200
lock ( _lastFieldLock )
135
201
{
136
202
if ( key == _lastField )
@@ -163,6 +229,13 @@ public bool TryGetValue(GraphQLField key, out IDictionary<string, ArgumentValue>
163
229
}
164
230
165
231
IEnumerator IEnumerable . GetEnumerator ( ) => throw new NotImplementedException ( ) ;
232
+ void IDictionary < GraphQLField , IDictionary < string , ArgumentValue > > . Add ( GraphQLField key , IDictionary < string , ArgumentValue > value ) => throw new NotImplementedException ( ) ;
233
+ bool IDictionary < GraphQLField , IDictionary < string , ArgumentValue > > . Remove ( GraphQLField key ) => throw new NotImplementedException ( ) ;
234
+ void ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . Add ( KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > item ) => throw new NotImplementedException ( ) ;
235
+ void ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . Clear ( ) => throw new NotImplementedException ( ) ;
236
+ bool ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . Contains ( KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > item ) => throw new NotImplementedException ( ) ;
237
+ void ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . CopyTo ( KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > [ ] array , int arrayIndex ) => throw new NotImplementedException ( ) ;
238
+ bool ICollection < KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > > . Remove ( KeyValuePair < GraphQLField , IDictionary < string , ArgumentValue > > item ) => throw new NotImplementedException ( ) ;
166
239
}
167
240
}
168
241
}
0 commit comments