Esempio n. 1
0
        /// <summary>
        /// Checks if the <see cref="IGraphType"/> is a Connection.
        /// </summary>
        /// <remarks>
        /// A <see cref="IGraphType"/> is considered a Connection if it either inherits from <see cref="ConnectionType{TNodeType,TEdgeType}"/> or has a <c>edges</c> field which has a <c>node</c> field.
        /// </remarks>
        /// <param name="graphType">The graph type to check.</param>
        /// <returns><c>true</c> if the <see cref="IGraphType"/> is a Connection, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="graphType"/> is <c>null</c>.</exception>
        public static bool IsConnectionType(this IGraphType graphType)
        {
            if (graphType == null)
            {
                throw new ArgumentNullException(nameof(graphType));
            }

            var type = graphType.GetType();

            var isConnection = type.ImplementsGenericType(typeof(ConnectionType <,>));

            if (isConnection)
            {
                return(true);
            }

            if (graphType is IComplexGraphType complexGraphType && complexGraphType.HasField("edges"))
            {
                if (complexGraphType.GetField("edges").ResolvedType.GetNamedType() is IComplexGraphType edgesType)
                {
                    return(edgesType.HasField("node"));
                }
            }

            return(false);
        }
Esempio n. 2
0
    static Type?ResolvedEntityType(IGraphType graphType)
    {
        var type = graphType.GetType();

        while (type != null)
        {
            if (type.IsGenericType)
            {
                var genericTypeDefinition = type.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(ComplexGraphType <>))
                {
                    return(type.GetGenericArguments().Single());
                }
                if (genericTypeDefinition == typeof(ConnectionType <>))
                {
                    var resolvedEntityType = type.GetGenericArguments().Single();
                    type = resolvedEntityType.BaseType;
                    continue;
                }
                if (genericTypeDefinition == typeof(ConnectionType <,>))
                {
                    var resolvedEntityType = type.GetGenericArguments().First();
                    type = resolvedEntityType.BaseType;
                    continue;
                }
            }
            type = type.BaseType;
        }

        return(null);
    }
Esempio n. 3
0
        public string PrintType(IGraphType type)
        {
            if (type is EnumerationGraphType)
            {
                return(PrintEnum((EnumerationGraphType)type));
            }

            if (type is ScalarGraphType)
            {
                return(PrintScalar((ScalarGraphType)type));
            }

            if (type is IObjectGraphType)
            {
                return(PrintObject((IObjectGraphType)type));
            }

            if (type is IInterfaceGraphType)
            {
                return(PrintInterface((IInterfaceGraphType)type));
            }

            if (type is UnionGraphType)
            {
                return(PrintUnion((UnionGraphType)type));
            }

            if (!(type is InputObjectGraphType))
            {
                throw new InvalidOperationException("Unknown GraphType {0}".ToFormat(type.GetType().Name));
            }

            return(PrintInputObject((InputObjectGraphType)type));
        }
Esempio n. 4
0
        private void SetGraphType(string typeName, IGraphType type)
        {
            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ArgumentOutOfRangeException(nameof(typeName), "A type name is required to lookup.");
            }

            if (_types.TryGetValue(typeName, out var existingGraphType))
            {
                if (ReferenceEquals(existingGraphType, type))
                {
                    // nothing to do
                }
                else if (existingGraphType.GetType() == type.GetType())
                {
                    _types[typeName] = type; // this case worked before overwriting the old value
                }
                else
                {
                    throw new InvalidOperationException($@"Unable to register GraphType '{type.GetType().FullName}' with the name '{typeName}';
the name '{typeName}' is already registered to '{existingGraphType.GetType().FullName}'.");
                }
            }
            else
            {
                _types.Add(typeName, type);
            }
        }
Esempio n. 5
0
 protected void AddFilterField(
     IGraphType field,
     IGraphType parentType,
     string name,
     string description,
     Func <IEnumerable <IFilter>, IFilter> resolveFilter)
 {
     Field(field.GetType(),
           name,
           description,
           resolve: context =>
     {
         var value      = (IEnumerable <object>)context.Source;
         var subFilters = new List <IFilter>();
         foreach (var obj in value)
         {
             var dict = (IDictionary <string, object>)obj;
             foreach (KeyValuePair <string, object> pair in dict)
             {
                 subFilters.Add(this.ResolveFilter(pair, context));
             }
         }
         return(resolveFilter(subFilters));
     }).ResolvedType = field;
 }
Esempio n. 6
0
 private IGraphType CacheType(GraphTypeInfo typeInfo, IGraphType graphType)
 {
     //string:StringGraphType
     _typeDescriptors.AddEntity(typeInfo.TypeRepresentation.AsType(), WrapNonNullableType(typeInfo, graphType));
     //StringGraphType:StringGraphType
     _typeDescriptors.AddEntity(graphType.GetType(), graphType);
     return(graphType);
 }
Esempio n. 7
0
        /// <summary>
        /// if a variable defintion has a default value, it is effectively non-null.
        /// </summary>
        private GraphType effectiveType(IGraphType varType, VariableDefinition varDef)
        {
            if (varDef.DefaultValue == null || varType is NonNullGraphType)
            {
                return((GraphType)varType);
            }

            var type        = varType.GetType();
            var genericType = typeof(NonNullGraphType <>).MakeGenericType(type);

            return((GraphType)Activator.CreateInstance(genericType));
        }
Esempio n. 8
0
 public string PrintType(IGraphType type)
 {
     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}'")
     });
Esempio n. 9
0
        protected void AddFilterField(
            IGraphType field,
            FieldType fieldType,
            IGraphType parentType,
            string name,
            string description,
            Func <Func <object, object>, object, IFilter> resolveFilter)
        {
            Field(field.GetType(),
                  name,
                  description,
                  deprecationReason: fieldType.DeprecationReason,
                  resolve: context =>
            {
                object ResolveValue(object source)
                {
                    var path  = (context.Path ?? new [] { "filter" }).Concat(new[] { fieldType.Name });
                    var value = fieldType.Resolver.Resolve(
                        new ResolveFieldContext
                    {
                        FieldName         = fieldType.Name,
                        FieldAst          = new Field(null, new NameNode(fieldType.Name)),
                        FieldDefinition   = fieldType,
                        ParentType        = (IObjectGraphType)parentType,
                        Source            = source,
                        Schema            = context.Schema,
                        Document          = context.Document,
                        Fragments         = context.Fragments,
                        RootValue         = context.RootValue,
                        UserContext       = context.UserContext,
                        Operation         = context.Operation,
                        Variables         = context.Variables,
                        CancellationToken = context.CancellationToken,
                        Metrics           = context.Metrics,
                        Errors            = context.Errors,
                        Path = path
                    }
                        );

                    if (value is Task <object> task)
                    {
                        return(task.Result);
                    }

                    return(value);
                }

                return(resolveFilter(ResolveValue, context.Source));
            }).ResolvedType = field;
        }
        private Type GetModelType(IGraphType type)
        {
            var args = type.GetType().GetGenericArguments();

            if (args.Length == 1)
            {
                args = args[0].GetGenericArguments();
                if (args.Length == 1)
                {
                    return(args[0]);
                }
            }

            return(null);
        }
    static Type ResolvedEntityType(IGraphType graphType)
    {
        var type = graphType.GetType();

        while (type.BaseType != null)
        {
            type = type.BaseType;
            if (type.IsGenericType &&
                type.GetGenericTypeDefinition() == typeof(ComplexGraphType <>))
            {
                return(type.GetGenericArguments().Single());
            }
        }

        return(null);
    }
Esempio n. 12
0
        private                                        QueryArgument[] CreateQueryArguments(Type entityType, bool onlyStructural)
        {
            PropertyInfo[] properties = entityType.GetProperties();
            if (onlyStructural)
            {
                properties = properties.Where(p => p.PropertyType.IsValueType || p.PropertyType == typeof(String)).ToArray();
            }

            var queryArguments = new List <QueryArgument>(properties.Length);

            for (int i = 0; i < properties.Length; i++)
            {
                QueryArgument queryArgument;
                var           entityGraphType = (IObjectGraphType)_clrTypeToObjectGraphType[entityType];
                FieldType     fieldType       = entityGraphType.Fields.SingleOrDefault(f => f.Name == properties[i].Name);
                if (fieldType != null)
                {
                    if (fieldType.Type == null)
                    {
                        IGraphType resolvedType = fieldType.ResolvedType;
                        if (resolvedType is NonNullGraphType nonNullGraphType)
                        {
                            resolvedType = nonNullGraphType.ResolvedType;
                        }
                        queryArgument = new QueryArgument(resolvedType.GetType())
                        {
                            ResolvedType = resolvedType
                        };
                    }
                    else
                    {
                        if (fieldType.Type.IsGenericType && typeof(NonNullGraphType).IsAssignableFrom(fieldType.Type))
                        {
                            queryArgument = new QueryArgument(fieldType.Type.GetGenericArguments()[0]);
                        }
                        else
                        {
                            queryArgument = new QueryArgument(fieldType.Type);
                        }
                    }
                    queryArgument.Name = NameFirstCharLower(properties[i].Name);
                    queryArguments.Add(queryArgument);
                }
            }
            return(queryArguments.ToArray());
        }
Esempio n. 13
0
        // https://github.com/graphql-dotnet/graphql-dotnet/pull/1010
        private void AddTypeWithLoopCheck(IGraphType resolvedType, TypeCollectionContext context, Type namedType)
        {
            if (context.InFlightRegisteredTypes.Any(t => t == namedType))
            {
                throw new InvalidOperationException($@"A loop has been detected while registering schema types.
There was an attempt to re-register '{namedType.FullName}' with instance of '{resolvedType.GetType().FullName}'.
Make sure that your ServiceProvider is configured correctly.");
            }

            context.InFlightRegisteredTypes.Push(namedType);
            try
            {
                AddType(resolvedType, context);
            }
            finally
            {
                context.InFlightRegisteredTypes.Pop();
            }
        }
Esempio n. 14
0
        private IEnumerable <Change> ChangesInType(IGraphType oldType, IGraphType newType)
        {
            List <Change> changes = new List <Change>();

            if (oldType.GetType() != newType.GetType())
            {
                changes.Add(new TypeKindChanged(oldType, newType));
            }
            else
            {
                if (oldType.GetType() == typeof(EnumerationGraphType))
                {
                    changes.AddRange(new model.Diff.EnumType((EnumerationGraphType)oldType, (EnumerationGraphType)newType).Diff());
                }
                else if (oldType.GetType() == typeof(ObjectGraphType))
                {
                    changes.AddRange(new model.Diff.ObjectType((ObjectGraphType)oldType, (ObjectGraphType)newType).Diff());
                }
                else if (oldType.GetType() == typeof(InputObjectGraphType))
                {
                    changes.AddRange(new model.Diff.InputObjectType((InputObjectGraphType)oldType, (InputObjectGraphType)newType).Diff());
                }
                else if (oldType.GetType() == typeof(UnionGraphType))
                {
                    changes.AddRange(new model.Diff.UnionObjectType((UnionGraphType)oldType, (UnionGraphType)newType).Diff());
                }
                else if (oldType.GetType() == typeof(InterfaceGraphType))
                {
                    changes.AddRange(new model.Diff.InterfacesType((InterfaceGraphType)oldType, (InterfaceGraphType)newType).Diff());
                }
            }


            if (!IsTypeDescriptionEqual(oldType, newType))
            {
                changes.Add(new TypeDescriptionChanged(oldType, newType));
            }

            return(changes);
        }
Esempio n. 15
0
        public string PrintType(IGraphType type)
        {
            if (type is EnumerationGraphType graphType)
            {
                return(PrintEnum(graphType));
            }

            if (type is ScalarGraphType scalarGraphType)
            {
                return(PrintScalar(scalarGraphType));
            }

            if (type is IObjectGraphType objectGraphType)
            {
                return(PrintObject(objectGraphType));
            }

            if (type is IInterfaceGraphType interfaceGraphType)
            {
                return(PrintInterface(interfaceGraphType));
            }

            if (type is UnionGraphType unionGraphType)
            {
                return(PrintUnion(unionGraphType));
            }

            if (type is DirectiveGraphType directiveGraphType)
            {
                return(PrintDirective(directiveGraphType));
            }

            if (!(type is IInputObjectGraphType))
            {
                throw new InvalidOperationException("Unknown GraphType {0}".ToFormat(type.GetType().Name));
            }

            return(PrintInputObject((IInputObjectGraphType)type));
        }
        protected void AddFilterField(
            IGraphType field,
            IGraphType parentType,
            string name,
            string description,
            Func <IEnumerable <IFilter>, IFilter> resolveFilter)
        {
            Field(field.GetType(),
                  name,
                  description,
                  resolve: context =>
            {
                var executionContext = new ExecutionContext
                {
                    Schema            = context.Schema,
                    CancellationToken = context.CancellationToken,
                    Document          = context.Document,
                    Errors            = context.Errors,
                    Fragments         = context.Fragments,
                    Metrics           = context.Metrics,
                    Operation         = context.Operation,
                    RootValue         = context.RootValue,
                    UserContext       = context.UserContext,
                    Variables         = context.Variables
                };

                var value      = (IEnumerable <object>)context.Source;
                var subFilters = new List <IFilter>();
                foreach (var obj in value)
                {
                    var dict = (IDictionary <string, object>)obj;
                    foreach (KeyValuePair <string, object> pair in dict)
                    {
                        subFilters.Add(this.ResolveFilter(pair, (IObjectGraphType)parentType, executionContext));
                    }
                }
                return(resolveFilter(subFilters));
            }).ResolvedType = field;
        }
Esempio n. 17
0
        private Type OverrideForScalarList(IGraphType graphType)
        {
            var graphTypeType = graphType.GetType();

            if (!graphTypeType.IsGenericFor(typeof(ListGraphType <>)))
            {
                return(null);
            }

            var namedElemType = graphTypeType.GetNamedType();

            if (namedElemType == null)
            {
                return(null);
            }

            if (typeof(ScalarGraphType).IsAssignableFrom(namedElemType))
            {
                return(graphTypeType);
            }

            return(null);
        }
Esempio n. 18
0
        /// <summary>
        /// Generates a new color of the same tone as the basecolor of the given type
        /// </summary>
        public System.Windows.Media.Color NewColor(IGraphType type)
        {
            System.Drawing.Color newColor;
            // Get basecolor of the type
            var baseColorWpf = typeColors[Types.IndexOf(Types.Single(t => t.Model.GetType() == type.GetType()))];
            var baseColor    = System.Drawing.Color.FromArgb(baseColorWpf.R, baseColorWpf.G, baseColorWpf.B);

            var h = baseColor.GetHue();

            var random = new Random();

            do
            {
                // Generate new color by using the hue of the basecolor and getting a random brightness and saturation.
                newColor = HslHelper.HslToRgb(h, random.NextDouble(), random.NextDouble());
            } while (!IsInInterval(0.5, newColor.GetSaturation(), 0.3) || !IsInInterval(0.5, newColor.GetBrightness(), 0.3) || Graphs.Any(g => SimilarColor(Color.FromArgb(g.LineColor.R, g.LineColor.G, g.LineColor.B), newColor)));

            return(System.Windows.Media.Color.FromRgb(newColor.R, newColor.G, newColor.B));
        }
Esempio n. 19
0
 private IGraphType WrapNonNullableType(GraphTypeInfo typeInfo, IGraphType graphType) =>
 typeInfo.IsNullable
         ? graphType
         : CreateTypeInstance <GraphType>(typeof(NonNullGraphType <>).MakeGenericType(graphType.GetType()));
Esempio n. 20
0
 public static void ShouldBeOfNonNullableListType <TType>(this IGraphType type)
     where TType : GraphType
 {
     Assert.AreEqual(typeof(NonNullGraphType <ListGraphType <TType> >), type.GetType());
 }
Esempio n. 21
0
 public static void ShouldBeOfListType <TType>(this IGraphType type)
     where TType : GraphType
 {
     Assert.AreEqual(typeof(ListGraphType <TType>), type.GetType());
 }
Esempio n. 22
0
 protected override string GetMessage()
 {
     return($"`{oldType.Name}` kind changed from `{oldType.GetType().Name}` to `{newType.GetType().Name}`");
 }
Esempio n. 23
0
        public void AddType(IGraphType type, TypeCollectionContext context)
        {
            CheckSealed();

            if (type == null || type is GraphQLTypeReference)
            {
                return;
            }

            if (type is NonNullGraphType || type is ListGraphType)
            {
                throw new ExecutionError("Only add root types.");
            }

            var name = type.CollectTypes(context).TrimGraphQLTypes();

            lock (_lock)
            {
                SetGraphType(name, type);
            }

            if (type is IComplexGraphType complexType)
            {
                foreach (var field in complexType.Fields)
                {
                    HandleField(type.GetType(), field, context);
                }
            }

            if (type is IObjectGraphType obj)
            {
                foreach (var objectInterface in obj.Interfaces)
                {
                    AddTypeIfNotRegistered(objectInterface, context);

                    if (this[objectInterface] is IInterfaceGraphType interfaceInstance)
                    {
                        obj.AddResolvedInterface(interfaceInstance);
                        interfaceInstance.AddPossibleType(obj);

                        if (interfaceInstance.ResolveType == null && obj.IsTypeOf == null)
                        {
                            throw new ExecutionError((
                                                         "Interface type {0} does not provide a \"resolveType\" function " +
                                                         "and possible Type \"{1}\" does not provide a \"isTypeOf\" function.  " +
                                                         "There is no way to resolve this possible type during execution.")
                                                     .ToFormat(interfaceInstance.Name, obj.Name));
                        }
                    }
                }
            }

            if (type is UnionGraphType union)
            {
                if (!union.Types.Any() && !union.PossibleTypes.Any())
                {
                    throw new ExecutionError("Must provide types for Union {0}.".ToFormat(union));
                }

                foreach (var unionedType in union.PossibleTypes)
                {
                    AddTypeIfNotRegistered(unionedType, context);

                    if (union.ResolveType == null && unionedType.IsTypeOf == null)
                    {
                        throw new ExecutionError((
                                                     "Union type {0} does not provide a \"resolveType\" function " +
                                                     "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " +
                                                     "There is no way to resolve this possible type during execution.")
                                                 .ToFormat(union.Name, unionedType.Name));
                    }
                }

                foreach (var unionedType in union.Types)
                {
                    AddTypeIfNotRegistered(unionedType, context);

                    var objType = this[unionedType] as IObjectGraphType;

                    if (union.ResolveType == null && objType != null && objType.IsTypeOf == null)
                    {
                        throw new ExecutionError((
                                                     "Union type {0} does not provide a \"resolveType\" function " +
                                                     "and possible Type \"{1}\" does not provide a \"isTypeOf\" function. " +
                                                     "There is no way to resolve this possible type during execution.")
                                                 .ToFormat(union.Name, objType.Name));
                    }

                    union.AddPossibleType(objType);
                }
            }
        }
Esempio n. 24
0
        public void AddType(IGraphType type, TypeCollectionContext context)
        {
            if (type == null)
            {
                return;
            }

            if (type is NonNullGraphType || type is ListGraphType)
            {
                throw new ExecutionError("Only add root types.");
            }

            var name = type.CollectTypes(context).TrimGraphQLTypes();

            lock (_lock)
            {
                _types[name] = type;
            }

            if (type is IComplexGraphType)
            {
                var complexType = type as IComplexGraphType;
                complexType.Fields.Apply(field =>
                {
                    HandleField(type.GetType(), field, context);
                });
            }

            if (type is IObjectGraphType)
            {
                var obj = (IObjectGraphType)type;
                obj.Interfaces.Apply(objectInterface =>
                {
                    AddTypeIfNotRegistered(objectInterface, context);

                    var interfaceInstance = this[objectInterface] as IInterfaceGraphType;
                    if (interfaceInstance != null)
                    {
                        obj.AddResolvedInterface(interfaceInstance);
                        interfaceInstance.AddPossibleType(obj);

                        if (interfaceInstance.ResolveType == null && obj.IsTypeOf == null)
                        {
                            throw new ExecutionError((
                                                         "Interface type {0} does not provide a \"resolveType\" function " +
                                                         "and possible Type \"{1}\" does not provide a \"isTypeOf\" function.  " +
                                                         "There is no way to resolve this possible type during execution.")
                                                     .ToFormat(interfaceInstance, obj));
                        }
                    }
                });
            }

            if (type is UnionGraphType)
            {
                var union = (UnionGraphType)type;

                if (!union.Types.Any() && !union.PossibleTypes.Any())
                {
                    throw new ExecutionError("Must provide types for Union {0}.".ToFormat(union));
                }

                union.PossibleTypes.Apply(unionedType =>
                {
                    AddTypeIfNotRegistered(unionedType, context);

                    if (union.ResolveType == null && unionedType.IsTypeOf == null)
                    {
                        throw new ExecutionError((
                                                     "Union type {0} does not provide a \"resolveType\" function" +
                                                     "and possible Type \"{1}\" does not provide a \"isTypeOf\" function.  " +
                                                     "There is no way to resolve this possible type during execution.")
                                                 .ToFormat(union, unionedType));
                    }
                });

                union.Types.Apply(unionedType =>
                {
                    AddTypeIfNotRegistered(unionedType, context);

                    var objType = this[unionedType] as IObjectGraphType;

                    if (union.ResolveType == null && objType != null && objType.IsTypeOf == null)
                    {
                        throw new ExecutionError((
                                                     "Union type {0} does not provide a \"resolveType\" function" +
                                                     "and possible Type \"{1}\" does not provide a \"isTypeOf\" function.  " +
                                                     "There is no way to resolve this possible type during execution.")
                                                 .ToFormat(union, objType));
                    }

                    union.AddPossibleType(objType);
                });
            }
        }
 private static Type GetEntityTypeFromResolvedType(IGraphType resolvedType)
 {
     return(resolvedType.GetType().GetGenericArguments()[0]);
 }
        /// <summary>
        /// if a variable defintion has a default value, it is effectively non-null.
        /// </summary>
        private GraphType effectiveType(IGraphType varType, VariableDefinition varDef)
        {
            if (varDef.DefaultValue == null || varType is NonNullGraphType)
            {
                return (GraphType)varType;
            }

            var type = varType.GetType();
            var genericType = typeof(NonNullGraphType<>).MakeGenericType(type);

            var nonNull = (NonNullGraphType)Activator.CreateInstance(genericType);
            nonNull.ResolvedType = varType;
            return nonNull;
        }
        private                                        QueryArgument[] CreateQueryArguments(Type entityType, bool onlyStructural)
        {
            PropertyInfo[] properties = entityType.GetProperties();
            if (onlyStructural)
            {
                properties = properties.Where(p => p.PropertyType.IsValueType || p.PropertyType == typeof(String)).ToArray();
            }

            var queryArguments = new List <QueryArgument>(properties.Length);

            for (int i = 0; i < properties.Length; i++)
            {
                QueryArgument queryArgument;
                var           entityGraphType = (IObjectGraphType)_clrTypeToObjectGraphType[entityType];
                FieldType?    fieldType       = entityGraphType.Fields.SingleOrDefault(f => f.Name == properties[i].Name);
                if (fieldType != null)
                {
                    if (fieldType.Type == null)
                    {
                        String            name;
                        IGraphType        resolvedType     = fieldType.ResolvedType;
                        IComplexGraphType?complexGraphType = null;
                        if (resolvedType is NonNullGraphType nonNullGraphType)
                        {
                            resolvedType     = nonNullGraphType.ResolvedType;
                            name             = resolvedType.Name;
                            complexGraphType = resolvedType as IComplexGraphType;
                        }
                        else if (resolvedType is ListGraphType listGraphType)
                        {
                            name             = listGraphType.ResolvedType.Name;
                            complexGraphType = listGraphType.ResolvedType as IComplexGraphType;
                        }
                        else
                        {
                            name             = resolvedType.Name;
                            complexGraphType = resolvedType as IComplexGraphType;
                        }

                        if (complexGraphType == null)
                        {
                            continue;
                        }

                        Type inputObjectGraphType = typeof(InputObjectGraphType <>).MakeGenericType(resolvedType.GetType());
                        var  inputObjectGraph     = (IInputObjectGraphType)Activator.CreateInstance(inputObjectGraphType) !;
                        inputObjectGraph.Description = name;
                        foreach (FieldType typeField in complexGraphType.Fields)
                        {
                            if (typeField.ResolvedType == null || typeField.ResolvedType.IsInputType())
                            {
                                inputObjectGraph.AddField(typeField);
                            }
                        }

                        queryArgument = new QueryArgument(inputObjectGraphType)
                        {
                            Name = name, ResolvedType = inputObjectGraph
                        };
                    }
                    else
                    {
                        if (fieldType.Type.IsGenericType && typeof(NonNullGraphType).IsAssignableFrom(fieldType.Type))
                        {
                            queryArgument = new QueryArgument(fieldType.Type.GetGenericArguments()[0]);
                        }
                        else
                        {
                            queryArgument = new QueryArgument(fieldType.Type);
                        }
                    }
                    queryArgument.Name = NameFirstCharLower(properties[i].Name);
                    queryArguments.Add(queryArgument);
                }
            }
            return(queryArguments.ToArray());
        }
Esempio n. 28
0
        public static ArgumentValue CoerceValue(IGraphType type, IValue?input, Variables?variables = null, object?fieldDefault = null)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (type is NonNullGraphType nonNull)
            {
                // validation rules have verified that this is not null; if the validation rule was not executed, it
                // is assumed that the caller does not wish this check to be executed
                return(CoerceValue(nonNull.ResolvedType !, input, variables, fieldDefault));
            }

            if (input == null)
            {
                return(new ArgumentValue(fieldDefault, ArgumentSource.FieldDefault));
            }

            if (input is VariableReference variable)
            {
                if (variables == null)
                {
                    return(new ArgumentValue(fieldDefault, ArgumentSource.FieldDefault));
                }

                var found = variables.ValueFor(variable.Name, out var ret);
                return(found ? ret : new ArgumentValue(fieldDefault, ArgumentSource.FieldDefault));
            }

            if (type is ScalarGraphType scalarType)
            {
                return(new ArgumentValue(scalarType.ParseLiteral(input), ArgumentSource.Literal));
            }

            if (input is NullValue)
            {
                return(ArgumentValue.NullLiteral);
            }

            if (type is ListGraphType listType)
            {
                var listItemType = listType.ResolvedType !;

                if (input is ListValue list)
                {
                    var count = list.ValuesList.Count;
                    if (count == 0)
                    {
                        return(new ArgumentValue(Array.Empty <object>(), ArgumentSource.Literal));
                    }

                    var values = new object?[count];
                    for (int i = 0; i < count; ++i)
                    {
                        values[i] = CoerceValue(listItemType, list.ValuesList[i], variables).Value;
                    }
                    return(new ArgumentValue(values, ArgumentSource.Literal));
                }
                else
                {
                    return(new ArgumentValue(new[] { CoerceValue(listItemType, input, variables).Value }, ArgumentSource.Literal));
                }
            }

            if (type is IInputObjectGraphType inputObjectGraphType)
            {
                if (!(input is ObjectValue objectValue))
                {
                    throw new ArgumentOutOfRangeException(nameof(input), $"Expected object value for '{inputObjectGraphType.Name}', found not an object '{input}'.");
                }

                var obj = new Dictionary <string, object?>();

                foreach (var field in inputObjectGraphType.Fields.List)
                {
                    // https://spec.graphql.org/June2018/#sec-Input-Objects
                    var objectField = objectValue.Field(field.Name);
                    if (objectField != null)
                    {
                        // Rules covered:

                        // If a literal value is provided for an input object field, an entry in the coerced unordered map is
                        // given the result of coercing that value according to the input coercion rules for the type of that field.

                        // If a variable is provided for an input object field, the runtime value of that variable must be used.
                        // If the runtime value is null and the field type is non‐null, a field error must be thrown.
                        // If no runtime value is provided, the variable definition’s default value should be used.
                        // If the variable definition does not provide a default value, the input object field definition’s
                        // default value should be used.

                        // so: do not pass the field's default value to this method, since the field was specified
                        obj[field.Name] = CoerceValue(field.ResolvedType !, objectField.Value, variables).Value;
                    }
                    else if (field.DefaultValue != null)
                    {
                        // If no value is provided for a defined input object field and that field definition provides a default value,
                        // the default value should be used.
                        obj[field.Name] = field.DefaultValue;
                    }
                    // Otherwise, if the field is not required, then no entry is added to the coerced unordered map.

                    // Covered by validation rules:
                    // If no default value is provided and the input object field’s type is non‐null, an error should be
                    // thrown.
                }

                return(new ArgumentValue(inputObjectGraphType.ParseDictionary(obj), ArgumentSource.Literal));
            }

            throw new ArgumentOutOfRangeException(nameof(input), $"Unknown type of input object '{type.GetType()}'");
        }