Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ChilliCream/graphql-platform
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 11.2.0
Choose a base ref
...
head repository: ChilliCream/graphql-platform
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 11.2.1
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 20, 2021

  1. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    Mic92 Jörg Thalheim
    Copy the full SHA
    002da3a View commit details
  2. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    Mic92 Jörg Thalheim
    Copy the full SHA
    20ce7d9 View commit details
15 changes: 6 additions & 9 deletions src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs
Original file line number Diff line number Diff line change
@@ -525,15 +525,12 @@ private void CompileResolvers()
RegisteredResolver registered = item.Value;
if (registered.Field is FieldMember member)
{
ResolverDescriptor descriptor =
registered.IsSourceResolver
? new ResolverDescriptor(
registered.SourceType,
member)
: new ResolverDescriptor(
registered.ResolverType,
registered.SourceType,
member);
ResolverDescriptor descriptor = new(
registered.SourceType,
member,
resolverType: registered.IsSourceResolver
? null
: registered.ResolverType);
_resolvers[item.Key] = registered.WithField(
ResolverCompiler.Resolve.Compile(descriptor));
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
using System;

#nullable enable

namespace HotChocolate.Resolvers.Expressions
{
/// <summary>
/// Describes a resolver that is based on a resolver type.
/// </summary>
internal class ResolverDescriptor
{
/// <summary>
/// Creates a new instance of <see cref="ResolverType"/>
/// </summary>
public ResolverDescriptor(
Type resolverType,
Type sourceType,
FieldMember field)
FieldMember field,
Type? resolverType = null)
{
ResolverType = resolverType
?? throw new ArgumentNullException(nameof(resolverType));
SourceType = sourceType
?? throw new ArgumentNullException(nameof(sourceType));
Field = field
?? throw new ArgumentNullException(nameof(field));
}

public ResolverDescriptor(
Type sourceType,
FieldMember field)
{
SourceType = sourceType
?? throw new ArgumentNullException(nameof(sourceType));
Field = field
?? throw new ArgumentNullException(nameof(field));
ResolverType = resolverType == typeof(object) ? null : resolverType;
}

public Type ResolverType { get; }
/// <summary>
/// Gets the resolver type.
/// If a resolver type is the <see cref="Field"/> belongs to this type.
/// </summary>
public Type? ResolverType { get; }

/// <summary>
/// Gets the source type aka runtime type of a GraphQL type.
/// </summary>
public Type SourceType { get; }

/// <summary>
/// Gets the member that shall be compiled to a resolver.
/// </summary>
public FieldMember Field { get; }
}
}
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ public override Type RuntimeType
public bool IsExtension { get; set; }

public IList<ITypeReference> Interfaces =>
_interfaces ??=new List<ITypeReference>();
_interfaces ??= new List<ITypeReference>();

public IBindableList<ObjectFieldDefinition> Fields { get; } =
new BindableList<ObjectFieldDefinition>();
@@ -168,14 +168,14 @@ protected internal void MergeInto(ObjectTypeDefinition target)

if (removeField)
{
if(targetField is not null)
if (targetField is not null)
{
target.Fields.Remove(targetField);
}
}
else if (targetField is null || replaceField)
{
if(targetField is not null)
if (targetField is not null)
{
target.Fields.Remove(targetField);
}
@@ -184,21 +184,33 @@ protected internal void MergeInto(ObjectTypeDefinition target)
field.CopyTo(newField);
newField.SourceType = target.RuntimeType;

if (newField.Member is not null && newField.ResolverMember is null)
{
newField.ResolverMember = newField.Member;
newField.Member = targetField?.Member;
}
SetResolverMember(newField, targetField);

target.Fields.Add(newField);
}
else
{
SetResolverMember(field, targetField);
field.MergeInto(targetField);
}
}

target.IsOfType ??= IsOfType;
}

private static void SetResolverMember(
ObjectFieldDefinition sourceField,
ObjectFieldDefinition? targetField)
{
// we prepare the field that is merged in to use the resolver member instead of member.
// this will ensure that the original source type member is preserved after we have
// merged the type extensions.

if (sourceField.Member is not null && sourceField.ResolverMember is null)
{
sourceField.ResolverMember = sourceField.Member;
sourceField.Member = targetField?.Member;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -69,9 +69,9 @@ public IObjectFieldDescriptor ResolveNodeWith<TResolver>(
FieldResolver resolver =
ResolverCompiler.Resolve.Compile(
new ResolverDescriptor(
typeof(TResolver),
typeof(object),
new FieldMember("_", "_", m)));
new FieldMember("_", "_", m),
resolverType: typeof(TResolver)));
return ResolveNode(resolver.Resolver);
}

@@ -90,9 +90,9 @@ public IObjectFieldDescriptor ResolveNodeWith(MethodInfo method)
FieldResolver resolver =
ResolverCompiler.Resolve.Compile(
new ResolverDescriptor(
method.DeclaringType ?? typeof(object),
typeof(object),
new FieldMember("_", "_", method)));
new FieldMember("_", "_", method),
resolverType: method.DeclaringType ?? typeof(object)));

return ResolveNode(resolver.Resolver);
}
Original file line number Diff line number Diff line change
@@ -71,9 +71,9 @@ public IObjectFieldDescriptor ResolveNodeWith<TResolver>(
FieldResolver resolver =
ResolverCompiler.Resolve.Compile(
new ResolverDescriptor(
typeof(TResolver),
typeof(object),
new FieldMember("_", "_", m)));
new FieldMember("_", "_", m),
resolverType: typeof(TResolver)));
return ResolveNode(resolver.Resolver);
}

@@ -93,9 +93,9 @@ public IObjectFieldDescriptor ResolveNodeWith(
FieldResolver resolver =
ResolverCompiler.Resolve.Compile(
new ResolverDescriptor(
method.DeclaringType ?? typeof(object),
typeof(object),
new FieldMember("_", "_", method)));
new FieldMember("_", "_", method),
resolverType: method.DeclaringType ?? typeof(object)));
return ResolveNode(resolver.Resolver);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Linq;
using HotChocolate.Resolvers.Expressions;
using Xunit;

namespace HotChocolate.Resolvers
{
public class ResolverDescriptorTests
{
[Fact]
public void Create_With_ResolverType_Object()
{
var descriptor = new ResolverDescriptor(
typeof(string),
new FieldMember("a", "b", typeof(object).GetMembers().First()),
resolverType: typeof(object));

Assert.Equal(typeof(string), descriptor.SourceType);
Assert.Null(descriptor.ResolverType);
Assert.NotNull(descriptor.Field.Member);
Assert.Equal("a", descriptor.Field.TypeName.Value);
Assert.Equal("b", descriptor.Field.FieldName.Value);
}

[Fact]
public void Create_With_ResolverType_Null()
{
var descriptor = new ResolverDescriptor(
typeof(string),
new FieldMember("a", "b", typeof(object).GetMembers().First()));

Assert.Equal(typeof(string), descriptor.SourceType);
Assert.Null(descriptor.ResolverType);
Assert.NotNull(descriptor.Field.Member);
Assert.Equal("a", descriptor.Field.TypeName.Value);
Assert.Equal("b", descriptor.Field.FieldName.Value);
}

[Fact]
public void Create_With_ResolverType_Int()
{
var descriptor = new ResolverDescriptor(
typeof(string),
new FieldMember("a", "b", typeof(object).GetMembers().First()),
resolverType: typeof(int));

Assert.Equal(typeof(string), descriptor.SourceType);
Assert.Equal(typeof(int), descriptor.ResolverType);
Assert.NotNull(descriptor.Field.Member);
Assert.Equal("a", descriptor.Field.TypeName.Value);
Assert.Equal("b", descriptor.Field.FieldName.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -265,9 +265,9 @@ public async Task Compile_TaskObjMethod_NoParams_Resolver()
Type type = typeof(Resolvers);
MemberInfo resolverMember = type.GetMethod(nameof(Resolvers.ObjectTaskResolver));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -287,9 +287,9 @@ public async Task Compile_TaskStringMethod_NoParams_Resolver()
Type type = typeof(Resolvers);
MemberInfo resolverMember = type.GetMethod(nameof(Resolvers.StringTaskResolver));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -310,9 +310,9 @@ public async Task Compile_TaskStringMethod_WithParams_Resolver()
MemberInfo resolverMember =
type.GetMethod(nameof(Resolvers.StringTaskResolverWithArg));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -333,9 +333,9 @@ public async Task Compile_ObjMethod_NoParams_Resolver()
Type type = typeof(Resolvers);
MemberInfo resolverMember = type.GetMethod(nameof(Resolvers.ObjectResolver));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -355,9 +355,9 @@ public async Task Compile_StringMethod_NoParams_Resolver()
Type type = typeof(Resolvers);
MemberInfo resolverMember = type.GetMethod(nameof(Resolvers.StringResolver));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
type);

// act
var compiler = new ResolveCompiler();
@@ -378,9 +378,9 @@ public async Task Compile_StringMethod_WithParams_Resolver()
MemberInfo resolverMember =
type.GetMethod(nameof(Resolvers.StringResolverWithArg));
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
type);

// act
var compiler = new ResolveCompiler();
@@ -402,9 +402,9 @@ public async Task Compile_ObjTaskProperty_Resolver()
MemberInfo resolverMember =
type.GetProperty("ObjectTaskStringProp");
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -425,9 +425,9 @@ public async Task Compile_StringTaskProperty_Resolver()
MemberInfo resolverMember =
type.GetProperty("StringTaskResolverProp");
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
@@ -448,9 +448,9 @@ public async Task Compile_StringProperty_Resolver()
MemberInfo resolverMember =
type.GetProperty("StringProp");
var resolverDescriptor = new ResolverDescriptor(
type,
typeof(Entity),
new FieldMember("A", "b", resolverMember!));
new FieldMember("A", "b", resolverMember!),
resolverType: type);

// act
var compiler = new ResolveCompiler();
Original file line number Diff line number Diff line change
@@ -588,6 +588,20 @@ public async Task Replace_Field_With_The_Same_Name_Execute()
.MatchSnapshotAsync();
}

[Fact]
public async Task Extended_Field_Overwrites_Extended_Field()
{
Snapshot.FullName();

await new ServiceCollection()
.AddGraphQL()
.AddQueryType()
.AddTypeExtension<ExtensionA>()
.AddTypeExtension<ExtensionB>()
.ExecuteRequestAsync("{ foo }")
.MatchSnapshotAsync();
}

public class FooType
: ObjectType<Foo>
{
@@ -843,5 +857,17 @@ public class Replace_Field_PersonResolvers_2
public string SomeId([Parent] IPersonDto dto, string arg = "abc") =>
dto.SomeId() + arg;
}

[ExtendObjectType(OperationTypeNames.Query)]
public class ExtensionA
{
public string Foo() => "abc";
}

[ExtendObjectType(OperationTypeNames.Query)]
public class ExtensionB
{
public string Foo() => "def";
}
}
}
Loading