Skip to content

Commit 2c90ea1

Browse files
authored
Fixed issue that wrongly inferrs arguments as services. (#6980)
1 parent 2a1f1bc commit 2c90ea1

File tree

4 files changed

+105
-27
lines changed

4 files changed

+105
-27
lines changed

src/HotChocolate/Core/src/Types/Resolvers/Expressions/Parameters/InferredServiceParameterExpressionBuilder.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#nullable enable
22

3+
using System.Collections;
4+
using System.Collections.Generic;
35
using System.Linq.Expressions;
46
using System.Reflection;
57
using HotChocolate.Internal;
@@ -19,7 +21,16 @@ internal sealed class InferredServiceParameterExpressionBuilder(IServiceProvider
1921
public bool IsDefaultHandler => false;
2022

2123
public bool CanHandle(ParameterInfo parameter)
22-
=> serviceInspector.IsService(parameter.ParameterType);
24+
{
25+
if (parameter.ParameterType.IsGenericType &&
26+
typeof(IEnumerable).IsAssignableFrom(parameter.ParameterType) &&
27+
parameter.ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
28+
{
29+
return serviceInspector.IsService(parameter.ParameterType.GetGenericArguments()[0]);
30+
}
31+
32+
return serviceInspector.IsService(parameter.ParameterType);
33+
}
2334

2435
public Expression Build(ParameterExpressionBuilderContext context)
2536
{

src/HotChocolate/Core/test/Execution.Tests/Integration/Cancellation/CancellationTests.cs

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System.Diagnostics;
12
using HotChocolate.Execution;
3+
using HotChocolate.Tests;
24
using HotChocolate.Types;
35
using Microsoft.Extensions.DependencyInjection;
46

@@ -40,35 +42,32 @@ await executor.ExecuteAsync(
4042

4143
[Fact]
4244
public async Task Parallel_Ensure_Execution_Waits_For_Tasks()
43-
{
44-
// arrange
45-
var query = new Query2();
45+
=> await TryTest(async ct =>
46+
{
47+
// arrange
48+
var query = new Query2();
4649

47-
var executor =
48-
await new ServiceCollection()
49-
.AddSingleton(query)
50-
.AddGraphQL()
51-
.AddQueryType<Query2>()
52-
.BuildRequestExecutorAsync();
50+
var executor =
51+
await new ServiceCollection()
52+
.AddSingleton(query)
53+
.AddGraphQL()
54+
.AddQueryType<Query2>()
55+
.BuildRequestExecutorAsync(cancellationToken: ct);
5356

54-
using var cts = new CancellationTokenSource(150);
57+
using var cts = new CancellationTokenSource(150);
5558

56-
// act
57-
await executor.ExecuteAsync(
58-
QueryRequestBuilder.New()
59-
.SetQuery("{ task1 task2 }")
60-
.Create(),
61-
cts.Token);
59+
// act
60+
await executor.ExecuteAsync("{ task1 task2 }", cts.Token);
6261

63-
// assert
64-
// the first task is completed
65-
Assert.True(query.Task1);
66-
Assert.True(query.Task1Done);
62+
// assert
63+
// the first task is completed
64+
Assert.True(query.Task1);
65+
Assert.True(query.Task1Done);
6766

68-
// the second task is completed
69-
Assert.True(query.Task2);
70-
Assert.True(query.Task2Done);
71-
}
67+
// the second task is completed
68+
Assert.True(query.Task2);
69+
Assert.True(query.Task2Done);
70+
});
7271

7372
public class Query1
7473
{
@@ -133,4 +132,40 @@ public async Task<string> GetTask2()
133132
return "bar";
134133
}
135134
}
135+
136+
protected static async Task TryTest(Func<CancellationToken, Task> action)
137+
{
138+
// we will try four times ....
139+
using var cts = new CancellationTokenSource(Debugger.IsAttached ? 600_000_000 : 60_000);
140+
var ct = cts.Token;
141+
var count = 0;
142+
var wait = 50;
143+
144+
while (true)
145+
{
146+
ct.ThrowIfCancellationRequested();
147+
148+
if (count < 3)
149+
{
150+
try
151+
{
152+
await action(ct).ConfigureAwait(false);
153+
break;
154+
}
155+
catch
156+
{
157+
// try again
158+
}
159+
}
160+
else
161+
{
162+
await action(ct).ConfigureAwait(false);
163+
break;
164+
}
165+
166+
await Task.Delay(wait, ct).ConfigureAwait(false);
167+
wait *= 2;
168+
count++;
169+
}
170+
}
136171
}

src/HotChocolate/Core/test/Types.Tests/CodeFirstTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections;
5+
using System.Collections.Generic;
56
using System.Threading;
67
using System.Threading.Tasks;
78
using CookieCrumble;
@@ -209,6 +210,27 @@ public async Task Infer_Nullability_From_Nested_Classes()
209210
schema.MatchSnapshot();
210211
}
211212

213+
[Fact]
214+
public async Task EnumerableArgs_Are_Inferred_As_List()
215+
{
216+
var schema =
217+
await new ServiceCollection()
218+
.AddGraphQLServer()
219+
.AddQueryType<QueryWithEnumerableArg>()
220+
.BuildSchemaAsync();
221+
222+
schema.MatchInlineSnapshot(
223+
"""
224+
schema {
225+
query: QueryWithEnumerableArg
226+
}
227+
228+
type QueryWithEnumerableArg {
229+
foo(foo: [String!]!): String!
230+
}
231+
""");
232+
}
233+
212234
public class Query
213235
{
214236
public string SayHello(string name) =>
@@ -246,6 +268,12 @@ public Task<GenericWrapper<IPet>> GetPets(
246268
throw new NotImplementedException();
247269
}
248270

271+
public class QueryWithEnumerableArg
272+
{
273+
public string GetFoo(IEnumerable<string> foo)
274+
=> "foo";
275+
}
276+
249277
public class GenericWrapper<T>
250278
{
251279
public T Value { get; set; } = default!;

src/HotChocolate/Core/test/Utilities/TestHelper.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ public static Task<IExecutionResult> ExpectValid(
2323
query,
2424
new TestConfiguration
2525
{
26-
ConfigureRequest = request, Configure = configure, Services = requestServices,
26+
ConfigureRequest = request,
27+
Configure = configure,
28+
Services = requestServices,
2729
});
2830
}
2931

@@ -73,7 +75,9 @@ public static Task ExpectError(
7375
query,
7476
new TestConfiguration
7577
{
76-
Configure = configure, ConfigureRequest = request, Services = requestServices,
78+
Configure = configure,
79+
ConfigureRequest = request,
80+
Services = requestServices,
7781
},
7882
elementInspectors);
7983
}

0 commit comments

Comments
 (0)