// https://graphql.github.io/graphql-spec/June2018/#sec-Input-and-Output-Types
        public static bool IsInputType(this IGraphType type)
        {
            var namedType = type.GetNamedType();

            return(namedType is ScalarGraphType ||
                   namedType is IInputObjectGraphType);
        }
        public static bool IsInputType(this IGraphType type, ISchema schema)
        {
            var namedType = type.GetNamedType(schema);

            return(namedType is ScalarGraphType ||
                   namedType is EnumerationGraphType ||
                   namedType is InputObjectGraphType);
        }
Esempio n. 3
0
        // https://graphql.github.io/graphql-spec/June2018/#sec-Input-and-Output-Types
        public static bool IsInputType(this IGraphType type)
        {
            var namedType = type.GetNamedType();

            return(namedType is ScalarGraphType ||
                   namedType is EnumerationGraphType || // EnumerationGraphType inherits ScalarGraphType, but for clarity let it be here
                   namedType is IInputObjectGraphType);
        }
        // https://graphql.github.io/graphql-spec/June2018/#sec-Input-and-Output-Types
        public static bool IsOutputType(this IGraphType type)
        {
            var namedType = type.GetNamedType();

            return(namedType is ScalarGraphType ||
                   namedType is IObjectGraphType ||
                   namedType is IInterfaceGraphType ||
                   namedType is UnionGraphType);
        }
Esempio n. 5
0
        private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context)
        {
            var namedType = type.GetNamedType();
            var foundType = this[namedType.Name];

            if (foundType == null)
            {
                AddType(namedType, context);
            }
        }
Esempio n. 6
0
        public Result IGraphQLTypeIsValidForSchema(IGraphType type, ISchema schema)
        {
            var namedType = type.GetNamedType();

            if (namedType.IsSupportedScalarGraphType())
            {
                return(Results.Ok());
            }

            var csType = GetType(namedType.GetName());

            if (csType != null)
            {
                return(TypeIsValidForSchema(csType, schema));
            }
            return(Results.Fail($"Type {namedType.GetName()} can't be found as a C# type."));
        }
        private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context)
        {
            var namedType = type.GetNamedType();

            // TODO: kapiris additions - need PR!

            /*
             * if (string.IsNullOrEmpty(namedType.Name))
             * {
             *  namedType.Name = namedType.CollectTypes(context);
             * }
             */

            var foundType = this[namedType.Name];

            if (foundType == null)
            {
                AddType(namedType, context);
            }
        }
        public static bool IsLeafType(this IGraphType type)
        {
            var namedType = type.GetNamedType();

            return(namedType is ScalarGraphType || namedType is EnumerationGraphType);
        }
        /// <summary>
        /// Creates a new instance of the indicated type, populating it with the dictionary.
        /// Can use any constructor of the indicated type, provided that there are keys in the
        /// dictionary that correspond (case sensitive) to the names of the constructor parameters.
        /// </summary>
        /// <param name="source">The source of values.</param>
        /// <param name="type">The type to create.</param>
        /// <param name="mappedType">
        /// GraphType for matching dictionary keys with <paramref name="type"/> property names.
        /// GraphType contains information about this matching in Metadata property.
        /// In case of configuring field as Field(x => x.FName).Name("FirstName") source dictionary
        /// will have 'FirstName' key but its value should be set to 'FName' property of created object.
        /// </param>
        public static object ToObject(this IDictionary <string, object> source, Type type, IGraphType mappedType = null)
        {
            // Given Field(x => x.FName).Name("FirstName") and key == "FirstName" returns "FName"
            string GetPropertyName(string key, out FieldType field)
            {
                var complexType = mappedType.GetNamedType() as IComplexGraphType;

                // type may not contain mapping information
                field = complexType?.GetField(key);
                return(field?.GetMetadata(ComplexGraphType <object> .ORIGINAL_EXPRESSION_PROPERTY_NAME, key) ?? key);
            }

            // Returns keys from source that match constructor signature
            string[] MatchSourceKeys(ParameterInfo[] parameters)
            {
                // parameterless constructors are the most common use case
                if (parameters.Length == 0)
                {
                    return(Array.Empty <string>());
                }

                // otherwise we have to iterate over the parameters - worse performance but this is rather rare case
                List <string> keys = null;

                if (parameters.All(p => source.Any(keyValue =>
                {
                    bool matched = string.Equals(GetPropertyName(keyValue.Key, out var _), p.Name, StringComparison.InvariantCultureIgnoreCase);
                    if (matched)
                    {
                        (keys ??= new List <string>()).Add(keyValue.Key);
                    }
                    return(matched);
                })))
                {
                    return(keys.ToArray());
                }

                return(null);
            }

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            // force sourceType to be IDictionary<string, object>
            if (ValueConverter.TryConvertTo(source, type, out object result, typeof(IDictionary <string, object>)))
            {
                return(result);
            }

            // attempt to use the most specific constructor sorting in decreasing order of parameters number
            var ctorCandidates = _types.GetOrAdd(type, t => t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderByDescending(ctor => ctor.GetParameters().Length).ToArray());

            ConstructorInfo targetCtor = null;

            ParameterInfo[] ctorParameters = null;
            string[]        matchedKeys    = null;

            foreach (var ctor in ctorCandidates)
            {
                var parameters = ctor.GetParameters();
                matchedKeys = MatchSourceKeys(parameters);
                if (matchedKeys != null)
                {
                    targetCtor     = ctor;
                    ctorParameters = parameters;
                    break;
                }
            }

            if (targetCtor == null)
            {
                throw new ArgumentException($"Type '{type}' does not contain a constructor that could be used for current input arguments.", nameof(type));
            }

            object[] ctorArguments = ctorParameters.Length == 0 ? Array.Empty <object>() : new object[ctorParameters.Length];

            for (int i = 0; i < ctorParameters.Length; ++i)
            {
                object arg = GetPropertyValue(source[matchedKeys[i]], ctorParameters[i].ParameterType);
                ctorArguments[i] = arg;
            }

            object obj = targetCtor.Invoke(ctorArguments);

            foreach (var item in source)
            {
                // these parameters have already been used in the constructor, no need to set property
                if (matchedKeys.Length > 0 && matchedKeys.Any(k => k == item.Key))
                {
                    continue;
                }

                string       propertyName = GetPropertyName(item.Key, out var field);
                PropertyInfo propertyInfo = null;

                try
                {
                    propertyInfo = type.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                }
                catch (AmbiguousMatchException)
                {
                    propertyInfo = type.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
                }

                if (propertyInfo != null && propertyInfo.CanWrite)
                {
                    object value = GetPropertyValue(item.Value, propertyInfo.PropertyType, field?.ResolvedType);
                    propertyInfo.SetValue(obj, value, null); //issue: this works even if propertyInfo is ValueType and value is null
                }
            }

            return(obj);
        }
Esempio n. 10
0
 private static bool IsEnumType(IGraphType type)
 {
     return(type.GetNamedType() is EnumerationGraphType);
 }