Skip to content

Commit 4fb98f1

Browse files
authored
Merge pull request graphql-dotnet#254 from graphql-dotnet/union-instance
Fix Union instance registration
2 parents d6d50a9 + 03deb70 commit 4fb98f1

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

src/GraphQL.Tests/Execution/RegisteredInstanceTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,42 @@ public void build_dynamic_schema()
117117
root: new SomeObject { Name = "Quinn"});
118118
}
119119

120+
[Fact]
121+
public void build_union()
122+
{
123+
var schema = new Schema();
124+
125+
var person = new ObjectGraphType();
126+
person.Name = "Person";
127+
person.Field("name", new StringGraphType());
128+
person.IsTypeOf = type => true;
129+
130+
var robot = new ObjectGraphType();
131+
robot.Name = "Robot";
132+
robot.Field("name", new StringGraphType());
133+
robot.IsTypeOf = type => true;
134+
135+
var personOrRobot = new UnionGraphType();
136+
personOrRobot.Name = "PersonOrRobot";
137+
personOrRobot.AddPossibleType(person);
138+
personOrRobot.AddPossibleType(robot);
139+
140+
var root = new ObjectGraphType();
141+
root.Name = "Root";
142+
root.Field("hero", personOrRobot, resolve: ctx => ctx.RootValue);
143+
144+
schema.Query = root;
145+
146+
AssertQuerySuccess(
147+
schema,
148+
@"{ hero {
149+
... on Person { name }
150+
... on Robot { name }
151+
} }",
152+
@"{ hero: { name : 'Quinn' }}",
153+
root: new SomeObject { Name = "Quinn"});
154+
}
155+
120156
public class SomeObject
121157
{
122158
public string Name { get; set; }

src/GraphQL/Types/GraphTypesLookup.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,25 @@ public void AddType(IGraphType type, TypeCollectionContext context)
224224
{
225225
var union = (UnionGraphType) type;
226226

227-
if (!union.Types.Any())
227+
if (!union.Types.Any() && !union.PossibleTypes.Any())
228228
{
229229
throw new ExecutionError("Must provide types for Union {0}.".ToFormat(union));
230230
}
231231

232+
union.PossibleTypes.Apply(unionedType =>
233+
{
234+
AddTypeIfNotRegistered(unionedType, context);
235+
236+
if (union.ResolveType == null && unionedType.IsTypeOf == null)
237+
{
238+
throw new ExecutionError((
239+
"Union type {0} does not provide a \"resolveType\" function" +
240+
"and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " +
241+
"There is no way to resolve this possible type during execution.")
242+
.ToFormat(union, unionedType));
243+
}
244+
});
245+
232246
union.Types.Apply(unionedType =>
233247
{
234248
AddTypeIfNotRegistered(unionedType, context);
@@ -256,11 +270,16 @@ private void HandleField(FieldType field, TypeCollectionContext context)
256270
AddTypeIfNotRegistered(field.Type, context);
257271
field.ResolvedType = BuildNamedType(field.Type, context.ResolveType);
258272
}
273+
else
274+
{
275+
AddTypeIfNotRegistered(field.ResolvedType, context);
276+
}
259277

260278
field.Arguments?.Apply(arg =>
261279
{
262280
if (arg.ResolvedType != null)
263281
{
282+
AddTypeIfNotRegistered(arg.ResolvedType, context);
264283
return;
265284
}
266285

@@ -278,5 +297,15 @@ private void AddTypeIfNotRegistered(Type type, TypeCollectionContext context)
278297
AddType(context.ResolveType(namedType), context);
279298
}
280299
}
300+
301+
private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context)
302+
{
303+
var namedType = type.GetNamedType().Name;
304+
var foundType = this[namedType];
305+
if(foundType == null)
306+
{
307+
AddType(type, context);
308+
}
309+
}
281310
}
282311
}

0 commit comments

Comments
 (0)