public FieldType AddSingleField <TReturn>( IObjectGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, object>, IQueryable <TReturn> > resolve, Func <ResolveEfFieldContext <TDbContext, object>, TReturn, Task>?mutate = null, Type?graphType = null, IEnumerable <QueryArgument>?arguments = null, bool nullable = false, string?description = null) where TReturn : class { var field = BuildSingleField(name, resolve, mutate, arguments, graphType, nullable, description); return(graph.AddField(field)); }
public static ExecutionNode BuildExecutionNode(ExecutionNode parent, IGraphType graphType, Field field, FieldType fieldDefinition, int?indexInParentNode = null) { if (graphType is NonNullGraphType nonNullFieldType) { graphType = nonNullFieldType.ResolvedType; } return(graphType switch { ListGraphType _ => new ArrayExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode), IObjectGraphType _ => new ObjectExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode), IAbstractGraphType _ => new ObjectExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode), ScalarGraphType _ => new ValueExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode), _ => throw new InvalidOperationException($"Unexpected type: {graphType}") });
/// <summary> /// Builds an execution node with the specified parameters. /// </summary> protected ExecutionNode BuildSubscriptionExecutionNode(ExecutionNode parent, IGraphType graphType, Field field, FieldType fieldDefinition, int?indexInParentNode, object source) { if (graphType is NonNullGraphType nonNullFieldType) { graphType = nonNullFieldType.ResolvedType; } return(graphType switch { ListGraphType _ => new SubscriptionArrayExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode, source), IObjectGraphType _ => new SubscriptionObjectExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode, source), IAbstractGraphType _ => new SubscriptionObjectExecutionNode(parent, graphType, field, fieldDefinition, indexInParentNode, source), ScalarGraphType scalarGraphType => new SubscriptionValueExecutionNode(parent, scalarGraphType, field, fieldDefinition, indexInParentNode, source), _ => throw new InvalidOperationException($"Unexpected type: {graphType}") });
public override void VisitObjectFieldDefinition(FieldType field, IObjectGraphType type, ISchema schema) { var applied = field.FindAppliedDirective("upper"); if (applied != null) { var inner = field.Resolver ?? NameFieldResolver.Instance; field.Resolver = new FuncFieldResolver <object>(async context => { object result = await inner.ResolveAsync(context).ConfigureAwait(false); return(result is string str ? str.ToUpperInvariant() : result); }); } }
public string PrintType(IGraphType type) { Schema?.Initialize(); return(type switch { EnumerationGraphType graphType => PrintEnum(graphType), ScalarGraphType scalarGraphType => PrintScalar(scalarGraphType), IObjectGraphType objectGraphType => PrintObject(objectGraphType), IInterfaceGraphType interfaceGraphType => PrintInterface(interfaceGraphType), UnionGraphType unionGraphType => PrintUnion(unionGraphType), DirectiveGraphType directiveGraphType => PrintDirective(directiveGraphType), //TODO: DirectiveGraphType does not inherit IGraphType IInputObjectGraphType input => PrintInputObject(input), _ => throw new InvalidOperationException($"Unknown GraphType '{type.GetType().Name}' with name '{type.Name}'") });
public override string PrintObject(IObjectGraphType type) { var isExtension = type.IsExtensionType(); var interfaces = type.ResolvedInterfaces.Select(x => x.Name).ToList(); var delimiter = " & "; var implementedInterfaces = interfaces.Count > 0 ? " implements {0}".ToFormat(string.Join(delimiter, interfaces)) : ""; var federatedDirectives = PrintFederatedDirectives(type); var extended = isExtension ? "extend " : ""; return(FormatDescription(type.Description) + "{1}type {2}{3}{4} {{{0}{5}{0}}}".ToFormat(Environment.NewLine, extended, type.Name, implementedInterfaces, federatedDirectives, PrintFields(type))); }
public static void AddFieldToQuery <TFrom, TTo>( this IGraphQLQueryResolver resolver, IObjectGraphType query, string name, string methodName) where TFrom : ObjectGraphType <TTo> { (query as ObjectGraphType) .FieldAsync <ListGraphType <TFrom> >( name, arguments: resolver.GetQueryArguments(methodName), resolve: async context => { return(await resolver.InvokeAsync <IEnumerable <TTo> >(context, methodName)); }); }
public static void Field( this IObjectGraphType obj, string name, IGraphType type, string description = null, QueryArguments arguments = null, Func <ResolveFieldContext, object> resolve = null) { var field = new FieldType(); field.Name = name; field.Description = description; field.Arguments = arguments; field.ResolvedType = type; field.Resolver = resolve != null ? new FuncFieldResolver <object>(resolve) : null; obj.AddField(field); }
public static ExecutionNode BuildExecutionNode(ExecutionNode parent, IGraphType graphType, Field field, FieldType fieldDefinition, string[] path = null) { path ??= AppendPath(parent.Path, field.Name); if (graphType is NonNullGraphType nonNullFieldType) { graphType = nonNullFieldType.ResolvedType; } return(graphType switch { ListGraphType _ => new ArrayExecutionNode(parent, graphType, field, fieldDefinition, path), IObjectGraphType _ => new ObjectExecutionNode(parent, graphType, field, fieldDefinition, path), IAbstractGraphType _ => new ObjectExecutionNode(parent, graphType, field, fieldDefinition, path), ScalarGraphType _ => new ValueExecutionNode(parent, graphType, field, fieldDefinition, path), _ => throw new InvalidOperationException($"Unexpected type: {graphType}") });
public FieldType GetFieldDefinition(ISchema schema, IObjectGraphType parentType, Field field) { if (field.Name == SchemaIntrospection.SchemaMeta.Name && schema.Query == parentType) { return(SchemaIntrospection.SchemaMeta); } if (field.Name == SchemaIntrospection.TypeMeta.Name && schema.Query == parentType) { return(SchemaIntrospection.TypeMeta); } if (field.Name == SchemaIntrospection.TypeNameMeta.Name) { return(SchemaIntrospection.TypeNameMeta); } return(parentType.Fields.FirstOrDefault(f => f.Name == field.Name)); }
public override void VisitObjectFieldDefinition(FieldType field, IObjectGraphType type, ISchema schema) { var applied = field.FindAppliedDirective(AuthorizeDirective.DirectiveName); if (applied == null) { return; } var isAuthenticated = _contextAccessor.HttpContext?.User.Identity?.IsAuthenticated; if (isAuthenticated == true) { return; } field.Resolver = new AsyncFieldResolver <object>(async context => { throw new NotAuthenticatedException(); }); }
public override void VisitObjectFieldDefinition(FieldType field, IObjectGraphType type, ISchema schema) { var applied = field.FindAppliedDirective("upper"); if (applied != null) { var inner = field.Resolver ?? NameFieldResolver.Instance; field.Resolver = new FuncFieldResolver <object>(context => { object result = inner.Resolve(context); return(result switch { string str => str?.ToUpperInvariant(), Task <string> task => Task.FromResult(task.GetAwaiter().GetResult()?.ToUpperInvariant()), _ => result }); });
public static void FieldAsync( this IObjectGraphType obj, string name, IGraphType type, string description = null, QueryArguments arguments = null, Func <IResolveFieldContext, Task <object> > resolve = null) { var field = new FieldType { Name = name, Description = description, Arguments = arguments, ResolvedType = type, Resolver = resolve != null ? new AsyncFieldResolver <object>(resolve) : null }; obj.AddField(field); }
/// <summary> /// Iterates the given <see cref="ControllerActionGraphFieldTemplate" /> and adds /// all found types to the type system for this <see cref="ISchema" />. Generates /// a field reference on the provided parent with a resolver pointing to the provided graph action. /// </summary> /// <param name="parentType">The parent which will own the generated action field.</param> /// <param name="action">The action.</param> private void AddActionAsField(IObjectGraphType parentType, IGraphTypeFieldTemplate action) { // apend the action as a field on the parent var maker = GraphQLProviders.GraphTypeMakerProvider.CreateFieldMaker(this.Schema); var fieldResult = maker.CreateField(action); if (fieldResult != null) { if (parentType.Fields.ContainsKey(fieldResult.Field.Name)) { throw new GraphTypeDeclarationException( $"The '{parentType.Kind}' graph type '{parentType.Name}' already contains a field named '{fieldResult.Field.Name}'. " + $"The action method '{action.InternalFullName}' cannot be added to the graph type with the same name."); } parentType.Extend(fieldResult.Field); this.EnsureDependents(fieldResult); } }
/// <summary> /// Adds a field with the specified properties to a specified output graph type. /// </summary> /// <param name="obj">The graph type to add a field to.</param> /// <param name="name">The name of the field.</param> /// <param name="type">The graph type of this field.</param> /// <param name="description">The description of the field.</param> /// <param name="arguments">A list of arguments for the field.</param> /// <param name="resolve">A field resolver delegate. If not specified, <see cref="NameFieldResolver"/> will be used.</param> public static void Field( //TODO: v5 - change void to T where T : IObjectGraphType this IObjectGraphType obj, string name, IGraphType type, string description = null, QueryArguments arguments = null, Func <IResolveFieldContext, object> resolve = null) { var field = new FieldType { Name = name, Description = description, Arguments = arguments, ResolvedType = type, Resolver = resolve != null ? new FuncFieldResolver <object>(resolve) : null }; obj.AddField(field); }
public void AddQueryConnectionField <TSource, TReturn>( IObjectGraphType graph, string name, Func <ResolveEfFieldContext <TDbContext, TSource>, IQueryable <TReturn> > resolve, Type?itemGraphType = null, IEnumerable <QueryArgument>?arguments = null, int pageSize = 10, string?description = null) where TReturn : class { Guard.AgainstNull(nameof(graph), graph); Guard.AgainstNull(nameof(resolve), resolve); var connection = BuildQueryConnectionField(name, resolve, pageSize, itemGraphType, description); var field = graph.AddField(connection.FieldType); field.AddWhereArgument(arguments); }
public static FieldType FieldAsync <TGraphType, TSourceType>( this IObjectGraphType obj, string name, string description = null, QueryArguments arguments = null, Func <ResolveFieldContext <TSourceType>, Task <object> > resolve = null, string deprecationReason = null) where TGraphType : IGraphType { return(obj.AddField(new FieldType { Name = name, Description = description, DeprecationReason = deprecationReason, Type = typeof(TGraphType), Arguments = arguments, Resolver = resolve != null ? new AsyncFieldResolver <TSourceType, object>(resolve) : null, })); }
public override void VisitObjectFieldDefinition(FieldType field, IObjectGraphType type, ISchema schema) { var permission = field.GetAppliedPermission(); if (permission == null) { return; } var isAuthorized = _contextAccessor .HttpContext ?.User .HasClaim(x => x.Type == "Permission" && x.Value == permission); if (isAuthorized == true) { return; } field.Resolver = new AsyncFieldResolver <object>(async context => throw new NotAuthorizedException()); }
/// <inheritdoc/> public override void VisitObjectFieldDefinition(FieldType field, IObjectGraphType type, ISchema schema) { // 2.2 if (field.Name.StartsWith("__")) { throw new InvalidOperationException($"The field '{field.Name}' of an Object type '{type.Name}' must not have a name which begins with the __ (two underscores)."); } if (field.ResolvedType == null) { throw new InvalidOperationException($"The field '{field.Name}' of an Object type '{type.Name}' must have non-null '{nameof(IFieldType.ResolvedType)}' property."); } // 2.3 if (!field.ResolvedType.IsOutputType()) { throw new InvalidOperationException($"The field '{field.Name}' of an Object type '{type.Name}' must be an output type."); } ValidateArgumentsUniqueness(field, type); }
/// <summary> /// Ensures the object graph type is tracked against all its implemented interfaces and queued /// to be added to the interfaces it declares that are not known to this instance. /// </summary> /// <param name="objectGraphType">The object graph type to watch.</param> private void EnsureObjectTypeIsTracked(IObjectGraphType objectGraphType) { _allKnownTypes.Add(objectGraphType); foreach (var interfaceName in objectGraphType.InterfaceNames) { if (_interfacesByName.TryGetValue(interfaceName, out var interfaceType)) { _graphTypesByInterface[interfaceType].Add(objectGraphType); this.ApplyAllFields(interfaceType, objectGraphType); } else { if (!_queuedTypesByInterfaceName.TryGetValue(interfaceName, out var _)) { _queuedTypesByInterfaceName.TryAdd(interfaceName, new HashSet <IObjectGraphType>()); } _queuedTypesByInterfaceName[interfaceName].Add(objectGraphType); } } }
public override string PrintObject(IObjectGraphType type) { // Do not return an empty query type: "Query { }" as it is not valid as part of the sdl. if (type != null && string.Equals(type.Name, "Query", StringComparison.Ordinal) && !type.Fields.Any(x => !IsFederatedType(x.ResolvedType.GetNamedType().Name))) { return(string.Empty); } var isExtension = type.IsExtensionType(); var interfaces = type.ResolvedInterfaces.List.Select(x => x.Name).ToList(); var delimiter = " & "; var implementedInterfaces = interfaces.Count > 0 ? " implements {0}".ToFormat(string.Join(delimiter, interfaces)) : ""; var federatedDirectives = PrintFederatedDirectives(type); var extended = isExtension ? "extend " : ""; return(FormatDescription(type.Description) + "{1}type {2}{3}{4} {{{0}{5}{0}}}".ToFormat(Environment.NewLine, extended, type.Name, implementedInterfaces, federatedDirectives, PrintFields(type))); }
/// <summary> /// Performs an out-of-band append of a new graph field to a parent. Accounts for type updates in this schema ONLY. /// </summary> /// <param name="parentType">the parent type to add the new field to.</param> /// <param name="fieldName">Name of the field.</param> /// <param name="path">The path segment to represent the new field.</param> /// <param name="definition">The definition item from which graph attributes should be used, if any. Attributes will be set to an empty string if not supplied.</param> /// <returns>The type associated with the field added to the parent type.</returns> private IObjectGraphType CreateVirtualFieldOnParent( IObjectGraphType parentType, string fieldName, GraphFieldPath path, IGraphItemTemplate definition = null) { var childField = new VirtualGraphField( fieldName, path, this.MakeSafeTypeNameFromRoutePath(path)) { IsDepreciated = false, DepreciationReason = string.Empty, Description = definition?.Description ?? string.Empty, }; parentType.Extend(childField); this.Schema.KnownTypes.EnsureGraphType(childField.AssociatedGraphType); this.EnsureDependents(childField); return(childField.AssociatedGraphType); }
/// <summary> /// Returns a <see cref="FieldType"/> for the specified AST <see cref="Field"/> within a specified parent /// output graph type within a given schema. For meta-fields, returns the proper meta-field field type. /// </summary> public static FieldType GetFieldDefinition(ISchema schema, IObjectGraphType parentType, Field field) { if (field.Name == schema.SchemaMetaFieldType.Name && schema.Query == parentType) { return(schema.SchemaMetaFieldType); } if (field.Name == schema.TypeMetaFieldType.Name && schema.Query == parentType) { return(schema.TypeMetaFieldType); } if (field.Name == schema.TypeNameMetaFieldType.Name) { return(schema.TypeNameMetaFieldType); } if (parentType == null) { throw new ArgumentNullException(nameof(parentType), $"Schema is not configured correctly to fetch field '{field.Name}'. Are you missing a root type?"); } return(parentType.GetField(field.Name)); }
/// <summary> /// Generates the list of used end-types /// </summary> /// <param name="providers">The list of defined api providers</param> /// <param name="types">The list of merged types</param> /// <param name="nodeInterface">The node interface (for relay compliance)</param> /// <param name="allInterfaces">The list of defined type interfaces</param> /// <param name="api">The api root element</param> /// <param name="mutationType">The type containing all mutation methods</param> /// <returns>The list of defined types</returns> private static Dictionary <string, IGraphType> GenerateApiTypes( List <ApiProvider> providers, List <MergedType> types, NodeInterface nodeInterface, Dictionary <string, IGraphType> allInterfaces, MergedApiRoot api, out IObjectGraphType mutationType) { var graphTypes = types.ToDictionary( type => type.ComplexTypeName, type => type.GenerateGraphType(nodeInterface, GetTypeInterfaces(type, providers, allInterfaces))); mutationType = api.GenerateMutationType(); graphTypes[mutationType.Name] = mutationType; graphTypes.Values.OfType <IComplexGraphType>().SelectMany(a => a.Fields).ForEach( f => { var fieldDescription = f.GetMetadata <MergedField>(MergedType.MetaDataTypeKey); if (fieldDescription == null) { return; } SetFieldArguments(f, fieldDescription, graphTypes); f.ResolvedType = GetTypeForField(fieldDescription, graphTypes); if (f.Resolver == null) { f.Resolver = fieldDescription.Resolver ?? fieldDescription.Type; } if (!string.IsNullOrWhiteSpace(fieldDescription.Description)) { f.Description = fieldDescription.Description; } }); return(graphTypes); }
public GraphQLModel(IAppEntity app, IEnumerable <ISchemaEntity> schemas, int pageSizeContents, int pageSizeAssets, IUrlGenerator urlGenerator) { partitionResolver = app.PartitionResolver(); CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl; assetType = new AssetGraphType(this); assetListType = new ListGraphType(new NonNullGraphType(assetType)); var allSchemas = schemas.Where(x => x.SchemaDef.IsPublished).ToList(); BuildSchemas(allSchemas); graphQLSchema = BuildSchema(this, pageSizeContents, pageSizeAssets, allSchemas); graphQLSchema.RegisterValueConverter(JsonConverter.Instance); graphQLSchema.RegisterValueConverter(InstantConverter.Instance); InitializeContentTypes(); }
// See 'Type Validation' section in https://spec.graphql.org/June2018/#sec-Objects // Object types have the potential to be invalid if incorrectly defined. // This set of rules must be adhered to by every Object type in a GraphQL schema. /// <inheritdoc/> public override void VisitObject(IObjectGraphType type, ISchema schema) { // 1 if (type.Fields.Count == 0) { throw new InvalidOperationException($"An Object type '{type.Name}' must define one or more fields."); } // 2.1 foreach (var item in type.Fields.List.ToLookup(f => f.Name)) { if (item.Count() > 1) { throw new InvalidOperationException($"The field '{item.Key}' must have a unique name within Object type '{type.Name}'; no two fields may share the same name."); } } // 3 // TODO: ? An object type may declare that it implements one or more unique interfaces. // 4 // TODO: An object type must be a superāset of all interfaces it implements }
private async Task ExtractFieldAsync(ExecutionContext context, IObjectGraphType rootType, object source, Field field, FieldType fieldType, ConcurrentDictionary <string, object> data, IEnumerable <string> path) { context.CancellationToken.ThrowIfCancellationRequested(); var name = field.Alias ?? field.Name; if (data.ContainsKey(name)) { return; } if (!ShouldIncludeNode(context, field.Directives)) { return; } if (CanResolveFromData(field, fieldType)) { var result = await ResolveFieldFromDataAsync(context, rootType, source, fieldType, field, path) .ConfigureAwait(false); data.TryAdd(name, result); } else { var result = await ResolveFieldAsync(context, rootType, source, field, path) .ConfigureAwait(false); if (result.Skip) { return; } data.TryAdd(name, result.Value); } }
public async Task <IActionResult> Post([FromBody] GraphQlQuery query) { IObjectGraphType currentObjectGraphType = null; switch (query.OperationName) { case "GetBlogData": currentObjectGraphType = new BlogQuery(blogService); break; case "GetAuthors": currentObjectGraphType = new AuthorsQuery(blogService); break; default: currentObjectGraphType = new BlogQuery(blogService); break; } var schema = new Schema { Query = currentObjectGraphType }; var result = await new DocumentExecuter().ExecuteAsync(x => { x.Schema = schema; x.Query = query.Query; x.Inputs = query.Variables; }); if (result.Errors?.Count > 0) { return(BadRequest()); } return(Ok(result)); }
/// <summary> /// Inspects the root and ensures that any intermediate, virtual fields /// are accounted for and returns a reference to the immediate parent this action should be added to. /// </summary> /// <param name="action">The action.</param> /// <returns>IGraphField.</returns> private IObjectGraphType AddOrRetrieveRoutePath(IGraphTypeFieldTemplate action) { var pathSegments = action.Route.GenerateParentPathSegments(); // loop through all parent path parts of this action // creating virtual fields as necessary or using existing ones and adding on to them IObjectGraphType parentType = this.Schema.OperationTypes[action.Route.RootCollection]; for (var i = 0; i < pathSegments.Count; i++) { var segment = pathSegments[i]; var formattedName = _formatter.FormatFieldName(segment.Name); if (parentType.Fields.ContainsKey(formattedName)) { var field = parentType[formattedName]; var foundType = Schema.KnownTypes.FindGraphType(field.TypeExpression.TypeName); if (foundType is IObjectGraphType ogt) { parentType = ogt; continue; } throw new GraphTypeDeclarationException( $"The action '{action.Name}' attempted to nest itself under the grpah type '{foundType?.Name}' but the graph type " + "does not exist or does not accept fields."); } var fieldType = this.CreateVirtualFieldOnParent( parentType, formattedName, segment, i == 0 ? action.Parent : null); parentType = fieldType; } return(parentType); }
public FieldType GetFieldDefinition(Document document, ISchema schema, IObjectGraphType parentType, Field field) { if (field.Name == SchemaIntrospection.SchemaMeta.Name && schema.Query == parentType) { return(SchemaIntrospection.SchemaMeta); } if (field.Name == SchemaIntrospection.TypeMeta.Name && schema.Query == parentType) { return(SchemaIntrospection.TypeMeta); } if (field.Name == SchemaIntrospection.TypeNameMeta.Name) { return(SchemaIntrospection.TypeNameMeta); } if (parentType == null) { var error = new ExecutionError($"Schema is not configured correctly to fetch {field.Name}. Are you missing a root type?"); error.AddLocation(field, document); throw error; } return(parentType.Fields.FirstOrDefault(f => f.Name == field.Name)); }
public FieldType GetFieldDefinition(ISchema schema, IObjectGraphType parentType, Field field) { if (field.Name == SchemaIntrospection.SchemaMeta.Name && schema.Query == parentType) { return SchemaIntrospection.SchemaMeta; } if (field.Name == SchemaIntrospection.TypeMeta.Name && schema.Query == parentType) { return SchemaIntrospection.TypeMeta; } if (field.Name == SchemaIntrospection.TypeNameMeta.Name) { return SchemaIntrospection.TypeNameMeta; } return parentType.Fields.FirstOrDefault(f => f.Name == field.Name); }
public async Task<ResolveFieldResult<object>> ResolveFieldAsync(ExecutionContext context, IObjectGraphType parentType, object source, Fields fields) { context.CancellationToken.ThrowIfCancellationRequested(); var resolveResult = new ResolveFieldResult<object> { Skip = false }; var field = fields.First(); var fieldDefinition = GetFieldDefinition(context.Schema, parentType, field); if (fieldDefinition == null) { resolveResult.Skip = true; return resolveResult; } var arguments = GetArgumentValues(context.Schema, fieldDefinition.Arguments, field.Arguments, context.Variables); try { var resolveContext = new ResolveFieldContext(); resolveContext.FieldName = field.Name; resolveContext.FieldAst = field; resolveContext.FieldDefinition = fieldDefinition; resolveContext.ReturnType = fieldDefinition.ResolvedType; resolveContext.ParentType = parentType; resolveContext.Arguments = arguments; resolveContext.Source = source; resolveContext.Schema = context.Schema; resolveContext.Document = context.Document; resolveContext.Fragments = context.Fragments; resolveContext.RootValue = context.RootValue; resolveContext.UserContext = context.UserContext; resolveContext.Operation = context.Operation; resolveContext.Variables = context.Variables; resolveContext.CancellationToken = context.CancellationToken; resolveContext.Metrics = context.Metrics; var resolver = fieldDefinition.Resolver ?? new NameFieldResolver(); var result = resolver.Resolve(resolveContext); if (result is Task) { var task = result as Task; await task.ConfigureAwait(false); result = task.GetProperyValue("Result"); } resolveResult.Value = await CompleteValueAsync(context, fieldDefinition.ResolvedType, fields, result).ConfigureAwait(false); return resolveResult; } catch (Exception exc) { var error = new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc); error.AddLocation(field, context.Document); context.Errors.Add(error); resolveResult.Skip = false; return resolveResult; } }
public Task<Dictionary<string, object>> ExecuteFieldsAsync(ExecutionContext context, IObjectGraphType rootType, object source, Dictionary<string, Fields> fields) { return fields.ToDictionaryAsync<KeyValuePair<string, Fields>, string, ResolveFieldResult<object>, object>( pair => pair.Key, pair => ResolveFieldAsync(context, rootType, source, pair.Value)); }