Skip to content

Commit

Permalink
Removed the schema resolver delegate (#5067)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed May 16, 2022
1 parent 8b623b6 commit 4d6db2e
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 109 deletions.
Expand Up @@ -93,6 +93,4 @@ public interface ITypeCompletionContext : ITypeSystemObjectContext
bool TryGetDirectiveType(
IDirectiveReference directiveRef,
[NotNullWhen(true)] out DirectiveType? directiveType);

Func<ISchema> GetSchemaResolver();
}
Expand Up @@ -14,7 +14,6 @@ namespace HotChocolate.Configuration;
internal sealed partial class RegisteredType : ITypeCompletionContext
{
private TypeReferenceResolver? _typeReferenceResolver;
private Func<ISchema>? _schemaResolver;

public TypeStatus Status { get; set; } = TypeStatus.Initialized;

Expand Down Expand Up @@ -43,12 +42,10 @@ IReadOnlyList<FieldMiddleware> ITypeCompletionContext.GlobalComponents

public void PrepareForCompletion(
TypeReferenceResolver typeReferenceResolver,
Func<ISchema> schemaResolver,
List<FieldMiddleware> globalComponents,
IsOfTypeFallback? isOfType)
{
_typeReferenceResolver = typeReferenceResolver;
_schemaResolver = schemaResolver;
GlobalComponents = globalComponents;
IsOfType = isOfType;
}
Expand Down Expand Up @@ -129,20 +126,4 @@ public ITypeReference GetNamedTypeReference(ITypeReference typeRef)

return _typeReferenceResolver.TryGetDirectiveType(directiveRef, out directiveType);
}

/// <inheritdoc />
public Func<ISchema> GetSchemaResolver()
{
if (_schemaResolver is null)
{
throw new InvalidOperationException(RegisteredType_Completion_NotYetReady);
}

if (Status == TypeStatus.Initialized)
{
throw new NotSupportedException();
}

return _schemaResolver;
}
}
Expand Up @@ -24,7 +24,6 @@ internal class TypeInitializer
private readonly TypeInterceptor _interceptor;
private readonly IsOfTypeFallback? _isOfType;
private readonly Func<TypeSystemObjectBase, RootTypeKind> _getTypeKind;
private readonly Func<ISchema> _schemaResolver;
private readonly IReadOnlySchemaOptions _options;
private readonly TypeRegistry _typeRegistry;
private readonly TypeLookup _typeLookup;
Expand All @@ -40,7 +39,6 @@ internal class TypeInitializer
IReadOnlyList<ITypeReference> initialTypes,
IsOfTypeFallback? isOfType,
Func<TypeSystemObjectBase, RootTypeKind> getTypeKind,
Func<ISchema> schemaResolver,
IReadOnlySchemaOptions options)
{
_context = descriptorContext ??
Expand All @@ -51,8 +49,6 @@ internal class TypeInitializer
throw new ArgumentNullException(nameof(initialTypes));
_getTypeKind = getTypeKind ??
throw new ArgumentNullException(nameof(getTypeKind));
_schemaResolver = schemaResolver ??
throw new ArgumentNullException(nameof(schemaResolver));
_options = options ??
throw new ArgumentNullException(nameof(options));

Expand Down Expand Up @@ -227,7 +223,6 @@ internal bool CompleteTypeName(RegisteredType registeredType)
{
registeredType.PrepareForCompletion(
_typeReferenceResolver,
_schemaResolver,
_globalComps,
_isOfType);

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/HotChocolate/Core/src/Types/Properties/TypeResources.resx
Expand Up @@ -858,4 +858,10 @@ Type: `{0}`</value>
<data name="ResolverContextExtensions_ContextData_KeyNotFound" xml:space="preserve">
<value>The specified key `{0}` does not exist on `context.ContextData`</value>
</data>
<data name="SchemaTypes_GetType_DoesNotExist" xml:space="preserve">
<value>The specified type `{0}` does not exist or is not of the specified kind `{1}`.</value>
</data>
<data name="SchemaTypes_DefinitionInvalid" xml:space="preserve">
<value>The schema types definition is in an invalid state.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/HotChocolate/Core/src/Types/Schema.cs
Expand Up @@ -122,7 +122,7 @@ public IReadOnlyList<ObjectType> GetPossibleTypes(INamedType abstractType)
throw new ArgumentNullException(nameof(abstractType));
}

if (_types.TryGetPossibleTypes(abstractType.Name, out IReadOnlyList<ObjectType> types))
if (_types.TryGetPossibleTypes(abstractType.Name, out IReadOnlyList<ObjectType>? types))
{
return types;
}
Expand Down
23 changes: 9 additions & 14 deletions src/HotChocolate/Core/src/Types/SchemaBuilder.Setup.cs
Expand Up @@ -65,8 +65,7 @@ public static Schema Create(SchemaBuilder builder)
IReadOnlyList<ITypeReference> typeReferences =
CreateTypeReferences(builder, context);

TypeRegistry typeRegistry =
InitializeTypes(builder, context, typeReferences, lazySchema);
TypeRegistry typeRegistry = InitializeTypes(builder, context, typeReferences);

return CompleteSchema(builder, context, lazySchema, typeRegistry);
}
Expand Down Expand Up @@ -127,7 +126,7 @@ public static Schema Create(SchemaBuilder builder)
{
var types = new List<ITypeReference>();
var documents = new List<DocumentNode>();
context.ContextData[WellKnownContextData.SchemaDocuments] = documents;
context.ContextData[WellKnownContextData.SchemaDocuments] = documents;

foreach (LoadSchemaDocument fetchSchema in builder._documents)
{
Expand Down Expand Up @@ -194,12 +193,11 @@ public static Schema Create(SchemaBuilder builder)
private static TypeRegistry InitializeTypes(
SchemaBuilder builder,
IDescriptorContext context,
IReadOnlyList<ITypeReference> types,
LazySchema lazySchema)
IReadOnlyList<ITypeReference> types)
{
var typeRegistry = new TypeRegistry(context.TypeInterceptor);
TypeInitializer initializer =
CreateTypeInitializer(builder, context, types, typeRegistry, lazySchema);
CreateTypeInitializer(builder, context, types, typeRegistry);
initializer.Initialize();
return typeRegistry;
}
Expand All @@ -208,8 +206,7 @@ public static Schema Create(SchemaBuilder builder)
SchemaBuilder builder,
IDescriptorContext context,
IReadOnlyList<ITypeReference> typeReferences,
TypeRegistry typeRegistry,
LazySchema lazySchema)
TypeRegistry typeRegistry)
{
var operations =
builder._operations.ToDictionary(
Expand All @@ -222,7 +219,6 @@ public static Schema Create(SchemaBuilder builder)
typeReferences,
builder._isOfType,
type => GetOperationKind(type, context.TypeInspector, operations),
() => lazySchema.Schema,
builder._options);

foreach (FieldMiddleware component in builder._globalComponents)
Expand Down Expand Up @@ -256,7 +252,7 @@ public static Schema Create(SchemaBuilder builder)
{
var serviceFactory = new ServiceFactory { Services = services };

foreach (object interceptorOrType in registered)
foreach (var interceptorOrType in registered)
{
if (interceptorOrType is Type type)
{
Expand Down Expand Up @@ -398,10 +394,9 @@ public static Schema Create(SchemaBuilder builder)
OperationType.Subscription,
builder._options.SubscriptionTypeName);

Dictionary<OperationType, ITypeReference> operations =
builder._operations.ToDictionary(
t => t.Key,
t => t.Value(context.TypeInspector));
var operations = builder._operations.ToDictionary(
static t => t.Key,
t => t.Value(context.TypeInspector));

ResolveOperations(definition, operations, typeRegistry);

Expand Down
39 changes: 24 additions & 15 deletions src/HotChocolate/Core/src/Types/SchemaTypes.cs
@@ -1,7 +1,11 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using HotChocolate.Types;
using static HotChocolate.Properties.TypeResources;

namespace HotChocolate;

Expand All @@ -17,38 +21,43 @@ public SchemaTypes(SchemaTypesDefinition definition)
throw new ArgumentNullException(nameof(definition));
}

if (definition.Types is null || definition.DirectiveTypes is null)
{
throw new ArgumentException(
SchemaTypes_DefinitionInvalid,
nameof(definition));
}

_types = definition.Types.ToDictionary(t => t.Name);
_possibleTypes = CreatePossibleTypeLookup(definition.Types);
QueryType = definition.QueryType;
QueryType = definition.QueryType!;
MutationType = definition.MutationType;
SubscriptionType = definition.SubscriptionType;
}

public ObjectType QueryType { get; }

public ObjectType MutationType { get; }
public ObjectType? MutationType { get; }

public ObjectType SubscriptionType { get; }
public ObjectType? SubscriptionType { get; }

public T GetType<T>(NameString typeName) where T : IType
{
if (_types.TryGetValue(typeName, out INamedType namedType)
if (_types.TryGetValue(typeName, out INamedType? namedType)
&& namedType is T type)
{
return type;
}

// TODO : resource
throw new ArgumentException(
$"The specified type `{typeName}` does not exist or " +
$"is not of the specified kind `{typeof(T).Name}`.",
string.Format(SchemaTypes_GetType_DoesNotExist, typeName, typeof(T).Name),
nameof(typeName));
}

public bool TryGetType<T>(NameString typeName, out T type)
public bool TryGetType<T>(NameString typeName, [NotNullWhen(true)] out T? type)
where T : IType
{
if (_types.TryGetValue(typeName, out INamedType namedType)
if (_types.TryGetValue(typeName, out INamedType? namedType)
&& namedType is T t)
{
type = t;
Expand All @@ -64,9 +73,9 @@ public IReadOnlyCollection<INamedType> GetTypes()
return _types.Values;
}

public bool TryGetClrType(NameString typeName, out Type clrType)
public bool TryGetClrType(NameString typeName, [NotNullWhen(true)] out Type? clrType)
{
if (_types.TryGetValue(typeName, out INamedType type)
if (_types.TryGetValue(typeName, out INamedType? type)
&& type is IHasRuntimeType ct
&& ct.RuntimeType != typeof(object))
{
Expand All @@ -80,9 +89,9 @@ public bool TryGetClrType(NameString typeName, out Type clrType)

public bool TryGetPossibleTypes(
string abstractTypeName,
out IReadOnlyList<ObjectType> types)
[NotNullWhen(true)] out IReadOnlyList<ObjectType>? types)
{
if (_possibleTypes.TryGetValue(abstractTypeName, out List<ObjectType> pt))
if (_possibleTypes.TryGetValue(abstractTypeName, out List<ObjectType>? pt))
{
types = pt;
return true;
Expand All @@ -103,7 +112,7 @@ public bool TryGetClrType(NameString typeName, out Type clrType)

foreach (InterfaceType interfaceType in objectType.Implements)
{
if (!possibleTypes.TryGetValue(interfaceType.Name, out List<ObjectType> pt))
if (!possibleTypes.TryGetValue(interfaceType.Name, out List<ObjectType>? pt))
{
pt = new List<ObjectType>();
possibleTypes[interfaceType.Name] = pt;
Expand All @@ -118,7 +127,7 @@ public bool TryGetClrType(NameString typeName, out Type clrType)
foreach (ObjectType objectType in unionType.Types.Values)
{
if (!possibleTypes.TryGetValue(
unionType.Name, out List<ObjectType> pt))
unionType.Name, out List<ObjectType>? pt))
{
pt = new List<ObjectType>();
possibleTypes[unionType.Name] = pt;
Expand Down
12 changes: 7 additions & 5 deletions src/HotChocolate/Core/src/Types/SchemaTypesDefinition.cs
@@ -1,14 +1,16 @@
#nullable enable

using System.Collections.Generic;
using HotChocolate.Types;

namespace HotChocolate;

internal sealed class SchemaTypesDefinition
{
public ObjectType QueryType { get; set; }
public ObjectType MutationType { get; set; }
public ObjectType SubscriptionType { get; set; }
public ObjectType? QueryType { get; set; }
public ObjectType? MutationType { get; set; }
public ObjectType? SubscriptionType { get; set; }

public IReadOnlyList<INamedType> Types { get; set; }
public IReadOnlyList<DirectiveType> DirectiveTypes { get; set; }
public IReadOnlyList<INamedType>? Types { get; set; }
public IReadOnlyList<DirectiveType>? DirectiveTypes { get; set; }
}
Expand Up @@ -62,6 +62,7 @@ public sealed class DescriptorContext : IDescriptorContext
void OnSchemaOnCompleted(object? sender, EventArgs args)
{
SchemaCompleted?.Invoke(this, new SchemaCompletedEventArgs(schema.Schema));
SchemaCompleted = null;
}
}

Expand Down
Expand Up @@ -16,6 +16,7 @@ public partial class InterfaceType
private InterfaceType[] _implements = Array.Empty<InterfaceType>();
private Action<IInterfaceTypeDescriptor>? _configure;
private ResolveAbstractType? _resolveAbstractType;
private ISchema _schema = default!;

protected override InterfaceTypeDefinition CreateDefinition(
ITypeDiscoveryContext context)
Expand Down Expand Up @@ -56,8 +57,9 @@ public partial class InterfaceType

SyntaxNode = definition.SyntaxNode;
Fields = OnCompleteFields(context, definition);
context.DescriptorContext.SchemaCompleted += (_, args) => _schema = args.Schema;

CompleteAbstractTypeResolver(context, definition.ResolveAbstractType);
CompleteAbstractTypeResolver(definition.ResolveAbstractType);
_implements = CompleteInterfaces(context, definition.GetInterfaces(), this);
}

Expand All @@ -70,24 +72,16 @@ static InterfaceField CreateField(InterfaceFieldDefinition fieldDef, int index)
=> new(fieldDef, index);
}

private void CompleteAbstractTypeResolver(
ITypeCompletionContext context,
ResolveAbstractType? resolveAbstractType)
private void CompleteAbstractTypeResolver(ResolveAbstractType? resolveAbstractType)
{
if (resolveAbstractType is null)
{
Func<ISchema> schemaResolver = context.GetSchemaResolver();

// if there is no custom type resolver we will use this default
// abstract type resolver.
IReadOnlyCollection<ObjectType>? types = null;
_resolveAbstractType = (c, r) =>
{
if (types is null)
{
ISchema schema = schemaResolver.Invoke();
types = schema.GetPossibleTypes(this);
}
types ??= _schema.GetPossibleTypes(this);
foreach (ObjectType type in types)
{
Expand Down

0 comments on commit 4d6db2e

Please sign in to comment.