// 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); }
// 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); }
private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context) { var namedType = type.GetNamedType(); var foundType = this[namedType.Name]; if (foundType == null) { AddType(namedType, context); } }
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); }
private static bool IsEnumType(IGraphType type) { return(type.GetNamedType() is EnumerationGraphType); }