Example #1
0
        private void HandleDirective(DirectiveGraphType directive, TypeCollectionContext context)
        {
            if (directive.Arguments?.Count > 0)
            {
                foreach (var arg in directive.Arguments.List !)
                {
                    if (arg.ResolvedType == null)
                    {
                        if (arg.Type == null)
                        {
                            throw new InvalidOperationException($"Both ResolvedType and Type properties on argument '{directive.Name}.{arg.Name}' are null.");
                        }

                        object typeOrError = RebuildType(arg.Type, true, context.TypeMappings);
                        if (typeOrError is string error)
                        {
                            throw new InvalidOperationException($"The GraphQL type for argument '{directive.Name}.{arg.Name}' could not be derived implicitly. " + error);
                        }
                        arg.Type = (Type)typeOrError;

                        AddTypeIfNotRegistered(arg.Type, context);
                        arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType);
                    }
                    else
                    {
                        AddTypeIfNotRegistered(arg.ResolvedType, context);
                        arg.ResolvedType = ConvertTypeReference(directive, arg.ResolvedType);
                    }
                }
            }
        }
        private void HandleField(Type parentType, FieldType field, TypeCollectionContext context)
        {
            field.Name = FieldNameConverter.NameFor(field.Name, parentType);

            if (field.ResolvedType == null)
            {
                AddTypeIfNotRegistered(field.Type, context);
                field.ResolvedType = BuildNamedType(field.Type, context.ResolveType);
            }
            else
            {
                AddTypeIfNotRegistered(field.ResolvedType, context);
            }

            field.Arguments?.Apply(arg =>
            {
                arg.Name = FieldNameConverter.NameFor(arg.Name, null);

                if (arg.ResolvedType != null)
                {
                    AddTypeIfNotRegistered(arg.ResolvedType, context);
                    return;
                }

                AddTypeIfNotRegistered(arg.Type, context);
                arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType);
            });
        }
Example #3
0
        public void AddType <TType>(TypeCollectionContext context)
            where TType : GraphType
        {
            var instance = context.ResolveType(typeof(TType));

            AddType(instance, context);
        }
Example #4
0
        /// <summary>
        /// Initalizes a new instance with the specified <see cref="INameConverter"/>.
        /// </summary>
        public GraphTypesLookup(INameConverter nameConverter)
        {
#pragma warning disable IDE0016 // Use 'throw' expression; if this rule is applied here, then the null check is moved to the very end of the method - this is not what we want
            if (nameConverter == null)
            {
                throw new ArgumentNullException(nameof(nameConverter));
            }
#pragma warning restore IDE0016

            _context = new TypeCollectionContext(
                type => BuildNamedType(type, t => _builtInScalars.TryGetValue(t, out var graphType) ? graphType : _introspectionTypes.TryGetValue(t, out graphType) ? graphType : (IGraphType)Activator.CreateInstance(t)),
                (name, type, ctx) =>
            {
                string trimmed = name.TrimGraphQLTypes();
                lock (_lock)
                {
                    SetGraphType(trimmed, type);
                }
                ctx.AddType(trimmed, type, null);
            });

            // Add introspection types. Note that introspection types rely on the
            // CamelCaseNameConverter, as some fields are defined in pascal case - e.g. Field(x => x.Name)
            NameConverter = CamelCaseNameConverter.Instance;

            foreach (var introspectionType in _introspectionTypes.Values)
            {
                AddType(introspectionType, _context);
            }

            // set the name converter properly
            NameConverter = nameConverter;
        }
Example #5
0
        private SchemaTypes(ISchema schema)
        {
            _introspectionTypes = CreateIntrospectionTypes(schema.Features.AppliedDirectives, schema.Features.RepeatableDirectives);

            _context = new TypeCollectionContext(
                type => BuildNamedType(type, t => _builtInScalars.TryGetValue(t, out var graphType) ? graphType : _introspectionTypes.TryGetValue(t, out graphType) ? graphType : (IGraphType)Activator.CreateInstance(t)),
                (name, type, ctx) =>
            {
                lock (_lock)
                {
                    SetGraphType(name, type);
                }
                ctx.AddType(name, type, null);
            });

            // Add introspection types. Note that introspection types rely on the
            // CamelCaseNameConverter, as some fields are defined in pascal case - e.g. Field(x => x.Name)
            _nameConverter = CamelCaseNameConverter.Instance;

            foreach (var introspectionType in _introspectionTypes.Values)
            {
                AddType(introspectionType, _context);
            }

            // set the name converter properly
            _nameConverter = schema.NameConverter ?? CamelCaseNameConverter.Instance;
        }
        public void AddType(GraphType type, TypeCollectionContext context)
        {
            if (type == null)
            {
                return;
            }

            var name = type.CollectTypes(context);

            _types[name] = type;

            type.Fields.Apply(field =>
            {
                AddTypeIfNotRegistered(field.Type, context);

                if (field.Arguments != null)
                {
                    field.Arguments.Apply(arg =>
                    {
                        AddTypeIfNotRegistered(arg.Type, context);
                    });
                }
            });

            if (type is ObjectGraphType)
            {
                var obj = (ObjectGraphType)type;
                obj.Interfaces.Apply(objectInterface =>
                {
                    AddTypeIfNotRegistered(objectInterface, context);
                });
            }
        }
        private void AddTypeIfNotRegistered(Type type, TypeCollectionContext context)
        {
            var namedType = type.GetNamedType();
            var foundType = FindGraphType(namedType);

            if (foundType == null)
            {
                if (namedType == typeof(PageInfoType))
                {
                    AddType(new PageInfoType(), context);
                }
                else if (namedType.IsGenericType && (namedType.ImplementsGenericType(typeof(EdgeType <>)) || namedType.ImplementsGenericType(typeof(ConnectionType <,>))))
                {
                    AddType((IGraphType)Activator.CreateInstance(namedType), context);
                }
                else if (_builtInCustomScalars.TryGetValue(namedType, out var builtInCustomScalar))
                {
                    AddType(builtInCustomScalar, _context);
                }
                else
                {
                    AddTypeWithLoopCheck(context.ResolveType(namedType), context, namedType);
                }
            }
        }
Example #8
0
        private void AddTypeIfNotRegistered(Type type, TypeCollectionContext context)
        {
            var namedType = type.GetNamedType();
            var foundType = this[namedType];

            if (foundType == null)
            {
                if (namedType == typeof(PageInfoType))
                {
                    AddType(new PageInfoType(), context);
                    return;
                }
                if (namedType.IsGenericType)
                {
                    var genericDefinition = namedType.GetGenericTypeDefinition();
                    if (genericDefinition == typeof(EdgeType <>))
                    {
                        AddType((IGraphType)Activator.CreateInstance(namedType), context);
                        return;
                    }
                    if (genericDefinition == typeof(ConnectionType <>))
                    {
                        AddType((IGraphType)Activator.CreateInstance(namedType), context);
                        return;
                    }
                }
                AddType(context.ResolveType(namedType), context);
            }
        }
        private void HandleField(Type parentType, FieldType field, TypeCollectionContext context)
        {
            field.Name = FieldNameConverter.NameFor(field.Name, parentType);

            if (field.ResolvedType == null)
            {
                AddTypeIfNotRegistered(field.Type, context);
                field.ResolvedType = BuildNamedType(field.Type, context.ResolveType);
            }
            else
            {
                AddTypeIfNotRegistered(field.ResolvedType, context);
            }

            if (field.Arguments == null)
            {
                return;
            }

            foreach (var arg in field.Arguments)
            {
                arg.Name = FieldNameConverter.NameFor(arg.Name, null);

                if (arg.ResolvedType != null)
                {
                    AddTypeIfNotRegistered(arg.ResolvedType, context);
                    continue;
                }

                AddTypeIfNotRegistered(arg.Type, context);
                arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType);
            }
        }
        public void AddType(GraphType type, TypeCollectionContext context)
        {
            if (type == null)
            {
                return;
            }

            var name = type.CollectTypes(context);

            _types[name] = type;

            type.Fields.Apply(field =>
            {
                var foundType = this[field.Type];
                if (foundType == null)
                {
                    AddType(context.ResolveType(field.Type), context);
                }
            });

            if (type is ObjectGraphType)
            {
                var obj = (ObjectGraphType)type;
                obj.Interfaces.Apply(objectInterface =>
                {
                    var foundType = this[objectInterface];
                    if (foundType == null)
                    {
                        AddType(context.ResolveType(objectInterface), context);
                    }
                });
            }
        }
Example #11
0
        public GraphTypesLookup(INameConverter nameConverter)
        {
            if (nameConverter == null)
            {
                throw new ArgumentNullException(nameof(nameConverter));
            }

            _context = new TypeCollectionContext(
                type => BuildNamedType(type, t => _builtInScalars.TryGetValue(t, out var graphType) ? graphType : _introspectionTypes.TryGetValue(t, out graphType) ? graphType : (IGraphType)Activator.CreateInstance(t)),
                (name, type, ctx) =>
            {
                string trimmed = name.TrimGraphQLTypes();
                lock (_lock)
                {
                    SetGraphType(trimmed, type);
                }
                ctx.AddType(trimmed, type, null);
            });

            // Add introspection types. Note that introspection types rely on the
            // CamelCaseNameConverter, as some fields are defined in pascal case - e.g. Field(x => x.Name)
            NameConverter = CamelCaseNameConverter.Instance;

            foreach (var introspectionType in _introspectionTypes.Values)
            {
                AddType(introspectionType, _context);
            }

            // set the name converter properly
            NameConverter = nameConverter;
        }
        public void AddType <TType>(TypeCollectionContext context)
            where TType : IGraphType
        {
            var type     = typeof(TType).GetNamedType();
            var instance = context.ResolveType(type);

            AddType(instance, context);
        }
Example #13
0
        public static GraphTypesLookup Create(
            IEnumerable <IGraphType> types,
            IEnumerable <DirectiveGraphType> directives,
            Func <Type, IGraphType> resolveType,
            IFieldNameConverter fieldNameConverter,
            bool seal = false)
        {
            var lookup = new GraphTypesLookup
            {
                FieldNameConverter = fieldNameConverter ?? CamelCaseFieldNameConverter.Instance
            };

            var ctx = new TypeCollectionContext(resolveType, (name, graphType, context) =>
            {
                if (lookup[name] == null)
                {
                    lookup.AddType(graphType, context);
                }
            });

            foreach (var type in types)
            {
                lookup.AddType(type, ctx);
            }

            var introspectionType = typeof(SchemaIntrospection);

            lookup.HandleField(introspectionType, SchemaIntrospection.SchemaMeta, ctx);
            lookup.HandleField(introspectionType, SchemaIntrospection.TypeMeta, ctx);
            lookup.HandleField(introspectionType, SchemaIntrospection.TypeNameMeta, ctx);

            foreach (var directive in directives)
            {
                if (directive.Arguments == null)
                {
                    continue;
                }

                foreach (var arg in directive.Arguments)
                {
                    if (arg.ResolvedType != null)
                    {
                        arg.ResolvedType = lookup.ConvertTypeReference(directive, arg.ResolvedType);
                    }
                    else
                    {
                        arg.ResolvedType = lookup.BuildNamedType(arg.Type, ctx.ResolveType);
                    }
                }
            }

            lookup.ApplyTypeReferences();

            Debug.Assert(ctx.InFlightRegisteredTypes.Count == 0);
            lookup._sealed = seal;

            return(lookup);
        }
Example #14
0
        public virtual string CollectTypes(TypeCollectionContext context)
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                Name = GetType().Name;
            }

            return(Name);
        }
Example #15
0
        private void AddTypeIfNotRegistered(Type type, TypeCollectionContext context)
        {
            var foundType = this[type];

            if (foundType == null)
            {
                AddType(context.ResolveType(type), context);
            }
        }
        private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context)
        {
            var namedType = type.GetNamedType();
            var foundType = this[namedType.Name];

            if (foundType == null)
            {
                AddType(namedType, context);
            }
        }
Example #17
0
        public static GraphTypesLookup Create(
            IEnumerable <IGraphType> types,
            IEnumerable <DirectiveGraphType> directives,
            Func <Type, IGraphType> resolveType,
            INameConverter nameConverter,
            bool seal = false)
        {
            var lookup = nameConverter == null ? new GraphTypesLookup() : new GraphTypesLookup(nameConverter);

            var ctx = new TypeCollectionContext(resolveType, (name, graphType, context) =>
            {
                if (lookup[name] == null)
                {
                    lookup.AddType(graphType, context);
                }
            });

            foreach (var type in types)
            {
                lookup.AddType(type, ctx);
            }

            // these fields must not have their field names translated by INameConverter; see HandleField
            lookup.HandleField(null, lookup.SchemaMetaFieldType, ctx, false);
            lookup.HandleField(null, lookup.TypeMetaFieldType, ctx, false);
            lookup.HandleField(null, lookup.TypeNameMetaFieldType, ctx, false);

            foreach (var directive in directives)
            {
                if (directive.Arguments == null)
                {
                    continue;
                }

                foreach (var arg in directive.Arguments)
                {
                    if (arg.ResolvedType != null)
                    {
                        arg.ResolvedType = lookup.ConvertTypeReference(directive, arg.ResolvedType);
                    }
                    else
                    {
                        arg.ResolvedType = lookup.BuildNamedType(arg.Type, ctx.ResolveType);
                    }
                }
            }

            lookup.ApplyTypeReferences();

            Debug.Assert(ctx.InFlightRegisteredTypes.Count == 0);
            lookup._sealed = seal;

            return(lookup);
        }
        private void AddTypeIfNotRegistered(IGraphType type, TypeCollectionContext context)
        {
            var(namedType, namedType2) = type.GetNamedTypes();
            namedType ??= context.ResolveType(namedType2);

            var foundType = this[namedType.Name];

            if (foundType == null)
            {
                AddType(namedType, context);
            }
        }
Example #19
0
        private GraphType AddType(Type type)
        {
            var ctx = new TypeCollectionContext(ResolveType, (name, graphType, context) =>
            {
                _lookup.Value.AddType(graphType, context);
            });

            var instance = ResolveType(type);

            _lookup.Value.AddType(instance, ctx);
            return(instance);
        }
Example #20
0
        private GraphType AddType(Type type)
        {
            EnsureLookup();
            var ctx = new TypeCollectionContext(ResolveType, (name, graphType, context) =>
            {
                _lookup.AddType(graphType, context);
            });

            var instance = ResolveType(type);
            _lookup.AddType(instance, ctx);
            return instance;
        }
        public void AddType <TType>()
            where TType : GraphType, new()
        {
            var context = new TypeCollectionContext(
                type => (GraphType)Activator.CreateInstance(type),
                (name, type) =>
            {
                _types[name] = type;
            });

            AddType <TType>(context);
        }
Example #22
0
        private void HandleField(IComplexGraphType parentType, FieldType field, TypeCollectionContext context, bool applyNameConverter)
        {
            // applyNameConverter will be false while processing the three root introspection query fields: __schema, __type, and __typename
            //
            // During processing of those three root fields, the NameConverter will be set to the schema's selected NameConverter,
            //   and the field names must not be processed by the NameConverter
            //
            // For other introspection types and fields, the NameConverter will be set to CamelCaseNameConverter at the time this
            //   code executes, and applyNameConverter will be true
            //
            // For any other fields, the NameConverter will be set to the schema's selected NameConverter at the time this code
            //   executes, and applyNameConverter will be true

            if (applyNameConverter)
            {
                field.Name = NameConverter.NameForField(field.Name, parentType);
                NameValidator.ValidateName(field.Name);
            }

            if (field.ResolvedType == null)
            {
                AddTypeIfNotRegistered(field.Type, context);
                field.ResolvedType = BuildNamedType(field.Type, context.ResolveType);
            }
            else
            {
                AddTypeIfNotRegistered(field.ResolvedType, context);
            }

            if (field.Arguments == null)
            {
                return;
            }

            foreach (var arg in field.Arguments)
            {
                if (applyNameConverter)
                {
                    arg.Name = NameConverter.NameForArgument(arg.Name, parentType, field);
                    NameValidator.ValidateName(arg.Name, "argument");
                }

                if (arg.ResolvedType != null)
                {
                    AddTypeIfNotRegistered(arg.ResolvedType, context);
                    continue;
                }

                AddTypeIfNotRegistered(arg.Type, context);
                arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType);
            }
        }
Example #23
0
        public void AddType <TType>()
            where TType : IGraphType, new()
        {
            var context = new TypeCollectionContext(
                type => (GraphType)Activator.CreateInstance(type),
                (name, type, _) =>
            {
                var trimmed     = name.TrimGraphQLTypes();
                _types[trimmed] = type;
                _?.AddType(trimmed, type, null);
            });

            AddType <TType>(context);
        }
Example #24
0
        public void EnsureLookup()
        {
            if (_lookup == null)
            {
                _lookup = new GraphTypesLookup();

                var ctx = new TypeCollectionContext(ResolveType, (name, graphType) =>
                {
                    _lookup[name] = graphType;
                });

                _lookup.AddType(Query, ctx);
                _lookup.AddType(Mutation, ctx);
            }
        }
Example #25
0
        public void EnsureLookup()
        {
            if (_lookup == null)
            {
                _lookup = new GraphTypesLookup();

                var ctx = new TypeCollectionContext(ResolveType, (name, graphType) =>
                {
                    _lookup[name] = graphType;
                });

                _lookup.AddType(Query, ctx);
                _lookup.AddType(Mutation, ctx);
            }
        }
        public static GraphTypesLookup Create(
            IEnumerable <IGraphType> types,
            IEnumerable <DirectiveGraphType> directives,
            Func <Type, IGraphType> resolveType,
            IFieldNameConverter fieldNameConverter)
        {
            var lookup = new GraphTypesLookup();

            lookup.FieldNameConverter = fieldNameConverter ?? new CamelCaseFieldNameConverter();

            var ctx = new TypeCollectionContext(resolveType, (name, graphType, context) =>
            {
                if (lookup[name] == null)
                {
                    lookup.AddType(graphType, context);
                }
            });

            types.Apply(type =>
            {
                lookup.AddType(type, ctx);
            });

            var introspectionType = typeof(SchemaIntrospection);

            lookup.HandleField(introspectionType, SchemaIntrospection.SchemaMeta, ctx);
            lookup.HandleField(introspectionType, SchemaIntrospection.TypeMeta, ctx);
            lookup.HandleField(introspectionType, SchemaIntrospection.TypeNameMeta, ctx);

            directives.Apply(directive =>
            {
                directive.Arguments?.Apply(arg =>
                {
                    if (arg.ResolvedType != null)
                    {
                        arg.ResolvedType = lookup.ConvertTypeReference(directive, arg.ResolvedType);
                        return;
                    }

                    arg.ResolvedType = lookup.BuildNamedType(arg.Type, ctx.ResolveType);
                });
            });

            lookup.ApplyTypeReferences();

            return(lookup);
        }
Example #27
0
        private IGraphType AddType(Type type)
        {
            if (type == null)
            {
                return(null);
            }

            var ctx = new TypeCollectionContext(ResolveType, (name, graphType, context) =>
            {
                _lookup.Value.AddType(graphType, context);
            });

            var namedType = type.GetNamedType();
            var instance  = ResolveType(namedType);

            _lookup.Value.AddType(instance, ctx);
            return(instance);
        }
Example #28
0
        private void HandleField(FieldType field, TypeCollectionContext context)
        {
            if (field.ResolvedType == null)
            {
                AddTypeIfNotRegistered(field.Type, context);
                field.ResolvedType = BuildNamedType(field.Type, context.ResolveType);
            }

            field.Arguments?.Apply(arg =>
            {
                if (arg.ResolvedType != null)
                {
                    return;
                }

                AddTypeIfNotRegistered(arg.Type, context);
                arg.ResolvedType = BuildNamedType(arg.Type, context.ResolveType);
            });
        }
        // 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();
            }
        }
Example #30
0
        public static GraphTypesLookup Create(IEnumerable <GraphType> types, Func <Type, GraphType> resolveType)
        {
            var lookup = new GraphTypesLookup();

            var ctx = new TypeCollectionContext(resolveType, (name, graphType, context) =>
            {
                if (lookup[name] == null)
                {
                    lookup.AddType(graphType, context);
                }
            });

            types.Apply(type =>
            {
                lookup.AddType(type, ctx);
            });

            return(lookup);
        }
        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 void AddType <TType>()
            where TType : IGraphType, new()
        {
            var context = new TypeCollectionContext(
                type =>
            {
                return(BuildNamedType(type, t => (IGraphType)Activator.CreateInstance(t)));
            },
                (name, type, ctx) =>
            {
                var trimmed = name.TrimGraphQLTypes();
                lock (_lock)
                {
                    _types[trimmed] = type;
                }
                ctx?.AddType(trimmed, type, null);
            });

            AddType <TType>(context);
        }
Example #33
0
        private GraphType AddType(Type type)
        {
            var ctx = new TypeCollectionContext(ResolveType, (name, graphType) =>
            {
                _lookup[name] = graphType;
            });

            var instance = ResolveType(type);
            _lookup.AddType(instance, ctx);
            return instance;
        }