/// <summary> /// Converts source values to <see cref="IPropertyContainer"/> enumeration using schema <typeparamref name="TSchema"/>. /// </summary> /// <typeparam name="TSchema">Schema.</typeparam> /// <param name="values">Source values.</param> /// <param name="settings">Optional settings.</param> /// <param name="configure">Optional configure action.</param> /// <returns>Property container enumeration created from source values.</returns> public static IEnumerable <PropertyContainer <TSchema> > MapToContainers <TSchema>( this IEnumerable values, PropertyContainerMapperSettings?settings = null, Action <PropertyContainerMapperSettings>?configure = null) where TSchema : IPropertySet, new() { if (configure != null) { settings ??= new PropertyContainerMapperSettings(); configure.Invoke(settings); } // Context is same as settings but all properties in context are initialized. var context = new PropertyContainerMappingContext(settings); foreach (var value in values) { yield return(value.MapToContainer <TSchema>(context)); } }
/// <summary> /// Converts source object to <see cref="IPropertyContainer"/> using schema <typeparamref name="TSchema"/>. /// </summary> /// <typeparam name="TSchema">Schema.</typeparam> /// <param name="value">Source object.</param> /// <param name="settings">Optional settings.</param> /// <param name="configure">Optional configure action.</param> /// <returns>Property container created from source object.</returns> public static PropertyContainer <TSchema> MapToContainer <TSchema>( this object value, PropertyContainerMapperSettings?settings = null, Action <PropertyContainerMapperSettings>?configure = null) where TSchema : IPropertySet, new() { // TODO: Exception or diagnostic messages // TODO: IValueFormatter, IConverter // TODO: Convert errors, type mismatch, nullable support if (configure != null) { settings ??= new PropertyContainerMapperSettings(); configure.Invoke(settings); } // Context is same as settings but all properties in context are initialized. var context = new PropertyContainerMappingContext(settings); return(value.MapToContainer <TSchema>(context)); }
/// <summary> /// Converts source object to <see cref="IPropertyContainer"/> using schema <typeparamref name="TSchema"/>. /// </summary> /// <typeparam name="TSchema">Schema.</typeparam> /// <param name="sourceData">Source object.</param> /// <param name="context">Mapping settings.</param> /// <returns>Property container created from source object.</returns> public static PropertyContainer <TSchema> MapToContainer <TSchema>( this object sourceData, PropertyContainerMappingContext context) where TSchema : IPropertySet, new() { context.AssertArgumentNotNull(nameof(context)); var schema = new TSchema(); IProperty[] schemaProperties = schema.GetProperties().ToArray(); var searchOptions = SearchOptions.Default.WithPropertyComparer(context.PropertyComparer); var propertyContainer = new MutablePropertyContainer(searchOptions: searchOptions); PropertyInfo[] propertyInfos = sourceData.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo propertyInfo in propertyInfos) { object?value = propertyInfo.GetValue(sourceData); IProperty propertyFromType = context.PropertyFactory.Create(propertyInfo.PropertyType, propertyInfo.Name); IProperty?schemaProperty = schemaProperties.FirstOrDefault(property => context.PropertyComparer.Equals(property, propertyFromType)); IProperty?propertyToAdd = schemaProperty; if (schemaProperty == null && context.AddPropertiesNotFromSchema) { // Property IsNotFromSchema propertyToAdd = propertyFromType.SetIsNotFromSchema(); } if (propertyToAdd != null) { if (value is not null) { if (value.GetType().IsAssignableTo(propertyToAdd.Type)) { IPropertyValue propertyValue = context.PropertyValueFactory.CreateUntyped(propertyToAdd, value); propertyContainer.Add(propertyValue); } else { object?convertedValue = null; if (propertyToAdd.Type == typeof(string)) { convertedValue = context.ValueFormatter.Format(value, value.GetType()); } else if (value is IConvertible convertible) { convertedValue = convertible.ToType(propertyToAdd.Type, CultureInfo.InvariantCulture); } else { // CAN NOT CONVERT TO SCHEMA TYPE!!! IPropertyValue propertyValue = context.PropertyValueFactory.CreateUntyped(propertyFromType, value); propertyContainer.Add(propertyValue); } if (convertedValue != null) { IPropertyValue propertyValue = context.PropertyValueFactory.CreateUntyped(propertyToAdd, convertedValue); propertyContainer.Add(propertyValue); } } } else { if (context.AddPropertiesWithNullValues) { IPropertyValue propertyValue = context.PropertyValueFactory.CreateUntyped(propertyToAdd, TypeExtensions.GetDefaultValue(propertyToAdd.Type), ValueSource.NotDefined); propertyContainer.Add(propertyValue); } } } } return(new PropertyContainer <TSchema>(sourceValues: propertyContainer, searchOptions: searchOptions)); }