public void Register_SchemaType_ClrTypeExists_NoSystemTypes()
        {
            // arrange
            var context      = DescriptorContext.Create();
            var typeRegistry = new TypeRegistry();
            var typeLookup   = new TypeLookup(context.TypeInspector, typeRegistry);

            var typeDiscoverer = new TypeDiscoverer(
                context,
                typeRegistry,
                typeLookup,
                new HashSet <ITypeReference>
            {
                _typeInspector.GetTypeRef(typeof(FooType), TypeContext.Output)
            },
                new AggregateTypeInterceptor(),
                false);

            // act
            IReadOnlyList <ISchemaError> errors = typeDiscoverer.DiscoverTypes();

            // assert
            Assert.Empty(errors);

            new
            {
                registered = typeRegistry.Types
                             .Select(t => new
                {
                    type        = t.Type.GetType().GetTypeName(),
                    runtimeType = t.Type is IHasRuntimeType hr
                            ? hr.RuntimeType.GetTypeName()
                            : null,
                    references = t.References.Select(t => t.ToString()).ToList()
                }).ToList(),
        public void Upgrade_Type_From_GenericType()
        {
            // arrange
            var initialTypes = new HashSet <ITypeReference>();

            initialTypes.Add(new ClrTypeReference(
                                 typeof(ObjectType <Foo>),
                                 TypeContext.Output));
            initialTypes.Add(new ClrTypeReference(
                                 typeof(FooType),
                                 TypeContext.Output));

            var serviceProvider = new EmptyServiceProvider();

            var clrTypeReferences = new Dictionary <IClrTypeReference, ITypeReference>();

            var typeDiscoverer = new TypeDiscoverer(
                initialTypes,
                clrTypeReferences,
                DescriptorContext.Create(),
                new Dictionary <string, object>(),
                new AggregateTypeInitializationInterceptor(),
                serviceProvider);

            // act
            DiscoveredTypes result = typeDiscoverer.DiscoverTypes();

            // assert
            Assert.Empty(result.Errors);

            result.Types
            .Select(t => t.Type)
            .OfType <IHasClrType>()
            .ToDictionary(
                t => t.GetType().GetTypeName(),
                t => t.ClrType.GetTypeName())
            .MatchSnapshot(new SnapshotNameExtension("registered"));

            clrTypeReferences.ToDictionary(
                t => t.Key.ToString(),
                t => t.Value.ToString())
            .MatchSnapshot(new SnapshotNameExtension("clr"));
        }
Beispiel #3
0
        public void Register_ClrType_InferSchemaTypes()
        {
            // arrange
            var initialTypes = new HashSet <ITypeReference>();

            initialTypes.Add(TypeReference.Create(
                                 typeof(Foo),
                                 TypeContext.Output));

            var serviceProvider = new EmptyServiceProvider();

            var clrTypeReferences = new Dictionary <ClrTypeReference, ITypeReference>();

            var typeDiscoverer = new TypeDiscoverer(
                initialTypes,
                clrTypeReferences,
                DescriptorContext.Create(),
                new AggregateTypeInitializationInterceptor(),
                serviceProvider);

            // act
            DiscoveredTypes result = typeDiscoverer.DiscoverTypes();

            // assert
            Assert.Empty(result.Errors);

            new
            {
                registered = result.Types
                             .Select(t => t.Type)
                             .OfType <IHasRuntimeType>()
                             .ToDictionary(
                    t => t.GetType().GetTypeName(),
                    t => t.RuntimeType.GetTypeName()),
                clr = clrTypeReferences.ToDictionary(
                    t => t.Key.ToString(),
                    t => t.Value.ToString())
            }.MatchSnapshot();
        }
        public void Initialize(
            Func <ISchema> schemaResolver,
            IReadOnlySchemaOptions options)
        {
            if (schemaResolver is null)
            {
                throw new ArgumentNullException(nameof(schemaResolver));
            }

            if (options is null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // first we are going to find and initialize all types that belong to our schema.
            var typeRegistrar = new TypeDiscoverer(
                _context,
                _typeRegistry,
                _typeLookup,
                _initialTypes,
                _interceptor);

            if (typeRegistrar.DiscoverTypes() is { Count : > 0 } errors)
            {
                throw new SchemaException(errors);
            }

            // next lets tell the type interceptors what types we have initialized.
            if (_interceptor.TriggerAggregations)
            {
                _interceptor.OnTypesInitialized(
                    _typeRegistry.Types.Select(t => t.DiscoveryContext).ToList());
            }

            // before we can start completing type names we need to register the field resolvers.
            RegisterResolvers();

            // now that we have the resolvers sorted and know what types our schema will roughly
            // consist of we are going to have a look if we can infer interface usage
            // from .NET classes that implement .NET interfaces.
            RegisterImplicitInterfaceDependencies();

            // with all types (implicit and explicit) known we complete the type names.
            CompleteNames(schemaResolver);

            // with the type names all known we can now build pairs to bring together types and
            // their type extensions.
            MergeTypeExtensions();

            // external resolvers are resolvers that are defined on the schema and are associated
            // with the types after they have received a name and the extensions are removed.
            RegisterExternalResolvers();

            // with all resolvers in place we compile the once inferred from a C# member.
            CompileResolvers();

            // last we complete the types. Completing types means that we will assign all
            // the fields resolving all missing parts and then making the types immutable.
            CompleteTypes();

            // if we do not have any errors we will validate the types for spec violations.
            if (_errors.Count == 0)
            {
                _errors.AddRange(SchemaValidator.Validate(
                                     _typeRegistry.Types.Select(t => t.Type),
                                     options));
            }

            if (_errors.Count > 0)
            {
                throw new SchemaException(_errors);
            }
        }