/// <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); }
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); }
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)); }
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); } }
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; }
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); }
/// <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)); }
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}'") });
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); }
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()); }
// 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(); } }
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); }
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; }
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); }
/// <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)); }
private IGraphType WrapNonNullableType(GraphTypeInfo typeInfo, IGraphType graphType) => typeInfo.IsNullable ? graphType : CreateTypeInstance <GraphType>(typeof(NonNullGraphType <>).MakeGenericType(graphType.GetType()));
public static void ShouldBeOfNonNullableListType <TType>(this IGraphType type) where TType : GraphType { Assert.AreEqual(typeof(NonNullGraphType <ListGraphType <TType> >), type.GetType()); }
public static void ShouldBeOfListType <TType>(this IGraphType type) where TType : GraphType { Assert.AreEqual(typeof(ListGraphType <TType>), type.GetType()); }
protected override string GetMessage() { return($"`{oldType.Name}` kind changed from `{oldType.GetType().Name}` to `{newType.GetType().Name}`"); }
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); } } }
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()); }
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()}'"); }