/// <summary>
    /// Adds the @provides directive which is used to annotate the expected returned
    /// fieldset from a field on a base type that is guaranteed to be selectable by
    /// the gateway.
    ///
    /// <example>
    /// # extended from the Users service
    /// type Review @key(fields: "id") {
    ///     product: Product @provides(fields: "name")
    /// }
    ///
    /// extend type Product @key(fields: "upc") {
    ///     upc: String @external
    ///     name: String @external
    /// }
    /// </example>
    /// </summary>
    /// <param name="descriptor">
    /// The object field descriptor on which this directive shall be annotated.
    /// </param>
    /// <param name="fieldSet">
    /// The fields that are guaranteed to be selectable by the gateway.
    /// Grammatically, a field set is a selection set minus the braces.
    /// </param>
    /// <returns>
    /// Returns the object field descriptor.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="descriptor"/> is <c>null</c>.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// <paramref name="fieldSet"/> is <c>null</c> or <see cref="string.Empty"/>.
    /// </exception>
    public static IObjectFieldDescriptor Provides(
        this IObjectFieldDescriptor descriptor,
        string fieldSet)
    {
        if (descriptor is null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        if (string.IsNullOrEmpty(fieldSet))
        {
            throw new ArgumentException(
                      FieldDescriptorExtensions_Provides_FieldSet_CannotBeNullOrEmpty,
                      nameof(fieldSet));
        }

        return(descriptor.Directive(
                   WellKnownTypeNames.Provides,
                   new ArgumentNode(
                       WellKnownArgumentNames.Fields,
                       new StringValueNode(fieldSet))));
    }
        /// <summary>
        /// Registers the middleware and adds the arguments for filtering
        /// </summary>
        /// <param name="descriptor">The field descriptor where the arguments and middleware are
        /// applied to</param>
        /// <param name="type">Either a runtime type or a <see cref="FilterInputType"/></param>
        /// <param name="scope">Specifies what scope should be used for the
        /// <see cref="FilterConvention" /></param>
        public static IObjectFieldDescriptor UseFiltering(
            this IObjectFieldDescriptor descriptor,
            Type type,
            string?scope = null)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

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

            Type filterType =
                typeof(IFilterInputType).IsAssignableFrom(type)
                    ? type
                    : typeof(FilterInputType <>).MakeGenericType(type);

            return(UseFiltering(descriptor, filterType, null, scope));
        }
Пример #3
0
        /// <summary>
        /// Registers the middleware and adds the arguments for sorting
        /// </summary>
        /// <param name="descriptor">The field descriptor where the arguments and middleware are
        /// applied to</param>
        /// <param name="type">Either a runtime type or a <see cref="SortInputType"/></param>
        /// <param name="scope">Specifies what scope should be used for the
        /// <see cref="SortConvention" /></param>
        public static IObjectFieldDescriptor UseSorting(
            this IObjectFieldDescriptor descriptor,
            Type type,
            string?scope = null)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

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

            Type sortType =
                typeof(ISortInputType).IsAssignableFrom(type)
                    ? type
                    : typeof(SortInputType <>).MakeGenericType(type);

            return(UseSortingInternal(descriptor, sortType, scope));
        }
        public static IObjectFieldDescriptor <T> UseFiltering <T>(
            this IObjectFieldDescriptor <T> descriptor)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (!TypeInspector.Default.TryCreate(
                    typeof(T), out TypeInfo typeInfo))
            {
                // TODO : resources
                throw new ArgumentException(
                          "Cannot handle the specified type.",
                          nameof(descriptor));
            }

            Type filterType =
                typeof(FilterInputType <>).MakeGenericType(typeInfo.ClrType);

            return(UseFiltering(descriptor, filterType));
        }
Пример #5
0
        public static IObjectFieldDescriptor UseDbContext <TDbContext>(
            this IObjectFieldDescriptor descriptor)
            where TDbContext : DbContext
        {
            string          scopedServiceName = typeof(TDbContext).FullName ?? typeof(TDbContext).Name;
            FieldMiddleware placeholder       = next => context => throw new NotSupportedException();

            descriptor
            .Use(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);
                }
            })
            .Use(placeholder)
            .Extend()
            .OnBeforeNaming((c, d) =>
            {
                if (d.ResultType is not null &&
                    typeof(IQueryable).IsAssignableFrom(d.ResultType) &&
                    d.ResultType.IsGenericType)
                {
                    Type entity     = d.ResultType.GenericTypeArguments[0];
                    Type middleware = typeof(ToListMiddleware <>).MakeGenericType(entity);

                    var index = d.MiddlewareComponents.IndexOf(placeholder);
                    d.MiddlewareComponents[index] = Create(middleware);
                }
Пример #6
0
        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 IClrTypeReference 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 = new ClrTypeReference(rewritten, TypeContext.Output);
                }

                d.SubscribeResolver = ResolverCompiler.Subscribe.Compile(
                    d.SourceType, d.ResolverType, member);
                d.Resolver = ctx => Task.FromResult(
                    ctx.CustomProperty <object>(WellKnownContextData.EventMessage));
                d.Type   = typeReference;
                d.Member = null;
            });
        }
Пример #7
0
        private void DeclareFieldArguments(
            IObjectFieldDescriptor fieldDescriptor,
            FieldDefinitionNode fieldDefinition)
        {
            foreach (InputValueDefinitionNode inputFieldDefinition in
                     fieldDefinition.Arguments)
            {
                fieldDescriptor.Argument(inputFieldDefinition.Name.Value,
                                         a =>
                {
                    IArgumentDescriptor descriptor = a.Description(inputFieldDefinition.Description?.Value)
                                                     .Type(inputFieldDefinition.Type)
                                                     .DefaultValue(inputFieldDefinition.DefaultValue)
                                                     .SyntaxNode(inputFieldDefinition);

                    foreach (DirectiveNode directive in
                             inputFieldDefinition.Directives)
                    {
                        descriptor.Directive(directive);
                    }
                });
            }
        }
Пример #8
0
    public static IObjectFieldDescriptor Resolver(
        this IObjectFieldDescriptor descriptor,
        Func <IResolverContext, Task <object?> > resolver)
    {
        if (descriptor is null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

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

        return(descriptor.Resolve(async ctx =>
        {
            Task <object?> resolverTask = resolver(ctx);
            if (resolverTask is null)
            {
                return default;
            }
            return await resolverTask.ConfigureAwait(false);
        }));
    }
Пример #9
0
    public static IObjectFieldDescriptor UseLimitOffsetPaging <TSchemaType>(
        this IObjectFieldDescriptor descriptor)
        where TSchemaType : class
    {
        descriptor
        .Type <PaginationPayloadType <TSchemaType> >()
        .Argument("pageIndex", a => a.Type <IntType>())
        .Argument("pageSize", a => a.Type <IntType>())
        .Use(next => async context =>
        {
            await next(context);

            if (context.Result is IQueryable <TSchemaType> list)
            {
                var paginatedList = await PaginatedList <TSchemaType> .CreateAsync(list,
                                                                                   context.Argument <int>("pageIndex"), context.Argument <int>("pageSize"));
                var result = new PaginationPayload <TSchemaType>(paginatedList.ToList(),
                                                                 paginatedList.HasNextPage, paginatedList.HasPreviousPage);
                context.Result = result;
            }
        });

        return(descriptor);
    }
Пример #10
0
 public static IObjectFieldDescriptor UseDbContext <TDbContext>(
     this IObjectFieldDescriptor descriptor)
     where TDbContext : DbContext =>
 descriptor.UseScopedService(
     create : s => s.GetRequiredService <IDbContextFactory <TDbContext> >().CreateDbContext(),
     disposeAsync : (s, c) => c.DisposeAsync());
 public abstract void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member);
Пример #12
0
        private static IObjectFieldDescriptor UseFiltering(
            IObjectFieldDescriptor descriptor,
            Type?filterType,
            ITypeSystemMember?filterTypeInstance,
            string?scope)
        {
            FieldMiddleware placeholder         = next => context => default;
            string          argumentPlaceholder =
                "_" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);

            descriptor
            .Use(placeholder)
            .Extend()
            .OnBeforeCreate(
                (c, definition) =>
            {
                IFilterConvention convention = c.GetFilterConvention(scope);
                ITypeReference argumentTypeReference;

                if (filterTypeInstance is not null)
                {
                    argumentTypeReference = TypeReference.Create(filterTypeInstance, scope);
                }
                else if (filterType is null)
                {
                    if (definition.ResultType is null ||
                        definition.ResultType == typeof(object) ||
                        !c.TypeInspector.TryCreateTypeInfo(
                            definition.ResultType,
                            out ITypeInfo? typeInfo))
                    {
                        throw new ArgumentException(
                            FilterObjectFieldDescriptorExtensions_UseFiltering_CannotHandleType,
                            nameof(descriptor));
                    }

                    argumentTypeReference = convention.GetFieldType(typeInfo.NamedType);
                }
                else
                {
                    argumentTypeReference = c.TypeInspector.GetTypeRef(
                        filterType,
                        TypeContext.Input,
                        scope);
                }

                var argumentDefinition = new ArgumentDefinition
                {
                    Name = argumentPlaceholder, Type = argumentTypeReference
                };

                definition.Arguments.Add(argumentDefinition);

                definition.Configurations.Add(
                    LazyTypeConfigurationBuilder
                    .New <ObjectFieldDefinition>()
                    .Definition(definition)
                    .Configure(
                        (context, definition) =>
                        CompileMiddleware(
                            context,
                            definition,
                            argumentTypeReference,
                            placeholder,
                            scope))
                    .On(ApplyConfigurationOn.Completion)
                    .DependsOn(argumentTypeReference, true)
                    .Build());

                argumentDefinition.Configurations.Add(
                    LazyTypeConfigurationBuilder
                    .New <ArgumentDefinition>()
                    .Definition(argumentDefinition)
                    .Configure(
                        (context, argumentDefinition) =>
                        argumentDefinition.Name =
                            context.GetFilterConvention(scope).GetArgumentName())
                    .On(ApplyConfigurationOn.Naming)
                    .Build());
            });

            return(descriptor);
        }
 public static IObjectFieldDescriptor UseFirstOrDefault(
     this IObjectFieldDescriptor descriptor) =>
 ApplyMiddleware(descriptor, SelectionOptions.FirstOrDefault, _firstMiddleware);
Пример #14
0
 public virtual void ConfigureField(
     NameString argumentName,
     IObjectFieldDescriptor descriptor)
 {
 }
 public static IObjectFieldDescriptor Use <TMiddleware>(
     this IObjectFieldDescriptor descriptor)
     where TMiddleware : class
 {
     return(descriptor.Use(FieldClassMiddlewareFactory.Create <TMiddleware>()));
 }
 public abstract void OnConfigure(IObjectFieldDescriptor descriptor);
Пример #17
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member) =>
 descriptor.Payload(FieldName, TypeName);
Пример #18
0
 public void ConfigureField(NameString argumentName, IObjectFieldDescriptor descriptor)
 {
     throw new NotImplementedException();
 }
Пример #19
0
        private static IObjectFieldDescriptor UseFiltering(
            IObjectFieldDescriptor descriptor,
            Type filterType,
            ITypeSystemMember filterTypeInstance = null)
        {
            FieldMiddleware placeholder =
                next => context => Task.CompletedTask;

            descriptor
            .Use(placeholder)
            .Extend()
            .OnBeforeCreate(definition =>
            {
                Type argumentType = filterType;

                if (filterType == null)
                {
                    if (!TypeInspector.Default.TryCreate(
                            definition.ResultType, out TypeInfo typeInfo))
                    {
                        // TODO : resources
                        throw new ArgumentException(
                            "Cannot handle the specified type.",
                            nameof(descriptor));
                    }

                    argumentType =
                        typeof(FilterInputType <>).MakeGenericType(
                            typeInfo.ClrType);
                }

                var argumentTypeReference = filterTypeInstance is null
                        ? (ITypeReference) new ClrTypeReference(
                    argumentType, TypeContext.Input)
                        : new SchemaTypeReference(filterTypeInstance);

                if (argumentType == typeof(object))
                {
                    // TODO : resources
                    throw new SchemaException(
                        SchemaErrorBuilder.New()
                        .SetMessage(
                            "The filter type cannot be " +
                            "infered from `System.Object`.")
                        .SetCode(ErrorCodes.Filtering.FilterObjectType)
                        .Build());
                }

                var argumentDefinition  = new ArgumentDefinition();
                argumentDefinition.Name = _whereArgumentName;
                argumentDefinition.Type = new ClrTypeReference(
                    argumentType, TypeContext.Input);
                definition.Arguments.Add(argumentDefinition);

                ILazyTypeConfiguration lazyConfiguration =
                    LazyTypeConfigurationBuilder
                    .New <ObjectFieldDefinition>()
                    .Definition(definition)
                    .Configure((context, defintion) =>
                               CompileMiddleware(
                                   context,
                                   definition,
                                   argumentTypeReference,
                                   placeholder))
                    .On(ApplyConfigurationOn.Completion)
                    .DependsOn(argumentTypeReference, true)
                    .Build();
                definition.Configurations.Add(lazyConfiguration);
            });

            return(descriptor);
        }
 public override void OnConfigure(IDescriptorContext context, IObjectFieldDescriptor descriptor, MemberInfo member)
 {
     descriptor.UseTenantContext <TenantFileContext>();
 }
Пример #21
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member) =>
 descriptor.External();
 public void ConfigFieldDescriptor(IObjectFieldDescriptor descriptor)
 {
     descriptor.Argument("id", a => a.Type <IdType>());
 }
 public static IObjectFieldDescriptor UseSingleOrDefault(
     this IObjectFieldDescriptor descriptor) =>
 ApplyMiddleware(descriptor, SelectionOptions.SingleOrDefault, _singleMiddleware);
Пример #24
0
 public static IObjectFieldDescriptor AddPaginationArguments(this IObjectFieldDescriptor descriptor)
 {
     return(descriptor
            .Argument("pageNumber", a => a.Type <IntType>())
            .Argument("limit", a => a.Type <IntType>()));
 }
 public override void OnConfigure(IDescriptorContext context, IObjectFieldDescriptor descriptor, MemberInfo member)
 {
     descriptor.UseUpperCase();
 }
        public static IObjectFieldDescriptor UseSorting(
            this IObjectFieldDescriptor descriptor,
            Type?sortType,
            ITypeSystemMember?sortTypeInstance = null)
        {
            FieldMiddleware placeholder         = next => context => default;
            string          argumentPlaceholder =
                "_" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);

            descriptor
            .Use(placeholder)
            .Extend()
            .OnBeforeCreate((c, definition) =>
            {
                Type argumentType = GetArgumentType(definition, sortType, c.TypeInspector);

                ITypeReference argumentTypeReference = sortTypeInstance is null
                        ? (ITypeReference)c.TypeInspector.GetTypeRef(
                    argumentType,
                    TypeContext.Input)
                        : TypeReference.Create(sortTypeInstance);

                var argumentDefinition = new ArgumentDefinition
                {
                    Name = argumentPlaceholder,
                    Type = c.TypeInspector.GetTypeRef(argumentType, TypeContext.Input)
                };

                ILazyTypeConfiguration lazyArgumentConfiguration =
                    LazyTypeConfigurationBuilder
                    .New <ArgumentDefinition>()
                    .Definition(argumentDefinition)
                    .Configure((context, definition) =>
                {
                    ISortingNamingConvention convention =
                        context.DescriptorContext.GetSortingNamingConvention();
                    definition.Name = convention.ArgumentName;
                })
                    .On(ApplyConfigurationOn.Completion)
                    .Build();

                argumentDefinition.Configurations.Add(lazyArgumentConfiguration);
                definition.Arguments.Add(argumentDefinition);

                ILazyTypeConfiguration lazyConfiguration =
                    LazyTypeConfigurationBuilder
                    .New <ObjectFieldDefinition>()
                    .Definition(definition)
                    .Configure((context, definition) =>
                               CompileMiddleware(
                                   context,
                                   definition,
                                   argumentTypeReference,
                                   placeholder))
                    .On(ApplyConfigurationOn.Completion)
                    .DependsOn(argumentTypeReference, true)
                    .Build();
                definition.Configurations.Add(lazyConfiguration);
            });

            return(descriptor);
        }
Пример #27
0
 public virtual void ConfigureField(IObjectFieldDescriptor descriptor) =>
 _provider.ConfigureField(_argumentName, descriptor);
Пример #28
0
 /// <summary>
 /// Adds TransactionScope field middleware.
 /// </summary>
 public static IObjectFieldDescriptor UseTransactionScope(
     this IObjectFieldDescriptor descriptor)
 {
     return(descriptor.UseTransactionScope <TransactionScopeFactory>());
 }
Пример #29
0
 public override void OnConfigure(
     IDescriptorContext context,
     IObjectFieldDescriptor descriptor,
     MemberInfo member) =>
 descriptor.UseDbContext <ApplicationDbContext>();
Пример #30
0
 /// <summary>
 /// Adds TransactionScope field middleware.
 /// </summary>
 /// <typeparam name="TFactory">Custom TransactionScope factory class implementing <see cref="ITransactionScopeFactory"/>.</typeparam>
 public static IObjectFieldDescriptor UseTransactionScope <TFactory>(
     this IObjectFieldDescriptor descriptor) where TFactory : ITransactionScopeFactory
 {
     return(descriptor.UseTransactionScope(typeof(TFactory)));
 }