private void CollectGraphTypes(HashSet <string> exists, List <IGraphType> graphTypes, IGraphType graphType) { if (graphType.OtherTypes.Any()) { graphTypes.Add(graphType); exists.Add(graphType.Name); CollectGraphTypes(exists, graphTypes, _graphTypeProvider.GetGraphType(graphType.Type, false, false)); foreach (var type in graphType.OtherTypes) { CollectGraphTypes(exists, graphTypes, _graphTypeProvider.GetGraphType(type, false, false)); } } if (!graphType.Fields.Any()) { return; } var graphTypeName = (!graphType.IsRequired && !graphType.IsEnumerable) ? graphType.Name : GraphValueResolver.GetGraphTypeName(graphType.Type); if (exists.Contains(graphTypeName)) { return; } graphTypes.Add(_graphTypeProvider.TryGetGraphType(graphTypeName, out var value)? value: graphType); exists.Add(graphTypeName); foreach (var field in graphType.Fields.Values) { CollectGraphTypes(exists, graphTypes, field.GraphType); } }
/// <summary> /// Creates the GraphQL schema factory based on specified GraphQL services. /// </summary> /// <param name="services">The <see cref="T:Dora.GraphQL.Descriptors.GraphServiceDescriptor" /> list.</param> /// <returns> /// The <see cref="T:Dora.GraphQL.Schemas.IGraphSchema" />. /// </returns> public IGraphSchema Create(IEnumerable <GraphServiceDescriptor> services) { var knownTypes = services.SelectMany(it => it.KnownTypes).ToList(); var methods = services.SelectMany(it => it.Operations.Values).ToArray(); knownTypes.AddRange(methods.SelectMany(it => it.KnownTypes)); foreach (var knowType in knownTypes) { _graphTypeProvider.GetGraphType(knowType, false, false); } var methodGroups = methods .GroupBy(it => it.OperationType, it => it) .ToDictionary(it => it.Key, it => it); var query = CreateGraphType(OperationType.Query, methodGroups.TryGetValue(OperationType.Query, out var queryMethods) ? queryMethods : null); var mutation = CreateGraphType(OperationType.Mutation, methodGroups.TryGetValue(OperationType.Mutation, out var mutationMethods) ? mutationMethods : null); var subscription = CreateGraphType(OperationType.Subscription, methodGroups.TryGetValue(OperationType.Subscription, out var subscirptionMethods) ? subscirptionMethods : null); var schema = new GraphSchema(query, mutation, subscription); foreach (var field in schema.Fields.Values) { field.SetHasCustomResolverFlags(); } return(schema); }
private ICollection <ISelectionNode> ResolveSelections(IEnumerable <ISelection> selections, Dictionary <string, IFragment> fragements) { var list = new List <ISelectionNode>(); foreach (var selection in selections) { if (selection is InlineFragment inlineFragment) { var graphType = _graphTypeProvider.GetGraphType(inlineFragment.Type.Name); var fragment = new Fragment(graphType); foreach (var item in ResolveSelections(inlineFragment.SelectionSet.Selections, fragements)) { fragment.AddSubSelection(item); } list.Add(fragment); } if (!(selection is Field field)) { continue; } var fieldSelection = new FieldSelection(field.Name) { Alias = field.Alias }; if (field.SelectionSet.Selections.FirstOrDefault() is FragmentSpread fragmentSpread) { var fragmentType = fragements[fragmentSpread.Name]; } foreach (var directiveDefinition in field.Directives) { var directive = new Directive(directiveDefinition.Name); foreach (var argument in directiveDefinition.Arguments) { directive.AddArgument(new NamedValueToken(argument.Name, argument.Value.Value, argument.Value is VariableReference)); } fieldSelection.Directives.Add(directive); } foreach (var argument in field.Arguments) { fieldSelection.AddArgument(new NamedValueToken(argument.Name, argument.Value.Value, argument.Value is VariableReference)); } var subSelections = ResolveSelections(field.SelectionSet.Selections, fragements); foreach (var subSelection in subSelections) { fieldSelection.AddSubSelection(subSelection); } list.Add(fieldSelection); } return(list); }
private IGraphTypeOfGraphQLNet Convert(IGraphType graphType) { //Enumerable if (graphType.IsEnumerable) { var elementGraphType = _graphTypeProvider.GetGraphType(graphType.Type, false, false); var listGraphType = new ListGraphType(Convert(elementGraphType)); return(graphType.IsRequired ? new NonNullGraphType(listGraphType) : (IGraphTypeOfGraphQLNet)listGraphType); } //Scalar if (!graphType.Fields.Any()) { if (graphType.IsEnum) { var enumGraphType = typeof(EnumerationGraphType <>).MakeGenericType(graphType.Type); enumGraphType = graphType.IsRequired ? typeof(NonNullGraphType <>).MakeGenericType(enumGraphType) : enumGraphType; return((IGraphTypeOfGraphQLNet)Activator.CreateInstance(enumGraphType)); } var scalarType = !graphType.IsRequired ? GraphTypeTypeRegistry.Get(graphType.Type.GenericTypeArguments[0]) : GraphTypeTypeRegistry.Get(graphType.Type); if (null != scalarType) { return(graphType.IsRequired ? (IGraphTypeOfGraphQLNet)Activator.CreateInstance(typeof(NonNullGraphType <>).MakeGenericType(scalarType)) : (IGraphTypeOfGraphQLNet)Activator.CreateInstance(scalarType)); } throw new GraphException($"Unknown GraphType '{graphType.Name}'"); } //Complex var objectGraphType = new ObjectGraphType(); foreach (var field in graphType.Fields.Values) { var fieldType = new FieldType { Name = field.Name, ResolvedType = Convert(field.GraphType) }; foreach (var argument in field.Arguments.Values) { var queryArgument = new QueryArgument(Convert(argument.GraphType)) { Name = argument.Name }; fieldType.Arguments.Add(queryArgument); } objectGraphType.AddField(fieldType); } return(graphType.IsRequired ? (IGraphTypeOfGraphQLNet) new NonNullGraphType(objectGraphType) : objectGraphType); }