/// <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; }
/// <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(); }
/// <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); }