Esempio n. 1
0
        /// <summary>
        /// Initializes static members of the <see cref="EnumResolver{T}"/> class.
        /// </summary>
        static EnumResolver()
        {
            var type = typeof(T);

            if (!type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                throw new Exception($"{type.Name} should be enum");
            }

            var names        = Enum.GetNames(type);
            var descriptions = new Dictionary <string, string>();

            foreach (var name in names)
            {
                var property  = type.GetTypeInfo().GetMember(name).FirstOrDefault();
                var attribute = property?.GetCustomAttribute <ApiDescriptionAttribute>();
                if (attribute != null)
                {
                    descriptions[name] = attribute.Description;
                }
            }

            GeneratedType = new ApiEnumType(ApiDescriptionAttribute.GetTypeName(type), names, descriptions);
            hasFlags      = type.GetTypeInfo().GetCustomAttribute <FlagsAttribute>() != null;
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes static members of the <see cref="CollectionResolver{T}"/> class.
        /// </summary>
        static CollectionResolver()
        {
            FilterType = new ApiObjectType($"{ApiDescriptionAttribute.GetTypeName(typeof(T))}_Filter");
            SortType   = new ApiEnumType($"{ApiDescriptionAttribute.GetTypeName(typeof(T))}_Sort");

            var param = Expression.Parameter(typeof(T));

            GetIdValue =
                Expression.Lambda <Func <T, object> >(
                    Expression.Convert(Expression.Property(param, NodeMetaData.KeyProperty), typeof(object)),
                    param).Compile();

            InitializeType();
        }
Esempio n. 3
0
        /// <summary>
        /// Parses the metadata of returning type for the field
        /// </summary>
        /// <param name="type">The original field return type</param>
        /// <param name="attribute">The description attribute</param>
        /// <returns>The type metadata</returns>
        public static TypeMetadata GenerateTypeMetadata(Type type, PublishToApiAttribute attribute)
        {
            var metadata  = new TypeMetadata();
            var asyncType = ApiDescriptionAttribute.CheckType(type, typeof(Task <>));

            if (asyncType != null)
            {
                metadata.IsAsync = true;
                type             = asyncType.GenericTypeArguments[0];
            }

            var converter = (attribute as DeclareFieldAttribute)?.Converter;

            if (attribute.ReturnType != null)
            {
                type = attribute.ReturnType;
                metadata.IsForwarding = true;
            }
            else if (converter != null)
            {
                var valueConverter =
                    converter.GetInterfaces()
                    .FirstOrDefault(
                        i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IValueConverter <>));
                if (valueConverter == null)
                {
                    throw new InvalidOperationException(
                              $"Converter {converter.FullName} should implement the IValueConverter<>");
                }

                type = valueConverter.GenericTypeArguments[0];
                metadata.ConverterType = converter;
            }

            var nullable = ApiDescriptionAttribute.CheckType(type, typeof(Nullable <>));

            if (nullable != null)
            {
                type = nullable.GenericTypeArguments[0];
            }

            var scalarType = CheckScalarType(type);

            metadata.MetaType = EnMetaType.Scalar;
            if (scalarType == EnScalarType.None)
            {
                var enumerable = ApiDescriptionAttribute.CheckType(type, typeof(IEnumerable <>));
                var connection = ApiDescriptionAttribute.CheckType(type, typeof(INodeConnection <>));

                if (connection != null)
                {
                    metadata.MetaType           = EnMetaType.Connection;
                    metadata.RealConnectionType = type;
                    type       = connection.GenericTypeArguments[0];
                    scalarType = CheckScalarType(type);
                }
                else if (enumerable != null)
                {
                    metadata.MetaType = EnMetaType.Array;
                    type       = enumerable.GenericTypeArguments[0];
                    scalarType = CheckScalarType(type);
                }
                else
                {
                    metadata.MetaType = EnMetaType.Object;
                }
            }

            if (scalarType != EnScalarType.None && type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                type = Enum.GetUnderlyingType(type);
            }

            // todo: check forwarding type
            metadata.ScalarType = scalarType;
            metadata.Type       = type;

            if (metadata.ScalarType == EnScalarType.None && !type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                var keyProperty =
                    type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)
                    .FirstOrDefault(p => p.GetCustomAttribute <DeclareFieldAttribute>()?.IsKey == true);
                if (keyProperty != null)
                {
                    metadata.KeyProperty     = keyProperty;
                    metadata.KeyPropertyName = PublishToApiAttribute.GetMemberName(keyProperty);
                }
            }

            var typeName = ApiDescriptionAttribute.GetTypeName(type);

            metadata.TypeName = typeName;
            ////metadata.TypeName = metadata.GetFlags().HasFlag(EnFieldFlags.IsConnection) ? $"{typeName}_Connection" : typeName;
            return(metadata);
        }