private SchemaTypesDefinition CreateSchemaDefinition(
            TypeInitializer typeInitializer,
            DiscoveredTypes discoveredTypes)
        {
            var definition = new SchemaTypesDefinition();

            RegisterOperationName(OperationType.Query, _options.QueryTypeName);
            RegisterOperationName(OperationType.Mutation, _options.MutationTypeName);
            RegisterOperationName(OperationType.Subscription, _options.SubscriptionTypeName);

            definition.QueryType = ResolveOperation(
                typeInitializer, OperationType.Query);
            definition.MutationType = ResolveOperation(
                typeInitializer, OperationType.Mutation);
            definition.SubscriptionType = ResolveOperation(
                typeInitializer, OperationType.Subscription);

            IReadOnlyCollection <TypeSystemObjectBase> types =
                RemoveUnreachableTypes(discoveredTypes, definition);

            definition.Types = types
                               .OfType <INamedType>()
                               .Distinct()
                               .ToArray();

            definition.DirectiveTypes = types
                                        .OfType <DirectiveType>()
                                        .Distinct()
                                        .ToArray();

            return(definition);
        }
        private IReadOnlyCollection <TypeSystemObjectBase> RemoveUnreachableTypes(
            DiscoveredTypes discoveredTypes,
            SchemaTypesDefinition definition)
        {
            if (_options.RemoveUnreachableTypes)
            {
                var trimmer = new TypeTrimmer(discoveredTypes);

                if (definition.QueryType is { })
        public Schema Create()
        {
            IServiceProvider services = _services ?? new EmptyServiceProvider();

            var descriptorContext = DescriptorContext.Create(
                _options,
                services,
                CreateConventions(services),
                _contextData);

            foreach (Action <IDescriptorContext> action in _onBeforeCreate)
            {
                action(descriptorContext);
            }

            IBindingLookup bindingLookup =
                _bindingCompiler.Compile(descriptorContext);

            IReadOnlyCollection <ITypeReference> types =
                GetTypeReferences(services, bindingLookup);

            var lazy = new LazySchema();

            TypeInitializer initializer =
                CreateTypeInitializer(
                    services,
                    descriptorContext,
                    bindingLookup,
                    types);

            DiscoveredTypes discoveredTypes = initializer.Initialize(() => lazy.Schema, _options);

            SchemaTypesDefinition definition = CreateSchemaDefinition(initializer, discoveredTypes);

            if (definition.QueryType == null && _options.StrictValidation)
            {
                throw new SchemaException(
                          SchemaErrorBuilder.New()
                          .SetMessage(TypeResources.SchemaBuilder_NoQueryType)
                          .Build());
            }

            Schema schema = discoveredTypes.Types
                            .Select(t => t.Type)
                            .OfType <Schema>()
                            .First();

            schema.CompleteSchema(definition);
            lazy.Schema = schema;
            TypeInspector.Default.Clear();
            return(schema);
        }
        private bool AddDiscoveredType(BaseTypeDeclarationSyntax syntaxItem, string fullType)
        {
            if (!DiscoverTypes || string.IsNullOrEmpty(fullType) || string.IsNullOrEmpty(Namespace))
            {
                return(false);
            }

            //if (fullType.Contains("BaseDataObject"))
            //    Log.Info("found");

            // Add Identifier
            var identifierFullType = $"{Namespace}.{syntaxItem.Identifier.Text}";

            var _fullType           = fullType.ToLower();
            var _identifierFullType = identifierFullType.ToLower();
            var _identifier         = syntaxItem.Identifier.Text.ToLower();

            if (fullType != identifierFullType)
            {
                if (!DiscoveredTypes.ContainsKey(_identifierFullType))
                {
                    DiscoveredTypes[_identifierFullType] = identifierFullType;
                }
            }

            // Add Unqualified Identifier
            if (_fullType != _identifier)
            {
                if (!DiscoveredTypes.ContainsKey(_identifier))
                {
                    DiscoveredTypes[_identifier] = syntaxItem.Identifier.Text;
                }
            }

            if (DiscoveredTypes.ContainsKey(_fullType))
            {
                Log.Warn($"Discovered Type already found: {fullType} {syntaxItem}");
                return(false);
            }

            // Use default namespace if specified
            if (!string.IsNullOrEmpty(DefaultNamespace))
            {
                DiscoveredTypes[_fullType] = fullType.Replace(Namespace, DefaultNamespace);
            }
            else
            {
                DiscoveredTypes[_fullType] = fullType;
            }

            return(true);
        }
        internal static string MapKnownType(string fullType)
        {
            var _fullType = fullType.ToLower();

            return(DiscoveredTypes.ContainsKey(_fullType) ? DiscoveredTypes[_fullType] : null);
        }
        internal static bool IsKnownType(string fullType)
        {
            var _fullType = fullType.ToLower();

            return(DiscoveredTypes.ContainsKey(_fullType) || KnownTypes.Contains(_fullType));
        }