Example #1
0
        public void ConfigureField(ComplexGraphType <TModel> graphType, GraphTypeCache cache, IServiceCollection services)
        {
            FieldType field;

            if (TryGetScalarGraphType(out var graphQlType))
            {
                AuthResolver.ValidateGraphqlType(graphQlType, Property);
                field = new FieldType
                {
                    Type     = graphQlType,
                    Name     = Property.Name,
                    Resolver = AuthResolver.GetResolver(services, NameFieldResolver.Instance)
                };
            }
            else
            {
                if (ResolverConfiguration == null)
                {
                    throw new UnableToResolveException(Property, typeof(TModel));
                }

                field          = ResolverConfiguration.ConfigureField(Property, cache, services);
                field.Resolver = AuthResolver.GetResolver(services, field.Resolver);
            }

            var descAttr = Property.GetCustomAttribute <DescriptionAttribute>();

            field.Description = descAttr?.Description;

            var isOutputType      = field.Type?.IsOutputType();
            var isOutputGraphType = field.ResolvedType?.IsOutputType();

            graphType.AddField(field);
        }
Example #2
0
        public void AddNavigationConnectionField <TSource, TReturn>(
            ComplexGraphType <TSource> graph,
            string name,
            Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve = null,
            Type?itemGraphType = null,
            IEnumerable <QueryArgument>?arguments = null,
            IEnumerable <string>?includeNames     = null,
            int pageSize       = 10,
            string?description = null)
            where TReturn : class
        {
            Guard.AgainstNull(nameof(graph), graph);

            Guard.AgainstNullWhiteSpace(nameof(name), name);
            Guard.AgainstNegative(nameof(pageSize), pageSize);

            itemGraphType ??= GraphTypeFinder.FindGraphType <TReturn>();
            var fieldType = GetFieldType <TSource>(name, itemGraphType);

            var builder = ConnectionBuilder <TSource> .Create <FakeGraph>(name);

            if (description != null)
            {
                builder.Description(description);
            }

            builder.PageSize(pageSize).Bidirectional();
            SetField(builder, fieldType);
            IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);

            var hasId = keyNames.ContainsKey(typeof(TReturn));

            if (resolve != null)
            {
                builder.ResolveAsync(async context =>
                {
                    var efFieldContext = BuildContext(context);

                    var enumerable = resolve(efFieldContext);


                    enumerable = enumerable.ApplyGraphQlArguments(hasId, context);
                    enumerable = await efFieldContext.Filters.ApplyFilter(enumerable, context.UserContext);
                    var page   = enumerable.ToList();

                    return(ConnectionConverter.ApplyConnectionContext(
                               page,
                               context.First,
                               context.After,
                               context.Last,
                               context.Before));
                });
            }

            var connection = builder;

            var field = graph.AddField(connection.FieldType);

            field.AddWhereArgument(hasId, arguments);
        }
    void AddEnumerableConnection <TSource, TGraph, TReturn>(
        ComplexGraphType <TSource> graph,
        string name,
        Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve,
        int pageSize,
        string?description,
        IEnumerable <QueryArgument>?arguments,
        IEnumerable <string>?includeNames)
        where TGraph : IGraphType
        where TReturn : class
    {
        var builder = ConnectionBuilder.Create <TGraph, TSource>();

        builder.Name(name);

        if (description is not null)
        {
            builder.Description(description);
        }
        builder.PageSize(pageSize).Bidirectional();
        IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);

        var hasId = keyNames.ContainsKey(typeof(TReturn));

        if (resolve is not null)
        {
            builder.ResolveAsync(async context =>
            {
                var efFieldContext = BuildContext(context);

                var enumerable = resolve(efFieldContext);

                enumerable = enumerable.ApplyGraphQlArguments(hasId, context);
                enumerable = await efFieldContext.Filters.ApplyFilter(enumerable, context.UserContext);
                var page   = enumerable.ToList();

                return(ConnectionConverter.ApplyConnectionContext(
                           page,
                           context.First,
                           context.After,
                           context.Last,
                           context.Before));
            });
        }

        // TODO: works around https://github.com/graphql-dotnet/graphql-dotnet/pull/2581/
        builder.FieldType.Type = typeof(NonNullGraphType <ConnectionType <TGraph, EdgeType <TGraph> > >);
        var field = graph.AddField(builder.FieldType);

        field.AddWhereArgument(hasId, arguments);
    }
Example #4
0
        public static ConnectionBuilder <TSourceType> Connection <TNodeType, TGraphType, TSourceType>(
            this ComplexGraphType <TNodeType> _this, IGraphTypesCache entityDtoCache, TGraphType itemType,
            string prefixName)
            where TGraphType : IGraphType
        {
            var type = entityDtoCache.GetOrCreateConnection(itemType, prefixName);

            var connectionBuilder =
                ConnectionBuilder <TSourceType> .Create <TGraphType>(
                    $"{prefixName}{CommonConstants.GraphQlConnectionSuffix}");

            connectionBuilder.FieldType.ResolvedType = type;
            _this.AddField(connectionBuilder.FieldType);
            return(connectionBuilder);
        }
Example #5
0
 internal static FieldType FieldAsync <TSourceType>(this ComplexGraphType <TSourceType> _this,
                                                    string name,
                                                    string description       = null,
                                                    IGraphType graphType     = null,
                                                    QueryArguments arguments = null,
                                                    Func <IResolveFieldContext <TSourceType>, Task <object> > resolve = null,
                                                    string deprecationReason = null)
 {
     return(_this.AddField(new FieldType
     {
         Name = name,
         Description = description,
         DeprecationReason = deprecationReason,
         ResolvedType = graphType,
         Arguments = arguments,
         Resolver = resolve != null ? new AsyncFieldResolver <TSourceType, object>(resolve) : null
     }));
 }
Example #6
0
        public FieldType AddNavigationField <TSource, TReturn>(
            ComplexGraphType <TSource> graph,
            string name,
            Func <ResolveEfFieldContext <TDbContext, TSource>, TReturn?>?resolve = null,
            Type?graphType = null,
            IEnumerable <string>?includeNames = null,
            string?description = null)
            where TReturn : class
        {
            Guard.AgainstNull(nameof(graph), graph);
            Guard.AgainstNullWhiteSpace(nameof(name), name);

            graphType ??= GraphTypeFinder.FindGraphType <TReturn>();

            FieldType field = new()
            {
                Name        = name,
                Type        = graphType,
                Description = description
            };

            IncludeAppender.SetIncludeMetadata(field, name, includeNames);

            if (resolve != null)
            {
                field.Resolver = new AsyncFieldResolver <TSource, TReturn?>(
                    async context =>
                {
                    var fieldContext = BuildContext(context);

                    var result = resolve(fieldContext);
                    if (await fieldContext.Filters.ShouldInclude(context.UserContext, result))
                    {
                        return(result);
                    }

                    return(null);
                });
            }

            return(graph.AddField(field));
        }
    }
        public FieldType AddNavigationListField <TSource, TReturn>(
            ComplexGraphType <TSource> graph,
            string name,
            Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve = null,
            Type?itemGraphType = null,
            IEnumerable <QueryArgument>?arguments = null,
            IEnumerable <string>?includeNames     = null,
            string?description = null)
            where TReturn : class
        {
            Guard.AgainstNull(nameof(graph), graph);
            Guard.AgainstNullWhiteSpace(nameof(name), name);

            var       hasId = keyNames.ContainsKey(typeof(TReturn));
            FieldType field = new()
            {
                Name        = name,
                Description = description,
                Type        = MakeListGraphType <TReturn>(itemGraphType),
                Arguments   = ArgumentAppender.GetQueryArguments(arguments, hasId, true),
            };

            IncludeAppender.SetIncludeMetadata(field, name, includeNames);

            if (resolve != null)
            {
                field.Resolver = new AsyncFieldResolver <TSource, IEnumerable <TReturn> >(
                    context =>
                {
                    var fieldContext = BuildContext(context);
                    var result       = resolve(fieldContext);
                    result           = result.ApplyGraphQlArguments(hasId, context);
                    return(fieldContext.Filters.ApplyFilter(result, context.UserContext));
                });
            }

            return(graph.AddField(field));
        }