Skip to content

Commit 28c895d

Browse files
committed
Fixed concurrency issue when building selector expressions. (#8118)
1 parent 9e1eb7b commit 28c895d

File tree

1 file changed

+8
-10
lines changed

1 file changed

+8
-10
lines changed

src/HotChocolate/Core/src/Execution.Projections/SelectionExpressionBuilder.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ namespace HotChocolate.Execution.Projections;
1111

1212
internal sealed class SelectionExpressionBuilder
1313
{
14-
private static readonly NullabilityInfoContext _nullabilityInfoContext = new();
15-
1614
public Expression<Func<TRoot, TRoot>> BuildExpression<TRoot>(ISelection selection)
1715
{
1816
var rootType = typeof(TRoot);
1917
var parameter = Expression.Parameter(rootType, "root");
2018
var requirements = selection.DeclaringOperation.Schema.Features.GetRequired<FieldRequirementsMetadata>();
21-
var context = new Context(parameter, rootType, requirements);
19+
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext());
2220
var root = new TypeContainer();
2321

2422
CollectTypes(context, selection, root);
@@ -38,7 +36,7 @@ public Expression<Func<TRoot, TRoot>> BuildNodeExpression<TRoot>(ISelection sele
3836
var rootType = typeof(TRoot);
3937
var parameter = Expression.Parameter(rootType, "root");
4038
var requirements = selection.DeclaringOperation.Schema.Features.GetRequired<FieldRequirementsMetadata>();
41-
var context = new Context(parameter, rootType, requirements);
39+
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext());
4240
var root = new TypeContainer();
4341

4442
var entityType = selection.DeclaringOperation
@@ -252,7 +250,7 @@ private void CollectSelections(
252250

253251
if (node.Nodes.Count == 0)
254252
{
255-
if (IsNullableType(node.Property))
253+
if (IsNullableType(context, node.Property))
256254
{
257255
var nullCheck = Expression.Condition(
258256
Expression.Equal(propertyAccessor, Expression.Constant(null)),
@@ -273,7 +271,7 @@ private void CollectSelections(
273271
var newContext = context with { Parent = propertyAccessor, ParentType = node.Property.PropertyType };
274272
var nestedExpression = BuildTypeSwitchExpression(newContext, node);
275273

276-
if (IsNullableType(node.Property))
274+
if (IsNullableType(context, node.Property))
277275
{
278276
var nullCheck = Expression.Condition(
279277
Expression.Equal(propertyAccessor, Expression.Constant(null)),
@@ -286,22 +284,22 @@ private void CollectSelections(
286284
return nestedExpression is null ? null : Expression.Bind(node.Property, nestedExpression);
287285
}
288286

289-
private static bool IsNullableType(PropertyInfo propertyInfo)
287+
private static bool IsNullableType(Context context, PropertyInfo propertyInfo)
290288
{
291289
if (propertyInfo.PropertyType.IsValueType)
292290
{
293291
return Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
294292
}
295293

296-
var nullabilityInfo = _nullabilityInfoContext.Create(propertyInfo);
297-
294+
var nullabilityInfo = context.NullabilityInfoContext.Create(propertyInfo);
298295
return nullabilityInfo.WriteState == NullabilityState.Nullable;
299296
}
300297

301298
private readonly record struct Context(
302299
Expression Parent,
303300
Type ParentType,
304-
FieldRequirementsMetadata Requirements)
301+
FieldRequirementsMetadata Requirements,
302+
NullabilityInfoContext NullabilityInfoContext)
305303
{
306304
public TypeNode? GetRequirements(ISelection selection)
307305
{

0 commit comments

Comments
 (0)