Example #1
0
        /// <summary>
        /// Adds a delegate that will be used to configure a named <see cref="ISchema"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IRequestExecutorBuilder"/>.</param>
        /// <param name="configureSchema">A delegate that is used to configure an <see cref="ISchema"/>.</param>
        /// <returns>An <see cref="IRequestExecutorBuilder"/> that can be used to configure a schema and its execution.</returns>
        /// <remarks>
        /// The <see cref="IServiceProvider"/> provided to <paramref name="configureSchema"/> will be the
        /// same application's root service provider instance.
        /// </remarks>
        public static IRequestExecutorBuilder ConfigureSchema(
            this IRequestExecutorBuilder builder,
            Action <IServiceProvider, ISchemaBuilder> configureSchema)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(Configure(
                       builder,
                       (services, options) => options.SchemaBuilderActions.Add(
                           new SchemaBuilderAction(b => configureSchema(services, b)))));
        }
        public static IRequestExecutorBuilder AddSortingForPreProcessedResults(
            this IRequestExecutorBuilder builder,
            string?name = null
            )
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            return(builder.AddSorting((sortConventionDescriptor) =>
            {
                //Add all Default Sorting Operation conventions & the Custom PreProcessedSortProvider...
                sortConventionDescriptor
                .AddDefaultOperations()
                .BindDefaultTypes()
                .Provider(new PreProcessedSortProvider());
            }, name));
        }
Example #3
0
        /// <summary>
        /// Adds a delegate that will be used to modify the <see cref="RequestExecutorOptions"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IRequestExecutorBuilder"/>.</param>
        /// <param name="modify">A delegate that is used to modify the <see cref="RequestExecutorOptions"/>.</param>
        /// <returns>An <see cref="IRequestExecutorBuilder"/> that can be used to configure a schema and its execution.</returns>
        public static IRequestExecutorBuilder ModifyRequestOptionsAsync(
            this IRequestExecutorBuilder builder,
            Func <IServiceProvider, RequestExecutorOptions, CancellationToken, ValueTask> modify)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(Configure(
                       builder,
                       (services, options) => options.RequestExecutorOptionsActions.Add(
                           new RequestExecutorOptionsAction((o, ct) => modify(services, o, ct)))));
        }
Example #4
0
    /// <summary>
    /// Adds a delegate that will be used to configure a named <see cref="ISchema"/>.
    /// </summary>
    /// <param name="builder">
    /// The <see cref="IRequestExecutorBuilder"/>.
    /// </param>
    /// <param name="configureSchema">
    /// A delegate that is used to configure an <see cref="ISchema"/>.
    /// </param>
    /// <returns>
    /// An <see cref="IRequestExecutorBuilder"/> that can be used to configure a schema
    /// and its execution.
    /// </returns>
    /// <remarks>
    /// The <see cref="IServiceProvider"/> provided to <paramref name="configureSchema"/>
    /// will be the same application's root service provider instance.
    /// </remarks>
    public static IRequestExecutorBuilder ConfigureSchemaAsync(
        this IRequestExecutorBuilder builder,
        Func <IServiceProvider, ISchemaBuilder, CancellationToken, ValueTask> configureSchema)
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

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

        return(Configure(
                   builder,
                   options => options.SchemaBuilderActions.Add(
                       new SchemaBuilderAction(configureSchema))));
    }
Example #5
0
    /// <summary>
    /// Adds a delegate that will be used to modify the <see cref="RequestExecutorOptions"/>.
    /// </summary>
    /// <param name="builder">The <see cref="IRequestExecutorBuilder"/>.</param>
    /// <param name="modify">
    /// A delegate that is used to modify the <see cref="RequestExecutorOptions"/>.
    /// </param>
    /// <returns>
    /// An <see cref="IRequestExecutorBuilder"/> that can be used to configure a schema
    /// and its execution.
    /// </returns>
    public static IRequestExecutorBuilder ModifyRequestOptions(
        this IRequestExecutorBuilder builder,
        Action <RequestExecutorOptions> modify)
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

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

        return(Configure(
                   builder,
                   options => options.RequestExecutorOptionsActions.Add(
                       new RequestExecutorOptionsAction(modify))));
    }
        public static IRequestExecutorBuilder UseHttpRequestPipeline(
            this IRequestExecutorBuilder builder)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            return(builder
                   .UseInstrumentations()
                   .UseExceptions()
                   .UseDocumentCache()
                   .UseDocumentParser()
                   .UseDocumentValidation()
                   .UseOperationCache()
                   .UseOperationResolver()
                   .UseOperationVariableCoercion()
                   .UseHttpRequests());
        }
Example #7
0
    public static IRequestExecutorBuilder AddErrorFilter <T>(
        this IRequestExecutorBuilder builder,
        Func <IServiceProvider, T> factory)
        where T : class, IErrorFilter
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

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

        return(builder.ConfigureSchemaServices(
                   s => s.AddSingleton <IErrorFilter, T>(
                       sp => factory(sp.GetCombinedServices()))));
    }
Example #8
0
        public static IRequestExecutorBuilder AddSubscriptionType(
            this IRequestExecutorBuilder builder,
            Action <IObjectTypeDescriptor> configure)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchema(b => b.AddSubscriptionType(d =>
            {
                d.Name(OperationTypeNames.Subscription);
                configure(d);
            })));
        }
        public static IRequestExecutorBuilder AddApolloTracing(
            this IRequestExecutorBuilder builder,
            TracingPreference tracingPreference  = TracingPreference.OnDemand,
            ITimestampProvider?timestampProvider = null)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (tracingPreference == TracingPreference.Never)
            {
                return(builder);
            }

            return(builder.AddDiagnosticEventListener(
                       sp => new ApolloTracingDiagnosticEventListener(
                           tracingPreference,
                           timestampProvider ?? sp.GetService <ITimestampProvider>())));
        }
Example #10
0
        public static IRequestExecutorBuilder OnAfterCompleteType(
            this IRequestExecutorBuilder builder,
            OnCompleteType onAfterCompleteType,
            Func <ITypeSystemObjectContext, bool>?canHandle = null)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchema(b => b
                                           .TryAddTypeInterceptor(new DelegateTypeInterceptor(
                                                                      canHandle,
                                                                      onAfterCompleteType: onAfterCompleteType))));
        }
Example #11
0
        /// <summary>
        /// Adds the MongoDB cursor and offset paging providers.
        /// </summary>
        /// <param name="builder">
        /// The GraphQL configuration builder.
        /// </param>
        /// <param name="providerName">
        /// The name which shall be used to refer to this registration.
        /// </param>
        /// <param name="defaultProvider">
        /// Defines if these providers shall be registered as default providers.
        /// </param>
        /// <returns>
        /// Returns the GraphQL configuration builder for further configuration chaining.
        /// </returns>
        public static IRequestExecutorBuilder AddMongoDbPagingProviders(
            this IRequestExecutorBuilder builder,
            string?providerName  = null,
            bool defaultProvider = false)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.AddCursorPagingProvider <MongoDbCursorPagingProvider>(
                providerName,
                defaultProvider);

            builder.AddOffsetPagingProvider <MongoDbOffsetPagingProvider>(
                providerName,
                defaultProvider);

            return(builder);
        }
        public static IRequestExecutorBuilder AddDocument(
            this IRequestExecutorBuilder builder,
            LoadDocumentAsync loadDocumentAsync)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchemaAsync(async(sp, b, ct) =>
            {
                DocumentNode document = await loadDocumentAsync(sp, ct).ConfigureAwait(false);
                b.AddDocument(document);
            }));
        }
        public static IRequestExecutorBuilder AddDocumentFromFile(
            this IRequestExecutorBuilder builder,
            string filePath)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentException(nameof(filePath));
            }

            return(builder.AddDocument(async(sp, ct) =>
            {
                byte[] buffer = await Task.Run(() => File.ReadAllBytes(filePath), ct);
                return Utf8GraphQLParser.Parse(buffer);
            }));
        }
        public static IRequestExecutorBuilder AddInventorySchema(
            this IRequestExecutorBuilder builder)
        {
            builder.Services
            .AddSingleton <InventoryInfoRepository>();

            return(builder
                   .AddQueryType <Query>()
                   .PublishSchemaDefinition(c => c
                                            .SetName("inventory")
                                            .IgnoreRootTypes()
                                            .AddTypeExtensionsFromString(
                                                @"extend type Product {
                            inStock: Boolean
                                @delegate(path: ""inventoryInfo(upc: $fields:upc).isInStock"")
                            shippingEstimate: Int
                                @delegate(path: ""shippingEstimate(price: $fields:price weight: $fields:weight)"")
                        }
                ")));
        }
Example #15
0
        public static IRequestExecutorBuilder AddDiagnosticEventListener <T>(
            this IRequestExecutorBuilder builder,
            Func <IServiceProvider, T> diagnosticEventListener)
            where T : IDiagnosticEventListener
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchemaServices(
                       s => s.AddSingleton <IDiagnosticEventListener>(
                           sp => diagnosticEventListener(
                               sp.GetRequiredService <IApplicationServiceProvider>()))));
        }
    /// <summary>
    /// Adds a query validation visitor to the schema.
    /// </summary>
    /// <param name="builder">
    /// The <see cref="IRequestExecutorBuilder"/>.
    /// </param>
    /// <param name="factory">
    /// The factory that creates the validator instance.
    /// </param>
    /// <param name="isCacheable">
    /// Defines if the result of this rule can be cached and reused on consecutive
    /// validations of the same GraphQL request document.
    /// </param>
    /// <typeparam name="T">
    /// The type of the validator.
    /// </typeparam>
    /// <returns>
    /// Returns an <see cref="IRequestExecutorBuilder"/> that can be used to chain
    /// configuration.
    /// </returns>
    public static IRequestExecutorBuilder AddValidationVisitor <T>(
        this IRequestExecutorBuilder builder,
        Func <IServiceProvider, ValidationOptions, T> factory,
        bool isCacheable = true)
        where T : DocumentValidatorVisitor
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

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

        return(ConfigureValidation(
                   builder,
                   b => b.TryAddValidationVisitor(factory, isCacheable)));
    }
Example #17
0
        public static IRequestExecutorBuilder OnAfterRegisterDependencies(
            this IRequestExecutorBuilder builder,
            OnInitializeType onAfterRegisterDependencies,
            Func <ITypeSystemObjectContext, bool>?canHandle = null)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchema(b => b
                                           .TryAddTypeInterceptor(new DelegateTypeInterceptor(
                                                                      canHandle,
                                                                      onAfterRegisterDependencies: onAfterRegisterDependencies))));
        }
        public static IRequestExecutorBuilder IgnoreField(
            this IRequestExecutorBuilder builder,
            NameString schemaName,
            FieldReference field)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (field == null)
            {
                throw new ArgumentNullException(nameof(field));
            }

            schemaName.EnsureNotEmpty(nameof(schemaName));

            return(builder.AddTypeRewriter(
                       new RemoveFieldRewriter(schemaName, field)));
        }
Example #19
0
        public static IRequestExecutorBuilder PublishSchemaDefinition(
            this IRequestExecutorBuilder builder,
            Action <IPublishSchemaDefinitionDescriptor> configure)
        {
            var descriptor = new PublishSchemaDefinitionDescriptor(builder);

            configure(descriptor);

            var typeInterceptor   = new SchemaDefinitionTypeInterceptor(!descriptor.HasPublisher);
            var schemaInterceptor = new SchemaDefinitionSchemaInterceptor(descriptor);

            builder
            .AddType <SchemaDefinitionType>()
            .TryAddTypeInterceptor(typeInterceptor)
            .TryAddSchemaInterceptor(schemaInterceptor)
            .ConfigureOnRequestExecutorCreatedAsync(
                async(sp, executor, ct) => await descriptor.PublishAsync(sp, ct));

            return(builder);
        }
Example #20
0
        public static IRequestExecutorBuilder AddProductsSchema(
            this IRequestExecutorBuilder builder)
        {
            builder.Services
            .AddSingleton <ProductRepository>();

            return(builder
                   .AddQueryType <Query>()
                   .PublishSchemaDefinition(c => c
                                            .SetName("products")
                                            .IgnoreRootTypes()
                                            .AddTypeExtensionsFromString(
                                                @"extend type Query {
                            topProducts(first: Int = 5): [Product] @delegate
                        }

                        extend type Review {
                            product: Product @delegate(path: ""product(upc: $fields:upc)"")
                        }")));
        }
        public static IRequestExecutorBuilder AddRemoteSchemaFromString(
            this IRequestExecutorBuilder builder,
            NameString schemaName,
            string schemaSdl,
            bool ignoreRootTypes = false)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            schemaName.EnsureNotEmpty(nameof(schemaName));

            return(AddRemoteSchema(
                       builder,
                       schemaName,
                       (services, cancellationToken) =>
                       new ValueTask <DocumentNode>(Utf8GraphQLParser.Parse(schemaSdl)),
                       ignoreRootTypes));
        }
        public static IRequestExecutorBuilder AddFairyBread(
            this IRequestExecutorBuilder requestExecutorBuilder,
            Action <IFairyBreadOptions>?configureOptions = null)
        {
            // Services
            var services = requestExecutorBuilder.Services;

            var options = new DefaultFairyBreadOptions();

            configureOptions?.Invoke(options);
            services.TryAddSingleton <IFairyBreadOptions>(options);

            services.TryAddSingleton <IValidatorProvider, DefaultValidatorProvider>();

            services.TryAddSingleton <IValidationResultHandler, DefaultValidationResultHandler>();

            // Execution
            requestExecutorBuilder.UseField <InputValidationMiddleware>();

            return(requestExecutorBuilder);
        }
Example #23
0
        /// <summary>
        /// Adds a offset paging provider to the DI.
        /// </summary>
        /// <param name="builder">
        /// The request executor builder.
        /// </param>
        /// <param name="providerName">
        /// The name the provider shall have.
        /// </param>
        /// <param name="defaultProvider">
        /// Defines if the registered provider shall be registered as the default provider.
        /// </param>
        /// <typeparam name="TProvider">
        /// The type of the provider.
        /// </typeparam>
        /// <returns>
        /// The request executor builder.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="builder"/> is <c>null</c>.
        /// </exception>
        public static IRequestExecutorBuilder AddOffsetPagingProvider <TProvider>(
            this IRequestExecutorBuilder builder,
            string?providerName  = null,
            bool defaultProvider = false)
            where TProvider : OffsetPagingProvider
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.TryAddSingleton <TProvider>();

            AddOffsetPagingProvider(
                builder,
                s => s.GetRequiredService <TProvider>(),
                providerName,
                defaultProvider);

            return(builder);
        }
Example #24
0
    public static IRequestExecutorBuilder AddChangeLog(this IRequestExecutorBuilder builder)
    {
        // dataloaders
        builder.AddDataLoader <ChangeLogByIdDataloader>();


        // nodes
        builder.AddTypeExtension <ChangeLogNode>();

        // types
        builder.AddTypeExtension <ChangeLogQueries>();

        // extensions
        builder
        .AddTypeExtension <ComponentExtensions>();

        // change log
        builder.AddInterfaceType <IChange>(x => x.Name("Change"));

        return(builder);
    }
Example #25
0
        public static IRequestExecutorBuilder OnBeforeCompleteType <T>(
            this IRequestExecutorBuilder builder,
            OnCompleteType <T> onBeforeCompleteType,
            Func <ITypeSystemObjectContext, bool>?canHandle = null)
            where T : DefinitionBase
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            return(builder.ConfigureSchema(b => b
                                           .TryAddTypeInterceptor(new DelegateTypeInitializationInterceptor <T>(
                                                                      canHandle,
                                                                      onBeforeCompleteType: onBeforeCompleteType))));
        }
    public static IRequestExecutorBuilder AddEnvironments(this IRequestExecutorBuilder builder)
    {
        // dataloaders
        builder.AddDataLoader <EnvironmentByIdDataLoader>();

        builder.Services
        .AddScoped <IDataLoader <Guid, Environment?> >(
            sp => sp.GetRequiredService <EnvironmentByIdDataLoader>());

        builder.AddTypeExtension <EnvironmentNode>();

        // types
        builder
        .AddTypeExtension <EnvironmentQueries>()
        .AddTypeExtension <EnvironmentMutations>();

        // extensions
        builder.AddTypeExtension <EnvironmentExtensions>();

        return(builder);
    }
Example #27
0
        public static IRequestExecutorBuilder UseActivePersistedQueryPipeline(
            this IRequestExecutorBuilder builder)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            return(builder
                   .UseInstrumentations()
                   .UseExceptions()
                   .UseDocumentCache()
                   .UseReadPersistedQuery()
                   .UseWritePersistedQuery()
                   .UseDocumentParser()
                   .UseDocumentValidation()
                   .UseOperationCache()
                   .UseOperationResolver()
                   .UseOperationVariableCoercion()
                   .UseOperationExecution());
        }
        public static IRequestExecutorBuilder RenameField(
            this IRequestExecutorBuilder builder,
            FieldReference field,
            NameString newFieldName)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (field == null)
            {
                throw new ArgumentNullException(nameof(field));
            }

            newFieldName.EnsureNotEmpty(nameof(newFieldName));

            return(builder.AddTypeRewriter(
                       new RenameFieldRewriter(
                           field, newFieldName)));
        }
Example #29
0
        public static IRequestExecutorBuilder AddAccountsSchema(
            this IRequestExecutorBuilder builder)
        {
            builder.Services
            .AddSingleton <UserRepository>();

            return(builder
                   .AddGraphQLServer()
                   .AddQueryType <Query>()
                   .PublishSchemaDefinition(c => c
                                            .SetName("accounts")
                                            .IgnoreRootTypes()
                                            .AddTypeExtensionsFromString(
                                                @"extend type Query {
                             me: User! @delegate(path: ""user(id: 1)"")
                        }

                        extend type Review {
                            author: User @delegate(path: ""user(id: $fields:authorId)"")
                        }")));
        }
Example #30
0
        /// <summary>
        /// Executes the specified action if the specified <paramref name="condition"/> is <c>true</c> which can be
        /// used to conditionally add to the request execution pipeline.
        /// </summary>
        /// <param name="builder">The request executor builder.</param>
        /// <param name="condition">If set to <c>true</c> the action is executed.</param>
        /// <param name="action">The action used to add to the request execution pipeline.</param>
        /// <returns>The same application builder.</returns>
        public static IRequestExecutorBuilder AddIf(
            this IRequestExecutorBuilder builder,
            bool condition,
            Func <IRequestExecutorBuilder, IRequestExecutorBuilder> action)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

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

            if (condition)
            {
                builder = action(builder);
            }

            return(builder);
        }