public static IObjectFieldDescriptor UseDbContext <TDbContext>(
            this IObjectFieldDescriptor descriptor)
            where TDbContext : DbContext
        {
            string scopedServiceName = typeof(TDbContext).FullName ?? typeof(TDbContext).Name;
            FieldMiddlewareDefinition placeholder =
                new(_ => _ => throw new NotSupportedException(), key : WellKnownMiddleware.ToList);

            descriptor.Extend().Definition.MiddlewareDefinitions.Add(
                new(next => async context =>
            {
                await using TDbContext dbContext = context.Services
                                                   .GetRequiredService <IDbContextFactory <TDbContext> >()
                                                   .CreateDbContext();

                try
                {
                    context.SetLocalValue(scopedServiceName, dbContext);
                    await next(context).ConfigureAwait(false);
                }
                finally
                {
                    context.RemoveLocalValue(scopedServiceName);
                }
            }, key: WellKnownMiddleware.DbContext));

            descriptor.Extend().Definition.MiddlewareDefinitions.Add(placeholder);

            descriptor
            .Extend()
            .OnBeforeNaming((_, d) =>
            {
                if (d.ResultType is null)
                {
                    d.MiddlewareDefinitions.Remove(placeholder);
                    return;
                }

                if (TryExtractEntityType(d.ResultType, out Type? entityType))
                {
                    Type middleware = typeof(ToListMiddleware <>).MakeGenericType(entityType);
                    var index       = d.MiddlewareDefinitions.IndexOf(placeholder);
                    d.MiddlewareDefinitions[index] =
                        new(Create(middleware), key: WellKnownMiddleware.ToList);
                    return;
                }

                if (IsExecutable(d.ResultType))
                {
                    Type middleware = typeof(ExecutableMiddleware);
                    var index       = d.MiddlewareDefinitions.IndexOf(placeholder);
                    d.MiddlewareDefinitions[index] =
                        new(Create(middleware), key: WellKnownMiddleware.ToList);
                }

                d.MiddlewareDefinitions.Remove(placeholder);
            });

            return(descriptor);
        }
        public static IObjectFieldDescriptor UsePaging(
            this IObjectFieldDescriptor descriptor,
            Type?type       = null,
            Type?entityType = null,
            GetCursorPagingProvider?resolvePagingProvider = null,
            PagingOptions options = default)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            resolvePagingProvider ??= ResolvePagingProvider;

            descriptor.AddPagingArguments();

            PagingHelper.UsePaging(
                descriptor,
                type,
                entityType,
                (services, source) => resolvePagingProvider(services, source),
                options);

            descriptor
            .Extend()
            .OnBeforeCreate(
                (c, d) => d.Type = CreateConnectionTypeRef(
                    c, d.ResolverMember ?? d.Member, type, options));

            return(descriptor);
        }
Esempio n. 3
0
    /// <summary>
    /// Applies the offset paging middleware to the current field.
    /// </summary>
    /// <param name="descriptor">
    /// The object field descriptor.
    /// </param>
    /// <param name="itemType">
    /// The schema type representation of the item.
    /// </param>
    /// <param name="entityType">
    /// The entity type represents the runtime type of the item.
    /// </param>
    /// <param name="resolvePagingProvider">
    /// A delegate allowing to dynamically define a paging resolver for a field.
    /// </param>
    /// <param name="options">
    /// The paging settings that shall be applied to this field.
    /// </param>
    /// <returns>
    /// Returns the field descriptor for chaining in other configurations.
    /// </returns>
    public static IObjectFieldDescriptor UseOffsetPaging(
        this IObjectFieldDescriptor descriptor,
        Type?itemType   = null,
        Type?entityType = null,
        GetOffsetPagingProvider?resolvePagingProvider = null,
        PagingOptions options = default)
    {
        if (descriptor is null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        resolvePagingProvider ??= ResolvePagingProvider;

        descriptor.AddOffsetPagingArguments();

        PagingHelper.UsePaging(
            descriptor,
            entityType,
            (services, source, name) => resolvePagingProvider(services, source, name),
            options);

        descriptor
        .Extend()
        .OnBeforeCreate((c, d) =>
        {
            MemberInfo?resolverMember = d.ResolverMember ?? d.Member;
            d.Type = CreateTypeRef(c, resolverMember, itemType, options);
            d.CustomSettings.Add(typeof(CollectionSegment));
        });

        return(descriptor);
    }
    public static IObjectFieldDescriptor Error(
        this IObjectFieldDescriptor descriptor,
        Type errorType)
    {
        descriptor.Extend().OnBeforeCreate(ConfigureField);

        return(descriptor);

        void ConfigureField(IDescriptorContext c, ObjectFieldDefinition d)
        {
            IReadOnlyList <ErrorDefinition>
            definitions = ErrorFactoryCompiler.Compile(errorType);

            if (!d.ContextData.TryGetValue(ErrorDefinitions, out var value) ||
                !(value is List <ErrorDefinition> errorFactories))
            {
                errorFactories = new List <ErrorDefinition>();
                d.ContextData[ErrorDefinitions] = errorFactories;
            }

            errorFactories.AddRange(definitions);

            foreach (ErrorDefinition definition in definitions)
            {
                ExtendedTypeReference typeRef =
                    c.TypeInspector.GetTypeRef(definition.SchemaType);
                d.Dependencies.Add(new TypeDependency(typeRef));
            }
        }
    }
 public static IObjectFieldDescriptor UseUpperCase(
     this IObjectFieldDescriptor descriptor)
 {
     descriptor.Extend().Definition.ResultConverters.Add(
         new((c, r) => r is string s ? s.ToUpperInvariant() : r));
     return(descriptor);
 }
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     descriptor.Extend().OnBeforeCompletion(
         (c, d) => d.ContextData.Add("abc", "def"));
 }
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     descriptor
     .Extend()
     .OnBeforeCreate(x => x.ContextData.Add(nameof(Neo4JCypherAttribute), _statement));
 }
        public static IObjectFieldDescriptor ID(
            this IObjectFieldDescriptor descriptor,
            NameString typeName = default)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            FieldMiddleware placeholder = n => c => default;

            descriptor.Use(placeholder);
            descriptor.Extend().OnBeforeCreate(RewriteObjectFieldType);
            descriptor.Extend().OnBeforeCompletion(
                (c, d) => AddSerializerToObjectField(c, d, placeholder, typeName));

            return(descriptor);
        }
Esempio n. 9
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     descriptor
     .Extend()
     .OnBeforeCreate(x => x.ContextData.Add(nameof(Neo4JRelationshipAttribute), this));
 }
Esempio n. 10
0
    /// <summary>
    /// Applies a cursor paging middleware to the field and rewrites the
    /// field type to a connection.
    /// </summary>
    /// <param name="descriptor">The field descriptor.</param>
    /// <param name="nodeType">
    /// The schema type of the node.
    /// </param>
    /// <param name="entityType">
    /// The entity type represents the runtime type of the node.
    /// </param>
    /// <param name="resolvePagingProvider">
    /// A delegate that can resolve the correct paging provider for the field.
    /// </param>
    /// <param name="connectionName">
    /// The name of the connection.
    /// </param>
    /// <param name="options">
    /// The paging options.
    /// </param>
    /// <returns>
    /// Returns the field descriptor to allow configuration chaining.
    /// </returns>
    public static IObjectFieldDescriptor UsePaging(
        this IObjectFieldDescriptor descriptor,
        Type?nodeType   = null,
        Type?entityType = null,
        GetCursorPagingProvider?resolvePagingProvider = null,
        NameString?connectionName = null,
        PagingOptions options     = default)
    {
        if (descriptor is null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        resolvePagingProvider ??= ResolvePagingProvider;

        PagingHelper.UsePaging(
            descriptor,
            entityType,
            (services, source, name) => resolvePagingProvider(services, source, name),
            options);

        descriptor
        .Extend()
        .OnBeforeCreate((c, d) =>
        {
            PagingOptions pagingOptions = c.GetSettings(options);
            var backward = pagingOptions.AllowBackwardPagination ?? AllowBackwardPagination;

            CreatePagingArguments(d.Arguments, backward);

            if (connectionName is null or {
                IsEmpty: true
            })
            {
                connectionName =
                    pagingOptions.InferConnectionNameFromField ??
                    InferConnectionNameFromField
                            ? (NameString?)EnsureConnectionNameCasing(d.Name)
                            : null;
            }

            ITypeReference?typeRef = nodeType is not null
                    ? c.TypeInspector.GetTypeRef(nodeType)
                    : null;

            if (typeRef is null &&
                d.Type is SyntaxTypeReference syntaxTypeRef &&
                syntaxTypeRef.Type.IsListType())
            {
                typeRef = syntaxTypeRef.WithType(syntaxTypeRef.Type.ElementType());
            }

            MemberInfo?resolverMember = d.ResolverMember ?? d.Member;
            d.Type = CreateConnectionTypeRef(c, resolverMember, connectionName, typeRef, options);
            d.CustomSettings.Add(typeof(Connection));
        });
Esempio n. 11
0
    /// <summary>
    /// Marks a field as parallel executable which will allow the execution engine
    /// to execute this field in parallel with other resolvers.
    /// </summary>
    public static IObjectFieldDescriptor Parallel(this IObjectFieldDescriptor descriptor)
    {
        if (descriptor is null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        descriptor.Extend().OnBeforeCreate(c => c.IsParallelExecutable = true);
        return(descriptor);
    }
Esempio n. 12
0
    public static IObjectFieldDescriptor Input(
        this IObjectFieldDescriptor descriptor,
        string argumentName = "input",
        string?typeName     = null)
    {
        ExtensionData contextData = descriptor.Extend().Definition.ContextData;

        contextData[InputContextData.Input] = new InputContextData(typeName, argumentName);
        return(descriptor);
    }
Esempio n. 13
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     descriptor.Extend().OnBeforeCreate(
         d => d.Type = new SyntaxTypeReference(
             new NamedTypeNode("IsoTimeSpan"),
             TypeContext.Output));
 }
        public static IObjectFieldDescriptor ID(
            this IObjectFieldDescriptor descriptor,
            NameString typeName = default)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            ResultConverterDefinition placeholder =
                new((_, r) => r, key : WellKnownMiddleware.GlobalId, isRepeatable : false);

            descriptor.Extend().Definition.ResultConverters.Add(placeholder);
            descriptor.Extend().OnBeforeCreate(RewriteObjectFieldType);
            descriptor.Extend().OnBeforeCompletion(
                (c, d) => AddSerializerToObjectField(c, d, placeholder, typeName));

            return(descriptor);
        }
Esempio n. 15
0
    public static IObjectFieldDescriptor Payload(
        this IObjectFieldDescriptor descriptor,
        string?fieldName = null,
        string?typeName  = null)
    {
        ExtensionData contextData = descriptor.Extend().Definition.ContextData;

        contextData[PayloadContextData.Payload] = new PayloadContextData(fieldName, typeName);
        return(descriptor);
    }
Esempio n. 16
0
        public static IObjectFieldDescriptor IsProjected(
            this IObjectFieldDescriptor descriptor,
            bool isProjected = true)
        {
            descriptor
            .Extend()
            .OnBeforeCreate(
                x => x.ContextData[ProjectionConvention.IsProjectedKey] = isProjected);

            return(descriptor);
        }
Esempio n. 17
0
    public static IObjectFieldDescriptor UseDbContext <TDbContext>(
        this IObjectFieldDescriptor descriptor)
        where TDbContext : DbContext
    {
        var scopedServiceName = typeof(TDbContext).FullName ?? typeof(TDbContext).Name;
        FieldMiddlewareDefinition placeholder =
            new(_ => _ => throw new NotSupportedException(), key : WellKnownMiddleware.ToList);

        descriptor.Extend().Definition.MiddlewareDefinitions.Add(
            new(next => async context =>
        {
#if NET6_0_OR_GREATER
            await using TDbContext dbContext = await context.Services
                                               .GetRequiredService <IDbContextFactory <TDbContext> >()
                                               .CreateDbContextAsync()
                                               .ConfigureAwait(false);
#else
            using TDbContext dbContext = context.Services
                                         .GetRequiredService <IDbContextFactory <TDbContext> >()
                                         .CreateDbContext();
#endif

            try
            {
                context.SetLocalValue(scopedServiceName, dbContext);
                await next(context).ConfigureAwait(false);
            }
            finally
            {
                context.RemoveLocalValue(scopedServiceName);
            }
        }, key: WellKnownMiddleware.DbContext));

        descriptor.Extend().Definition.MiddlewareDefinitions.Add(placeholder);

        descriptor
        .Extend()
        .OnBeforeNaming((_, d) => AddCompletionMiddleware(d, placeholder));

        return(descriptor);
    }
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     descriptor
     .Extend()
     .OnBeforeCreate(d =>
     {
         d.Type = ((ClrTypeReference)d.Type).WithScope(Scope);
     });
 }
Esempio n. 19
0
            public static IObjectFieldDescriptor TryAdd(IObjectFieldDescriptor descriptor)
            {
                descriptor.Extend().OnBeforeCreate(d =>
                {
                    if (!d.MiddlewareComponents.Contains(Middleware))
                    {
                        d.MiddlewareComponents.Add(Middleware);
                    }
                });

                return descriptor;
            }
Esempio n. 20
0
 public static void AddDescriptorContextData(this IObjectFieldDescriptor descriptor, IReadOnlyDictionary <string, object> contextBag)
 {
     //var context = descriptor;
     //context.ContextData.TryAdd(key, value);
     descriptor
     .Extend()
     .OnBeforeCreate((descriptorContext, fieldDefinition) =>
     {
         foreach (var(key, value) in contextBag)
         {
             fieldDefinition.ContextData.TryAdd(key, value);
         }
     });
 }
Esempio n. 21
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member)
 {
     if (!string.IsNullOrEmpty(Name))
     {
         descriptor.Extend().OnBeforeCreate(
             d => d.BindToField = new ObjectFieldBinding(
                 Name,
                 ObjectFieldBindingType.Field,
                 Replace));
     }
 }
Esempio n. 22
0
 public static IObjectFieldDescriptor UseAutoSubscription(this IObjectFieldDescriptor descriptor, string subscriptionName)
 {
     descriptor
     .Extend()
     .OnBeforeNaming((configure, defn) =>
     {
         if (!configure.ContextData.ContainsKey(AutoSubscriptionTypeInterceptor.AutoSubscriptionContext))
         {
             configure.ContextData[AutoSubscriptionTypeInterceptor.AutoSubscriptionContext] = new List <ObjectFieldDefinition>();
         }
         ((List <ObjectFieldDefinition>)configure.ContextData[AutoSubscriptionTypeInterceptor.AutoSubscriptionContext]).Add(defn);
     });
     descriptor.Use(next => async context =>
     {
         await next(context);
         await context.SendSimpleSubscription(subscriptionName, context.Result);
     });
     return(descriptor);
 }
        private static void DeclareFields(
            ITypeBindingInfo bindingInfo,
            IReadOnlySchemaOptions schemaOptions,
            IObjectTypeDescriptor typeDescriptor,
            IReadOnlyCollection <FieldDefinitionNode> fieldDefinitions)
        {
            foreach (FieldDefinitionNode fieldDefinition in fieldDefinitions)
            {
                bindingInfo.TrackField(fieldDefinition.Name.Value);

                IObjectFieldDescriptor fieldDescriptor = typeDescriptor
                                                         .Field(fieldDefinition.Name.Value)
                                                         .Description(fieldDefinition.Description?.Value)
                                                         .Type(fieldDefinition.Type)
                                                         .SyntaxNode(schemaOptions.PreserveSyntaxNodes ? fieldDefinition : null);

                if (bindingInfo.TryGetFieldMember(
                        fieldDefinition.Name.Value,
                        MemberKind.ObjectField,
                        out MemberInfo member))
                {
                    fieldDescriptor.Extend().OnBeforeCreate(
                        t => t.Member = member);
                }

                foreach (DirectiveNode directive in fieldDefinition.Directives)
                {
                    if (!directive.IsDeprecationReason())
                    {
                        fieldDescriptor.Directive(directive);
                    }
                }

                string deprecactionReason = fieldDefinition.DeprecationReason();
                if (!string.IsNullOrEmpty(deprecactionReason))
                {
                    fieldDescriptor.Deprecated(deprecactionReason);
                }

                DeclareFieldArguments(schemaOptions, fieldDescriptor, fieldDefinition);
            }
        }
        public static IObjectFieldDescriptor UseOptimizer(
            this IObjectFieldDescriptor descriptor,
            ISelectionSetOptimizer optimizer)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

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

            descriptor
            .Extend()
            .OnBeforeCreate(d => RegisterOptimizer(d.ContextData, optimizer));

            return(descriptor);
        }
        public override void OnConfigure(
            IDescriptorContext context,
            IObjectFieldDescriptor descriptor,
            MemberInfo member)
        {
            descriptor.Extend().OnBeforeCreate(d =>
            {
                ITypeReference typeReference =
                    context.TypeInspector.GetReturnTypeRef(member, TypeContext.Output);

                if (typeReference is ExtendedTypeReference typeRef &&
                    context.TypeInspector.TryCreateTypeInfo(typeRef.Type, out ITypeInfo? typeInfo) &&
                    !typeInfo.IsSchemaType)
                {
                    IExtendedType?rewritten = typeRef.Type.IsArrayOrList
                        ? typeRef.Type.ElementType
                        : null;

                    if (rewritten is null)
                    {
                        throw new SchemaException(
                            SchemaErrorBuilder.New()
                            .SetMessage(
                                "The specified type `{0}` is not a valid subscription type.",
                                typeRef.Type.Source.ToString())
                            .SetExtension("ClrMember", member)
                            .SetExtension("ClrType", member.DeclaringType)
                            .Build());
                    }

                    typeReference = TypeReference.Create(rewritten, TypeContext.Output);
                }

                d.SubscribeResolver = ResolverCompiler.Subscribe.Compile(
                    d.SourceType !, d.ResolverType, member);
                d.Resolver = ctx => new ValueTask <object?>(
                    ctx.GetEventMessage <object>());
                d.Type   = typeReference;
                d.Member = null;
            });
        }
        public override void OnConfigure(
            IDescriptorContext context,
            IObjectFieldDescriptor descriptor,
            MemberInfo member)
        {
            descriptor.Extend().OnBeforeCreate(d =>
            {
                ITypeReference typeReference = context.Inspector.GetReturnType(
                    member, TypeContext.Output);

                if (typeReference is ClrTypeReference clrTypeRef &&
                    !NamedTypeInfoFactory.Default.TryCreate(clrTypeRef.Type, out _))
                {
                    Type rewritten = Unwrap(UnwrapNonNull(Unwrap(clrTypeRef.Type)));
                    rewritten      = GetInnerListType(rewritten);

                    if (rewritten is null)
                    {
                        throw new SchemaException(
                            SchemaErrorBuilder.New()
                            .SetMessage(
                                "The specified type `{0}` is not a valid subscription type.",
                                clrTypeRef.Type.ToString())
                            .SetExtension("ClrMember", member)
                            .SetExtension("ClrType", member.DeclaringType)
                            .Build());
                    }

                    typeReference = TypeReference.Create(rewritten, TypeContext.Output);
                }

                d.SubscribeResolver = ResolverCompiler.Subscribe.Compile(
                    d.SourceType !, d.ResolverType, member);
                d.Resolver = ctx => new ValueTask <object?>(
                    ctx.GetEventMessage <object>());
                d.Type   = typeReference;
                d.Member = null;
            });
        }