private static object?ParseInternal(Type type, string?value, ICustomPropertyConfigurationProvider propertyConfigurator) { var configuration = propertyConfigurator.TryGetConfiguration(type); var parsedObject = ObjectParser.Parse(configuration?.ResolvedType ?? type, value); return(configuration == null ? parsedObject : configuration.ApiToStored(parsedObject)); }
public SchemaRegistryProvider(ISchemaConfiguration[] schemaConfigurations, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { schemaRegistry = new SchemaRegistry(); foreach (var schemaConfiguration in schemaConfigurations.OrderBy(x => x.Description.SchemaName)) { schemaRegistry.Add(schemaConfiguration.GetSchema(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), }); }
public static void BuildGettersForProperties(Type type, string currentName, Func<object?, object?> currentGetter, List<string> properties, List<Func<object?, object?>> getters, ICustomPropertyConfigurationProvider propertyConfigurationProvider, Type[]? usedTypes = null) { usedTypes = (usedTypes ?? new Type[0]).ToArray(); if (usedTypes.Contains(type) || typeof(IEnumerable).IsAssignableFrom(type)) { properties.Add(currentName); getters.Add(currentGetter); return; } usedTypes = usedTypes.Concat(new[] {type}).ToArray(); foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var propertyConfiguration = propertyConfigurationProvider.TryGetConfiguration(propertyInfo); var propertyType = propertyConfiguration?.ResolvedType ?? propertyInfo.PropertyType; var propertyName = propertyInfo.Name; var propertyGetter = propertyInfo.GetGetMethod(); var name = string.IsNullOrEmpty(currentName) ? propertyName : $"{currentName}.{propertyName}"; Func<object?, object?> getter = x => { var o = currentGetter(x); if (o == null) return null; var propertyValue = propertyGetter.Invoke(o, new object[0]); return propertyConfiguration == null ? propertyValue : propertyConfiguration.StoredToApi(propertyValue); }; if (IsSimpleType(propertyType)) { properties.Add(name); getters.Add(getter); continue; } BuildGettersForProperties(propertyType, name, getter, properties, getters, propertyConfigurationProvider, usedTypes); } }
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(), }); }
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), }); }
public static object StoredToApi(TypeInfo typeInfo, Type type, object o, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { if (o == null) { return(null); } if (!(typeInfo is ClassTypeInfo classTypeInfo)) { return(o); } var result = new Dictionary <string, object>(); foreach (var property in classTypeInfo.Properties) { var propertyInfo = type.GetProperty(property.Description.Name); var propertyValue = propertyInfo.GetValue(o); var customPropertyConfiguration = customPropertyConfigurationProvider?.TryGetConfiguration(o, propertyInfo); if (customPropertyConfiguration != null) { result[property.Description.Name] = StoredToApi(property.TypeInfo, customPropertyConfiguration.ResolvedType, customPropertyConfiguration.StoredToApi(propertyValue), customPropertyConfigurationProvider); } else { result[property.Description.Name] = StoredToApi(property.TypeInfo, propertyInfo.PropertyType, propertyValue, customPropertyConfigurationProvider); } } return(result); }
public static object ApiToStored(TypeInfo typeInfo, Type type, object o, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { var jObject = (JToken)o; if (jObject == null || jObject.ToString() == "") { return(null); } if (!(typeInfo is ClassTypeInfo classTypeInfo)) { return(jObject.ToObject(type)); } var result = Activator.CreateInstance(type); foreach (var property in classTypeInfo.Properties) { var propertyInfo = type.GetProperty(property.Description.Name); var customPropertyConfiguration = customPropertyConfigurationProvider?.TryGetConfiguration(o, propertyInfo); var value = ApiToStored(property.TypeInfo, customPropertyConfiguration?.ResolvedType ?? propertyInfo.PropertyType, jObject.SelectToken(property.Description.Name), customPropertyConfigurationProvider); if (customPropertyConfiguration != null) { value = customPropertyConfiguration.ApiToStored(value); } if (propertyInfo.SetMethod != null) { propertyInfo.SetValue(result, value); } } return(result); }
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))); }
public DownloadFileStream(Type type, object?[] objects, string[] excludedFields, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider, int downloadLimit) { var properties = new List <string>(); var getters = new List <Func <object?, object?> >(); PropertyHelpers.BuildGettersForProperties(type, "", x => x, properties, getters, customPropertyConfigurationProvider); var excludedIndices = properties.Select((x, i) => (x, i)).Where(x => excludedFields.Contains(x.x)).Select(x => x.i).ToArray(); formatter = new CsvFormatter( objects, properties.Where((x, i) => !excludedIndices.Contains(i)).ToArray(), getters.Where((x, i) => !excludedIndices.Contains(i)).ToArray() ); }
public static object SetValue(object obj, string[] path, string?value, ICustomPropertyConfigurationProvider propertyConfigurator) { var objectType = obj.GetType(); if (obj is IList list) { var type = objectType.HasElementType ? objectType.GetElementType() : objectType.GetGenericArguments()[0]; var index = int.Parse(path[0]); var newValue = path.Length == 1 ? ParseInternal(type, value, propertyConfigurator) : SetValue(list[index], path.Skip(1).ToArray(), value, propertyConfigurator); list[index] = newValue; return(obj); } if (obj is IDictionary dictionary) { var args = objectType.GetGenericArguments(); var key = ParseInternal(args[0], path[0], propertyConfigurator); var newValue = path.Length == 1 ? ParseInternal(args[1], value, propertyConfigurator) : SetValue(dictionary[key], path.Skip(1).ToArray(), value, propertyConfigurator); dictionary[key] = newValue; return(obj); } var property = objectType.GetProperty(path[0]); if (property == null) { throw new InvalidOperationException($"Expected type {objectType} to have property {path[0]}"); } var propertyConfiguration = propertyConfigurator.TryGetConfiguration(obj, property); if (propertyConfiguration != null) { if (path.Length == 1) { property.SetValue(obj, propertyConfiguration.ApiToStored(ObjectParser.Parse(propertyConfiguration.ResolvedType, value))); return(obj); } var oldValue = propertyConfiguration.StoredToApi(property.GetValue(obj)); if (oldValue == null) { throw new InvalidOperationException($"Unable to set inner value for property {property.Name} of type {propertyConfiguration.ResolvedType}"); } var intermediateValue = SetValue(oldValue, path.Skip(1).ToArray(), value, propertyConfigurator); var newValue = propertyConfiguration.ApiToStored(intermediateValue); property.SetValue(obj, newValue); return(obj); } var newPropertyValue = path.Length == 1 ? ObjectParser.Parse(property.PropertyType, value) : SetValue(property.GetValue(obj), path.Skip(1).ToArray(), value, propertyConfigurator); property.SetValue(obj, newPropertyValue); return(obj); }
public static Schema GetSchema(this ISchemaConfiguration schemaConfiguration, ICustomPropertyConfigurationProvider customPropertyConfigurationProvider) { var description = schemaConfiguration.Description; if (description.CountLimit == 0) { description.CountLimit = 1000; } if (description.CountLimitForSuperUser == 0) { description.CountLimitForSuperUser = description.CountLimit; } if (description.DownloadLimit == 0) { description.DownloadLimit = 10000; } if (description.DownloadLimitForSuperUser == 0) { description.DownloadLimitForSuperUser = description.DownloadLimit; } return(new Schema { Description = description, Types = schemaConfiguration.Types, ConnectorsFactory = schemaConfiguration.ConnectorsFactory, CustomPropertyConfigurationProvider = customPropertyConfigurationProvider, PropertyDescriptionBuilder = schemaConfiguration.PropertyDescriptionBuilder, }); }
public static TypeMetaInformation BuildTypeMetaInformation([NotNull] Type type, IPropertyDescriptionBuilder propertyDescriptionBuilder, ICustomPropertyConfigurationProvider propertyConfigurationProvider, [CanBeNull][ItemNotNull] Type[] usedTypes = null) { return(BuildTypeMetaInformation(@object: null, type, propertyDescriptionBuilder, propertyConfigurationProvider, usedTypes)); }