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);
            }
        }
示例#2
0
        /// <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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }