/// <summary> /// Determines if the given concrete type is associated to a graph type of the supplied kind. This /// method will perform a <see cref="TypeKind"/> coersion if possible. /// </summary> /// <param name="type">The concrete type to search for.</param> /// <param name="kind">The graph type kind to look for.</param> /// <returns><c>true</c> if a graph type exists, <c>false</c> otherwise.</returns> public bool Contains(Type type, TypeKind?kind = null) { type = GraphQLProviders.ScalarProvider.EnsureBuiltInTypeReference(type); if (_graphTypesByConcreteType.TryGetValue(type, out var typeSet)) { var resolvedKind = kind ?? GraphValidation.ResolveTypeKind(type); return(typeSet.ContainsKey(resolvedKind)); } else { return(false); } }
/// <summary> /// Retrieves the concrete types that this instance may return or make use of in a graph query. /// </summary> /// <returns>IEnumerable<Type>.</returns> public IEnumerable <DependentType> RetrieveRequiredTypes() { if (this.ArgumentModifiers.IsSourceParameter()) { // source parameters should not be injected into the object graph // so they have no dependents return(Enumerable.Empty <DependentType>()); } else { var expectedTypeKind = GraphValidation.ResolveTypeKind(this.ObjectType, TypeKind.INPUT_OBJECT); return(new DependentType(this.ObjectType, expectedTypeKind).AsEnumerable()); } }
/// <summary> /// Attempts to find the graph type of a given kind for the supplied concrete type. Returns null if no type is found. This /// method will perform a <see cref="TypeKind"/> coersion if possible. /// </summary> /// <param name="type">The concrete type to search with.</param> /// <param name="kind">The kind of graph type to search for. If not supplied the schema will attempt to automatically /// resolve the correct kind from the given <see cref="Type"/>.</param> /// <returns>IGraphType.</returns> public IGraphType FindGraphType(Type type, TypeKind?kind = null) { Validation.ThrowIfNull(type, nameof(type)); type = GraphQLProviders.ScalarProvider.EnsureBuiltInTypeReference(type); var resolvedKind = GraphValidation.ResolveTypeKind(type, kind); if (_graphTypesByConcreteType.TryGetValue(type, out var typeSet)) { if (typeSet.TryGetValue(resolvedKind, out var graphType)) { return(graphType); } } return(null); }
/// <summary> /// Parses the provided type, extracting the metadata to used in type generation for the object graph. /// </summary> /// <param name="objectType">The type of the object to parse.</param> /// <param name="kind">The kind of graph type to parse for.</param> /// <returns>IGraphTypeTemplate.</returns> public IGraphTypeTemplate ParseType(Type objectType, TypeKind?kind = null) { Validation.ThrowIfNull(objectType, nameof(objectType)); var typeKind = GraphValidation.ResolveTypeKind(objectType, kind); var typeKey = Tuple.Create(typeKind, objectType); if (_knownObjects.TryGetValue(typeKey, out var template) && this.CacheTemplates) { return(template); } if (GraphQLProviders.ScalarProvider.IsScalar(objectType)) { throw new GraphTypeDeclarationException( $"The type '{objectType.FriendlyName()}' is a known scalar type. Scalars must be explicitly defined and cannot be templated.", objectType); } if (Validation.IsCastable <IGraphUnionProxy>(objectType)) { throw new GraphTypeDeclarationException( $"The union proxy '{objectType.FriendlyName()}' cannot be directly parsed as a graph type. Double check " + "your field attribute declarations'.", objectType); } GraphValidation.IsValidGraphType(objectType, true); template = this.MakeTemplate(objectType, typeKind); template.Parse(); template.ValidateOrThrow(); if (this.CacheTemplates) { _knownObjects.TryAdd(typeKey, template); } return(template); }
/// <summary> /// Creates a <see cref="IGraphType" /> representing the union this field should masquerade as in the object graph. /// Returns null if no union is declared for this field. /// </summary> /// <returns>IGraphType.</returns> public virtual IEnumerable <DependentType> RetrieveRequiredTypes() { // a base field knows, at most, about the return object type it is dependent on return(this.PossibleTypes?.Select(x => new DependentType(x, GraphValidation.ResolveTypeKind(x, this.Kind))) ?? Enumerable.Empty <DependentType>()); }