Skip to content

Commit a19912c

Browse files
committed
Fix nullable, default value and enum argument support
1 parent a4dced6 commit a19912c

File tree

5 files changed

+409
-131
lines changed

5 files changed

+409
-131
lines changed

src/Our.Umbraco.GraphQL/Adapters/GraphTypeAdapter.cs

+66-15
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,20 @@ public IGraphType Adapt(TypeInfo typeInfo)
6262

6363
private IGraphType AdaptInput(TypeInfo typeInfo)
6464
{
65-
var initialType = typeInfo;
66-
typeInfo = UnwrapTypeInfo(typeInfo);
67-
var graphType = TryGetFromCache(typeInfo, initialType);
65+
var unwrappedTypeInfo = UnwrapTypeInfo(typeInfo);
66+
var graphType = TryGetFromCache(unwrappedTypeInfo, typeInfo);
6867
if (graphType != null) return graphType;
69-
70-
graphType = CreateGraphType(typeInfo, typeof(InputObjectGraphType<>).MakeGenericType(typeInfo));
71-
_visitor?.Visit((IInputObjectGraphType) graphType);
72-
return Wrap(initialType, graphType);
68+
if (unwrappedTypeInfo.IsEnum)
69+
{
70+
graphType = CreateGraphType(unwrappedTypeInfo,
71+
typeof(EnumerationGraphType<>).MakeGenericType(unwrappedTypeInfo));
72+
}
73+
else
74+
{
75+
graphType = CreateGraphType(unwrappedTypeInfo, typeof(InputObjectGraphType<>).MakeGenericType(unwrappedTypeInfo));
76+
_visitor?.Visit((IInputObjectGraphType)graphType);
77+
}
78+
return graphType;
7379
}
7480

7581
private void AddFields(TypeInfo typeInfo, IComplexGraphType graphType)
@@ -99,19 +105,27 @@ private void AddFields(TypeInfo typeInfo, IComplexGraphType graphType)
99105
private FieldType CreateField(MemberInfo memberInfo)
100106
{
101107
var returnType = GetReturnType(memberInfo);
108+
var unwrappedReturnType = UnwrapTypeInfo(returnType);
102109

103-
var resolvedType = Adapt(returnType);
104-
if (memberInfo.GetCustomAttribute<NonNullAttribute>() != null)
105-
{
106-
resolvedType = WrapNonNull(resolvedType);
107-
}
110+
var foundType = _typeRegistry.Get(unwrappedReturnType);
108111

109-
if (memberInfo.GetCustomAttribute<NonNullItemAttribute>() != null &&
112+
IGraphType resolvedType = null;
113+
if (foundType == null)
114+
resolvedType = Adapt(returnType);
115+
116+
var isNonNullItem = memberInfo.GetCustomAttribute<NonNullItemAttribute>() != null;
117+
if (isNonNullItem && resolvedType != null &&
110118
resolvedType is ListGraphType listGraphType)
111119
{
112120
resolvedType = WrapList(WrapNonNull(listGraphType.ResolvedType));
113121
}
114122

123+
var isNonNull = memberInfo.GetCustomAttribute<NonNullAttribute>() != null;
124+
if (isNonNull && resolvedType != null)
125+
{
126+
resolvedType = WrapNonNull(resolvedType);
127+
}
128+
115129
var fieldType = new FieldType
116130
{
117131
Arguments = CreateArguments(memberInfo),
@@ -121,9 +135,11 @@ private FieldType CreateField(MemberInfo memberInfo)
121135
Metadata = {{nameof(MemberInfo), memberInfo}},
122136
Name = memberInfo.GetCustomAttribute<NameAttribute>()?.Name ?? memberInfo.Name,
123137
ResolvedType = resolvedType,
124-
Resolver = new FieldResolver(memberInfo, _dependencyResolver)
138+
Type = WrapTypeInfo(foundType, returnType, isNonNull, isNonNullItem)
125139
};
126140

141+
fieldType.Resolver = new FieldResolver(fieldType, _dependencyResolver);
142+
127143
return fieldType;
128144
}
129145

@@ -140,7 +156,22 @@ private QueryArguments CreateArguments(MemberInfo memberInfo)
140156

141157
private QueryArgument CreateArgument(ParameterInfo parameterInfo)
142158
{
143-
return new QueryArgument(AdaptInput(parameterInfo.ParameterType.GetTypeInfo()))
159+
var parameterType = parameterInfo.ParameterType;
160+
var hasDefaultValue = parameterInfo.HasDefaultValue ||
161+
parameterInfo.GetCustomAttribute<DefaultValueAttribute>() != null ||
162+
parameterType.IsValueType && parameterType.IsNullable();
163+
164+
var inputType = AdaptInput(parameterType.GetTypeInfo());
165+
if (hasDefaultValue == false && !(inputType is NonNullGraphType))
166+
{
167+
inputType = WrapNonNull(inputType);
168+
}
169+
if (hasDefaultValue && inputType is NonNullGraphType nonNullGraphType)
170+
{
171+
inputType = nonNullGraphType.ResolvedType;
172+
}
173+
174+
return new QueryArgument(inputType)
144175
{
145176
DefaultValue = parameterInfo.HasDefaultValue
146177
? parameterInfo.DefaultValue
@@ -227,6 +258,26 @@ private static TypeInfo UnwrapTypeInfo(TypeInfo typeInfo)
227258
return typeInfo;
228259
}
229260

261+
private TypeInfo WrapTypeInfo(TypeInfo graphType, TypeInfo typeInfo, bool isNonNull, bool isNonNullItem)
262+
{
263+
if (graphType == null)
264+
return null;
265+
266+
var enumerableArgument = GetEnumerableArgument(typeInfo);
267+
268+
if (typeInfo.IsValueType && typeInfo.IsNullable() == false || enumerableArgument != null &&
269+
(enumerableArgument.IsValueType && enumerableArgument.IsNullable() == false || isNonNullItem))
270+
graphType = typeof(NonNullGraphType<>).MakeGenericType(graphType).GetTypeInfo();
271+
272+
if (enumerableArgument != null)
273+
graphType = typeof(ListGraphType<>).MakeGenericType(graphType).GetTypeInfo();
274+
275+
if (isNonNull)
276+
graphType = typeof(NonNullGraphType<>).MakeGenericType(graphType).GetTypeInfo();
277+
278+
return graphType;
279+
}
280+
230281
private IGraphType Wrap(TypeInfo typeInfo, IGraphType graphType)
231282
{
232283
var enumerableArgument = GetEnumerableArgument(typeInfo);

src/Our.Umbraco.GraphQL/Adapters/IGraphTypeAdapter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ public interface IGraphTypeAdapter
88
IGraphType Adapt<T>();
99
IGraphType Adapt(TypeInfo typeInfo);
1010
}
11-
}
11+
}

src/Our.Umbraco.GraphQL/Adapters/Resolvers/FieldResolver.cs

+22-14
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,23 @@ namespace Our.Umbraco.GraphQL.Adapters.Resolvers
1010
{
1111
public class FieldResolver : IFieldResolver
1212
{
13-
private readonly MemberInfo _memberInfo;
13+
private readonly FieldType _fieldType;
1414
private readonly IDependencyResolver _dependencyResolver;
1515

16-
public FieldResolver(MemberInfo memberInfo, IDependencyResolver dependencyResolver)
16+
public FieldResolver(FieldType fieldType, IDependencyResolver dependencyResolver)
1717
{
18-
_memberInfo = memberInfo ?? throw new ArgumentNullException(nameof(memberInfo));
18+
_fieldType = fieldType ?? throw new ArgumentNullException(nameof(fieldType));
1919
_dependencyResolver = dependencyResolver ?? throw new ArgumentNullException(nameof(dependencyResolver));
2020
}
2121

2222
public object Resolve(ResolveFieldContext context)
2323
{
24-
var source = context.Source ?? _dependencyResolver.Resolve(_memberInfo.DeclaringType);
24+
var memberInfo = _fieldType.GetMetadata<MemberInfo>(nameof(MemberInfo));
25+
var source = context.Source;
26+
if(source == null || memberInfo.DeclaringType.IsInstanceOfType(source) == false)
27+
source = _dependencyResolver.Resolve(memberInfo.DeclaringType);
2528

26-
switch (_memberInfo)
29+
switch (memberInfo)
2730
{
2831
case FieldInfo fieldInfo:
2932
return fieldInfo.GetValue(source);
@@ -38,23 +41,28 @@ public object Resolve(ResolveFieldContext context)
3841

3942
private object CallMethod(MethodInfo methodInfo, object source, ResolveFieldContext context)
4043
{
41-
var arguments = methodInfo.GetParameters().ToList();
42-
var parameters = new object[arguments.Count];
43-
for (var i = 0; i < arguments.Count; i++)
44+
var parameters = methodInfo.GetParameters().ToList();
45+
var arguments = new object[parameters.Count];
46+
47+
var argumentsIndex = 0;
48+
for (var i = 0; i < parameters.Count; i++)
4449
{
45-
var argument = arguments[i];
46-
var parameterType = argument.ParameterType;
50+
var parameterInfo = parameters[i];
51+
var parameterType = parameterInfo.ParameterType;
4752

48-
if (argument.GetCustomAttribute<InjectAttribute>() != null)
53+
if (parameterInfo.GetCustomAttribute<InjectAttribute>() != null)
4954
{
50-
parameters[i] = _dependencyResolver.Resolve(parameterType);
55+
arguments[i] = _dependencyResolver.Resolve(parameterType);
5156
continue;
5257
}
5358

54-
parameters[i] = context.GetArgument(parameterType, argument.Name, argument.DefaultValue);
59+
var argument = _fieldType.Arguments[argumentsIndex];
60+
argumentsIndex++;
61+
62+
arguments[i] = context.GetArgument(parameterType, parameterInfo.Name, argument.DefaultValue);
5563
}
5664

57-
return methodInfo.Invoke(source, parameters);
65+
return methodInfo.Invoke(source, arguments);
5866
}
5967
}
6068
}

0 commit comments

Comments
 (0)