private static IEnumerable <FieldType> GetFieldsForFieldType(string remote, Introspection.TypeElement parentField)
        {
            FieldTypeResolver complexFieldTypeResolver = member =>
            {
                if (!(member is RemoteLiteralGraphTypeMemberInfo literalMember))
                {
                    return(null);
                }

                if (!RemoteServerTypes.TryGetValue(remote, out var remoteTypes))
                {
                    return(null);
                }

                var schemaType = remoteTypes.FirstOrDefault(t => t.Name == literalMember.TypeName);
                var realType   = literalMember.IsList
                    ? typeof(ListGraphType <>).MakeGenericType(schemaType)
                    : schemaType;

                return(new FieldType
                {
                    Name = literalMember.Name,
                    Type = realType,
                    Resolver = LiteralGraphTypeHelpers.CreateFieldResolverFor(literalMember)
                });
            };

            var fields = parentField.Fields;

            if (fields == null)
            {
                return(new FieldType[] { });
            }

            return(fields
                   .Select(field =>
            {
                return new RemoteLiteralGraphTypeMemberInfo
                {
                    DeclaringTypeName = parentField.Name,
                    Name = field.Name,
                    Type = IntrospectionTypeToLiteralGraphTypeMemberInfoType(field.Type),
                    TypeName = IntrospectionTypeToLiteralGraphTypeMemberInfoTypeName(field.Type),
                    IsList = field.Type.Kind == TypeElementTypeKind.List,
                    GetValueFn = ctx =>
                    {
                        return ((JToken)ctx.Source)[field.Name].Value <object>();
                    }
                };
            })
                   // TODO: handle unresolvable types (I'm looking at you UNION)
                   .Where(member => member.Type != LiteralGraphTypeMemberInfoType.Unknown)
                   .Select(member => LiteralGraphTypeHelpers.GetFieldTypeForMember(member, complexFieldTypeResolver))
                   .ToList());
        }
Пример #2
0
        private IEnumerable <FieldType> GetFields()
        {
            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            var members = typeof(T)
                          .GetProperties(bindingFlags)
                          .AsEnumerable <MemberInfo>()
                          .Union(typeof(T).GetFields(bindingFlags))
                          .Select(member =>
            {
                var type = GetTypeForMemberInfo(member);

                return(new TypedLiteralGraphTypeMemberInfo
                {
                    DeclaringTypeName = member.DeclaringType.FullName,
                    Name = member.Name,
                    Type = LiteralGraphTypeHelpers.GetLiteralGraphTypeMemberInfoTypeForType(type),
                    IsList = IsListType(type),
                    ActualType = type,
                    GetValueFn = MakeGetValueFnForMemberInfo(member)
                });
            })
                          .ToList();

            FieldTypeResolver complexTypeResolver = member =>
            {
                if (!(member is TypedLiteralGraphTypeMemberInfo typedMember))
                {
                    return(null);
                }

                var maybeActualType = typedMember.ActualType;
                if (maybeActualType == null)
                {
                    return(null);
                }

                var literalGraphType = typedMember.IsList
                                       // IEnumerable<T> -> ListGraphType<LiteralGraphType<T>>
                    ? typeof(ListGraphType <>).MakeGenericType(typeof(LiteralGraphType <>).MakeGenericType(GetListElementType(maybeActualType)))
                                       // T -> LiteralGraphType<T>
                    : typeof(LiteralGraphType <>).MakeGenericType(maybeActualType);

                return(typeof(LiteralGraphTypeHelpers)
                       .GetMethod(nameof(LiteralGraphTypeHelpers.CreateFieldType), BindingFlags.NonPublic | BindingFlags.Static)
                       .MakeGenericMethod(literalGraphType)
                       .Invoke(null, new[] { member }) as FieldType);
            };

            return(members
                   .Select(member =>
            {
                try
                {
                    // Find the field type
                    var fieldType = LiteralGraphTypeHelpers.GetFieldTypeForMember(member, complexTypeResolver);

                    return fieldType;
                }
                catch (Exception)
                {
                    // TODO: log

                    return null;
                }
            })
                   .ToList());
        }
Пример #3
0
        internal static FieldTypeResolver MakeFieldTypeResolverForMember(LiteralGraphTypeMemberInfo member, FieldTypeResolver complexFieldTypeResolver)
        {
            var type = member.Type;

            if (type == LiteralGraphTypeMemberInfoType.Complex)
            {
                return(complexFieldTypeResolver);
            }

            LiteralGraphTypeMemberInfoFieldTypeResolverMappings.TryGetValue(type, out var resolver);

            return(resolver);
        }
Пример #4
0
 private static void PopulateTypeMapping(LiteralGraphTypeMemberInfoType type, Type actualType, FieldTypeResolver resolver)
 {
     LiteralGraphTypeMemberInfoTypeMappings.TryAdd(type, actualType);
     LiteralGraphTypeMemberInfoFieldTypeResolverMappings.TryAdd(type, resolver);
 }
Пример #5
0
        internal static FieldType GetFieldTypeForMember(LiteralGraphTypeMemberInfo member, FieldTypeResolver complexFieldTypeResolver)
        {
            var memberFieldTypeMapKey = MakeMemberFieldTypeMapKey(member);

            // Try to find an existing FieldType for this member
            if (!MemberFieldTypeMappings.TryGetValue(memberFieldTypeMapKey, out var fieldType))
            {
                // Throw a new FieldType in to indicate we're in the middle of resolving a FieldType
                fieldType = new FieldType();
                MemberFieldTypeMappings.AddOrUpdate(memberFieldTypeMapKey, fieldType, (m, old) => fieldType);

                // Get the fieldtype resolver
                var fieldTypeResolver = GetFieldTypeResolverForMember(member, complexFieldTypeResolver);

                // Execute the resolver
                var actualFieldType = fieldTypeResolver(member);

                // Copy over fields
                PatchFieldType(fieldType, actualFieldType);
            }

            return(fieldType);
        }
Пример #6
0
        internal static FieldTypeResolver GetFieldTypeResolverForMember(LiteralGraphTypeMemberInfo member, FieldTypeResolver complexFieldTypeResolver)
        {
            var memberFieldTypeResolverMapKey = MakeMemberFieldTypeResolverMapKey(member);

            // If we don't already know the fieldtype resolver for this member, we need to figure it out
            if (!MemberFieldTypeResolverMappings.TryGetValue(memberFieldTypeResolverMapKey, out var fieldTypeResolver) || fieldTypeResolver == null)
            {
                // Try to create a new field type resolver
                fieldTypeResolver = MakeFieldTypeResolverForMember(member, complexFieldTypeResolver);
                if (fieldTypeResolver == null)
                {
                    return(null);
                }

                // Save the resolver
                MemberFieldTypeResolverMappings.AddOrUpdate(memberFieldTypeResolverMapKey, fieldTypeResolver, (m, old) => fieldTypeResolver);
            }

            return(fieldTypeResolver);
        }