public static TypeMetaInformation BuildTypeMetaInformation(object? @object, Type type, Type originalType, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider? propertyConfigurationProvider, Type[]? usedTypes = null) { usedTypes = (usedTypes ?? new Type[0]).ToArray(); if (usedTypes.Contains(type)) return null; usedTypes = usedTypes.Concat(new[] {type}).ToArray(); var originalTypeName = new Regex(@"`.*").Replace(originalType.Name, ""); type = propertyConfigurationProvider?.TryGetConfiguration(type)?.ResolvedType ?? type; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) return TypeMetaInformation.ForSimpleType(type.GetGenericArguments()[0].Name, isNullable : true); if (IsSimpleType(type)) return TypeMetaInformation.ForSimpleType(type.Name, originalTypeName); var typeName = new Regex(@"`.*").Replace(type.Name, ""); if (typeof(IEnumerable).IsAssignableFrom(type)) { var genericArguments = type.HasElementType ? new[] {type.GetElementType()} : type.GetGenericArguments(); return new TypeMetaInformation { TypeName = typeName, OriginalTypeName = originalTypeName, IsArray = true, Properties = new PropertyMetaInformation[0], GenericTypeArguments = genericArguments .Select(x => BuildTypeMetaInformation(null, x, x, propertyDescriptionBuilder, @object == null ? null : propertyConfigurationProvider, usedTypes)) .ToArray(), }; } return new TypeMetaInformation { TypeName = typeName, OriginalTypeName = originalTypeName, Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(x => BuildPropertyInfo(@object, x, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes)) .ToArray(), GenericTypeArguments = type.GetGenericArguments() .Select(x => BuildTypeMetaInformation(null, x, x, propertyDescriptionBuilder, @object == null ? null : propertyConfigurationProvider, usedTypes)) .ToArray(), }; }
private static PropertyMetaInformation BuildPropertyInfo(object? @object, PropertyInfo propertyInfo, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider? propertyConfigurationProvider, Type[] types) { object? objectProperty; Type propertyType; Type originalPropertyType; if (@object == null) { var customConfiguration = propertyConfigurationProvider?.TryGetConfiguration(propertyInfo); objectProperty = null; propertyType = customConfiguration?.ResolvedType ?? propertyInfo.PropertyType; originalPropertyType = propertyInfo.PropertyType; } else { var customConfiguration = propertyConfigurationProvider?.TryGetConfiguration(@object, propertyInfo); var underlyingProperty = propertyInfo.GetValue(@object); objectProperty = customConfiguration != null ? customConfiguration.StoredToApi(underlyingProperty) : underlyingProperty; var resolvedType = customConfiguration?.ResolvedType ?? propertyInfo.PropertyType; var objectPropertyType = IsSimpleType(resolvedType) ? null : objectProperty?.GetType(); propertyType = objectPropertyType ?? resolvedType; originalPropertyType = underlyingProperty?.GetType() ?? propertyInfo.PropertyType; } var underlyingType = propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? propertyType.GetGenericArguments()[0] : propertyType; var propertyDescription = propertyDescriptionBuilder.Build(propertyInfo, propertyType); return new PropertyMetaInformation { Name = propertyInfo.Name, AvailableFilters = propertyDescription.AvailableFilters, AvailableValues = underlyingType.IsEnum ? Enum.GetNames(underlyingType) : new string[0], IsEditable = propertyInfo.SetMethod != null, IsIdentity = propertyDescription.IsIdentity, IsRequired = propertyDescription.IsRequired, IsSearchable = propertyDescription.IsSearchable, IsSortable = propertyDescription.IsSortable, Type = BuildTypeMetaInformation(objectProperty, propertyType, originalPropertyType, propertyDescriptionBuilder, @object == null ? null : propertyConfigurationProvider, types), }; }
private static PropertyMetaInformation BuildPropertyInfo(object @object, [NotNull] PropertyInfo propertyInfo, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider propertyConfigurationProvider, [NotNull, ItemNotNull] Type[] types) { var customConfiguration = @object == null ? propertyConfigurationProvider.TryGetConfiguration(propertyInfo) : propertyConfigurationProvider.TryGetConfiguration(@object, propertyInfo); var propertyType = customConfiguration?.ResolvedType ?? propertyInfo.PropertyType; var propertyDescription = propertyDescriptionBuilder.Build(propertyInfo, propertyType); return(new PropertyMetaInformation { Name = propertyInfo.Name, AvailableFilters = propertyDescription.AvailableFilters, IsIdentity = propertyDescription.IsIdentity, IsRequired = propertyDescription.IsRequired, IsSearchable = propertyDescription.IsSearchable, IsSortable = propertyDescription.IsSortable, Type = BuildTypeMetaInformation(propertyType, propertyDescriptionBuilder, propertyConfigurationProvider, types), }); }
private static TypeInfo ResolveType(object @object, Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { var realType = Nullable.GetUnderlyingType(type) ?? type; var canBeNull = Nullable.GetUnderlyingType(type) != null; if (realType == typeof(string) || realType == typeof(Guid)) { return(new StringTypeInfo()); } if (realType == typeof(char)) { return(new CharTypeInfo(canBeNull)); } if (realType == typeof(byte)) { return(new ByteTypeInfo(canBeNull)); } if (realType == typeof(sbyte)) { return(new SByteTypeInfo(canBeNull)); } if (realType == typeof(int)) { return(new IntTypeInfo(canBeNull)); } if (realType == typeof(DateTime) || realType == typeof(DateTimeOffset)) { return(new DateTimeTypeInfo(canBeNull)); } if (realType == typeof(long)) { return(new LongTypeInfo(canBeNull)); } if (realType == typeof(short)) { return(new ShortTypeInfo(canBeNull)); } if (realType == typeof(bool)) { return(new BoolTypeInfo(canBeNull)); } if (realType == typeof(byte[])) { return(new ByteArrayTypeInfo()); } if (realType == typeof(decimal) || realType == typeof(double)) { return(new DecimalTypeInfo(canBeNull)); } if (realType.IsEnum) { return(new EnumTypeInfo(canBeNull, Enum.GetNames(realType))); } if (realType.IsArray) { return(new EnumerableTypeInfo(ResolveType(null, realType.GetElementType(), propertyDescriptionBuilder, customPropertyConfigurationProvider))); } if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(List <>)) { return(new EnumerableTypeInfo(ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider))); } if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { return(new DictionaryTypeInfo( ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider), ResolveType(null, realType.GetGenericArguments()[1], propertyDescriptionBuilder, customPropertyConfigurationProvider))); } if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(HashSet <>)) { return(new HashSetTypeInfo(ResolveType(null, realType.GetGenericArguments()[0], propertyDescriptionBuilder, customPropertyConfigurationProvider))); } if (realType.IsClass) { return new ClassTypeInfo { Properties = realType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => ResolveProperty(@object, p, propertyDescriptionBuilder, customPropertyConfigurationProvider)) .ToArray(), } } ; throw new NotSupportedException($"{type.FullName} не поддерживается"); }
public static TypeInfo Extract(object @object, Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { return(ResolveType(@object, type, propertyDescriptionBuilder, customPropertyConfigurationProvider)); }
public static TypeInfo Extract(Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { return(typeInfos.GetOrAdd(type, t => ResolveType(null, t, propertyDescriptionBuilder, customPropertyConfigurationProvider))); }
private static Property ResolveProperty(object @object, PropertyInfo propertyInfo, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { var configuration = @object == null ? customPropertyConfigurationProvider?.TryGetConfiguration(propertyInfo) : customPropertyConfigurationProvider?.TryGetConfiguration(@object, propertyInfo); var typeInfo = ResolveType(null, configuration?.ResolvedType ?? propertyInfo.PropertyType, propertyDescriptionBuilder, customPropertyConfigurationProvider); return(new Property { TypeInfo = typeInfo, Description = propertyDescriptionBuilder.Build(propertyInfo, configuration?.ResolvedType ?? propertyInfo.PropertyType), }); }
private static TypeMetaInformation BuildTypeMetaInformation(object @object, [NotNull] Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider propertyConfigurationProvider, [CanBeNull][ItemNotNull] Type[] usedTypes = null) { usedTypes = (usedTypes ?? new Type[0]).ToArray(); if (usedTypes.Contains(type)) { return(null); } usedTypes = usedTypes.Concat(new[] { type }).ToArray(); if (type.IsArray || type.HasElementType) { return(new TypeMetaInformation { TypeName = type.Name, IsArray = true, ItemType = BuildTypeMetaInformation(type.GetElementType(), propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes), }); } if (type.IsGenericType) { return(new TypeMetaInformation { TypeName = new Regex(@"`.*").Replace(type.GetGenericTypeDefinition().Name, ""), IsArray = true, GenericTypeArguments = type.GetGenericArguments() .Select(x => BuildTypeMetaInformation(x, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes)) .ToArray(), }); } return(new TypeMetaInformation { TypeName = type.Name, Properties = IsSimpleType(type) ? null : type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(x => BuildPropertyInfo(@object, x, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes)) .ToArray(), }); }
public static TypeMetaInformation BuildTypeMetaInformation([NotNull] Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider propertyConfigurationProvider, [CanBeNull][ItemNotNull] Type[] usedTypes = null) { return(BuildTypeMetaInformation(@object: null, type, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes)); }