Skip to content

Commit 4e7b2f5

Browse files
authored
Fixed schema initialization when type has field that returns list of objects. (#8288)
1 parent de2a711 commit 4e7b2f5

File tree

7 files changed

+78
-78
lines changed

7 files changed

+78
-78
lines changed

src/HotChocolate/Core/src/Types/Types/Descriptors/Conventions/DefaultTypeInspector.cs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Buffers;
44
using System.Collections;
55
using System.Collections.Concurrent;
6+
using System.Collections.Immutable;
67
using System.ComponentModel.DataAnnotations;
78
using System.Diagnostics.CodeAnalysis;
89
using System.Reflection;
@@ -714,6 +715,12 @@ private bool CanBeHandled(
714715
return false;
715716
}
716717

718+
if(member.IsDefined(typeof(GraphQLTypeAttribute), true) ||
719+
member.IsDefined(typeof(DescriptorAttribute), true))
720+
{
721+
return true;
722+
}
723+
717724
if (member.DeclaringType == typeof(object))
718725
{
719726
return false;
@@ -784,6 +791,33 @@ private static bool CanHandleReturnType(
784791
return false;
785792
}
786793

794+
if (typeof(IEnumerable<object>)== returnType ||
795+
typeof(IAsyncEnumerable<object>) == returnType ||
796+
typeof(IReadOnlyCollection<object>) == returnType ||
797+
typeof(IReadOnlyList<object>) == returnType ||
798+
typeof(ICollection<object>) == returnType ||
799+
typeof(IList<object>) == returnType ||
800+
typeof(IList) == returnType ||
801+
typeof(ICollection) == returnType ||
802+
typeof(List<object>) == returnType ||
803+
typeof(Array) == returnType ||
804+
typeof(object[]) == returnType ||
805+
typeof(ImmutableArray<object>) == returnType ||
806+
typeof(ImmutableList<object>) == returnType ||
807+
typeof(ImmutableHashSet<object>) == returnType ||
808+
typeof(ImmutableDictionary<object, object>) == returnType ||
809+
typeof(HashSet<object>) == returnType ||
810+
typeof(Dictionary<object, object>) == returnType ||
811+
typeof(ConcurrentBag<object>) == returnType ||
812+
typeof(ConcurrentDictionary<object, object>) == returnType ||
813+
typeof(ConcurrentQueue<object>) == returnType ||
814+
typeof(ConcurrentStack<object>) == returnType ||
815+
typeof(Queue<object>) == returnType ||
816+
typeof(Stack<object>) == returnType)
817+
{
818+
return false;
819+
}
820+
787821
// All other types may cause errors and need to have an explicit configuration.
788822
if (typeof(ITypeSystemMember).IsAssignableFrom(returnType))
789823
{
@@ -813,7 +847,7 @@ private static bool CanHandleReturnType(
813847
private static bool CanHandleParameter(ParameterInfo parameter, bool allowObjectType)
814848
{
815849
// schema, object type and object field can be injected into a resolver, so
816-
// we allow these as parameter type.
850+
// we allow these as a parameter type.
817851
var parameterType = parameter.ParameterType;
818852

819853
if (typeof(ISchema).IsAssignableFrom(parameterType) ||
@@ -920,5 +954,3 @@ private bool TryGetDefaultValueFromConstructor(
920954
return false;
921955
}
922956
}
923-
924-

src/HotChocolate/Core/test/Types.Queries.Tests/__snapshots__/AnnotationBasedSchemaTests.Schema_Query_With_FieldResult_And_Paging.graphql

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -88,40 +88,6 @@ union UsersResult = UsersConnection | UserNotFound
8888

8989
union UsersWithFilterResult = UsersWithFilterConnection | UserNotFound
9090

91-
input AddressFilterInput {
92-
and: [AddressFilterInput!]
93-
or: [AddressFilterInput!]
94-
id: StringOperationFilterInput
95-
street: StringOperationFilterInput
96-
city: StringOperationFilterInput
97-
}
98-
99-
input BooleanOperationFilterInput {
100-
eq: Boolean
101-
neq: Boolean
102-
}
103-
104-
input FieldResultOfAddressAndAddressNotFoundFilterInput {
105-
and: [FieldResultOfAddressAndAddressNotFoundFilterInput!]
106-
or: [FieldResultOfAddressAndAddressNotFoundFilterInput!]
107-
value: AddressFilterInput
108-
errors: ListFilterInputTypeOfObjectFilterInput
109-
isSuccess: BooleanOperationFilterInput
110-
isError: BooleanOperationFilterInput
111-
}
112-
113-
input ListFilterInputTypeOfObjectFilterInput {
114-
all: ObjectFilterInput
115-
none: ObjectFilterInput
116-
some: ObjectFilterInput
117-
any: Boolean
118-
}
119-
120-
input ObjectFilterInput {
121-
and: [ObjectFilterInput!]
122-
or: [ObjectFilterInput!]
123-
}
124-
12591
input StringOperationFilterInput {
12692
and: [StringOperationFilterInput!]
12793
or: [StringOperationFilterInput!]
@@ -143,14 +109,12 @@ input UserFilterInput {
143109
id: StringOperationFilterInput
144110
name: StringOperationFilterInput
145111
email: StringOperationFilterInput
146-
address: FieldResultOfAddressAndAddressNotFoundFilterInput
147112
}
148113

149114
input UserSortInput {
150115
id: SortEnumType
151116
name: SortEnumType
152117
email: SortEnumType
153-
address: SortEnumType
154118
}
155119

156120
enum SortEnumType {

src/HotChocolate/Core/test/Types.Queries.Tests/__snapshots__/CodeFirstSchemaTests.Schema_Query_With_FieldResult_And_Paging.graphql

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -88,40 +88,6 @@ union UsersResult = UsersConnection | UserNotFound
8888

8989
union UsersWithFilterResult = UsersWithFilterConnection | UserNotFound
9090

91-
input AddressFilterInput {
92-
and: [AddressFilterInput!]
93-
or: [AddressFilterInput!]
94-
id: StringOperationFilterInput
95-
street: StringOperationFilterInput
96-
city: StringOperationFilterInput
97-
}
98-
99-
input BooleanOperationFilterInput {
100-
eq: Boolean
101-
neq: Boolean
102-
}
103-
104-
input FieldResultOfAddressAndAddressNotFoundFilterInput {
105-
and: [FieldResultOfAddressAndAddressNotFoundFilterInput!]
106-
or: [FieldResultOfAddressAndAddressNotFoundFilterInput!]
107-
value: AddressFilterInput
108-
errors: ListFilterInputTypeOfObjectFilterInput
109-
isSuccess: BooleanOperationFilterInput
110-
isError: BooleanOperationFilterInput
111-
}
112-
113-
input ListFilterInputTypeOfObjectFilterInput {
114-
all: ObjectFilterInput
115-
none: ObjectFilterInput
116-
some: ObjectFilterInput
117-
any: Boolean
118-
}
119-
120-
input ObjectFilterInput {
121-
and: [ObjectFilterInput!]
122-
or: [ObjectFilterInput!]
123-
}
124-
12591
input StringOperationFilterInput {
12692
and: [StringOperationFilterInput!]
12793
or: [StringOperationFilterInput!]
@@ -143,14 +109,12 @@ input UserFilterInput {
143109
id: StringOperationFilterInput
144110
name: StringOperationFilterInput
145111
email: StringOperationFilterInput
146-
address: FieldResultOfAddressAndAddressNotFoundFilterInput
147112
}
148113

149114
input UserSortInput {
150115
id: SortEnumType
151116
name: SortEnumType
152117
email: SortEnumType
153-
address: SortEnumType
154118
}
155119

156120
enum SortEnumType {

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections;
2+
using System.Collections.Immutable;
23
using System.Linq.Expressions;
34
using HotChocolate.Execution;
45
using HotChocolate.Language;
@@ -2112,6 +2113,18 @@ public async Task Ignore_Generic_Methods()
21122113
schema.MatchSnapshot();
21132114
}
21142115

2116+
[Fact]
2117+
public async Task Ignore_Object_Lists()
2118+
{
2119+
var schema =
2120+
await new ServiceCollection()
2121+
.AddGraphQL()
2122+
.AddQueryType<IgnoreObjectLists>()
2123+
.BuildSchemaAsync();
2124+
2125+
schema.MatchSnapshot();
2126+
}
2127+
21152128
public abstract class ResolverBase
21162129
{
21172130
public int GetValue() => 1024;
@@ -2439,4 +2452,21 @@ public class QueryWithGenerics
24392452

24402453
public T Foo<T>() => default!;
24412454
}
2455+
2456+
public class IgnoreObjectLists
2457+
{
2458+
public string Hello() => throw new InvalidOperationException();
2459+
2460+
public IEnumerable<object> ObjList1 => throw new InvalidOperationException();
2461+
2462+
public IReadOnlyCollection<object> ObjList2 => throw new InvalidOperationException();
2463+
2464+
public IReadOnlyList<object> ObjList3 => throw new InvalidOperationException();
2465+
2466+
public List<object> ObjList4 => throw new InvalidOperationException();
2467+
2468+
public object[] ObjList5 => throw new InvalidOperationException();
2469+
2470+
public ImmutableArray<object> ObjList6 => throw new InvalidOperationException();
2471+
}
24422472
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
schema {
2+
query: IgnoreObjectLists
3+
}
4+
5+
type IgnoreObjectLists {
6+
hello: String!
7+
}

src/HotChocolate/Data/src/Data/Filters/FilterInputTypeDescriptor`1.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ protected override void OnCompleteFields(
5252
fields,
5353
handledProperties,
5454
include: (_, member)
55-
=> member is PropertyInfo && !handledProperties.Contains(member));
55+
=> member is PropertyInfo p
56+
&& !handledProperties.Contains(member)
57+
&& !typeof(IFieldResult).IsAssignableFrom(p.PropertyType));
5658
}
5759

5860
base.OnCompleteFields(fields, handledProperties);

src/HotChocolate/Data/src/Data/Sorting/SortInputTypeDescriptor`1.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ protected override void OnCompleteFields(
5252
.CreateConfiguration(),
5353
fields,
5454
handledProperties,
55-
include: (_, member) => member is PropertyInfo &&
55+
include: (_, member) => member is PropertyInfo p &&
5656
!handledProperties.Contains(member) &&
57-
!Context.TypeInspector.GetReturnType(member).IsArrayOrList);
57+
!Context.TypeInspector.GetReturnType(member).IsArrayOrList &&
58+
!typeof(IFieldResult).IsAssignableFrom(p.PropertyType));
5859
}
5960

6061
base.OnCompleteFields(fields, handledProperties);

0 commit comments

Comments
 (0)