private object DeserializeSection(IniSection section, Type bindingType, object configSectionModel) { foreach (var kvp in section.Contents) { // Gets all properties of the bound type with an IniPropertyAttribute // which has a name that matches the key we are working on. var candidateProperties = bindingType.GetProperties(SearchFlags) .Select(prop => new { prop, attr = prop.GetCustomAttribute <IniPropertyAttribute>() }) .Where(x => x.attr != null) .Where(x => kvp.Key.Equals(x.attr.Name, StringComparison.OrdinalIgnoreCase)) .ToList(); if (candidateProperties.Count > 1) { throw new IniException($"Multiple candidates for '{section.InternalName}'.'{kvp.Key}'."); } PropertyInfo destProperty; if (candidateProperties.Count == 1) { destProperty = candidateProperties.Single().prop; } else { // Else if there is no suitable IniPropertyAttributes, just // search for a property with a matching name. destProperty = bindingType.GetProperty(kvp.Key, SearchFlags | BindingFlags.IgnoreCase); if (destProperty == null) { Debug.WriteLine($"Type '{bindingType.FullName}' has no suitable property" + $"for '{section.InternalName}'.'{kvp.Key}'"); continue; } } IniListPropertyAttribute listAttr = destProperty.GetCustomAttribute <IniListPropertyAttribute>(); IniConverterAttribute convertAttr = destProperty.GetCustomAttribute <IniConverterAttribute>(); IConverter converter = Converter; // If property has custom converter attribute, create a new instance of it and wrap // it into a IConverter for easy use with existing code. if (convertAttr != null) { if (!typeof(IniConverter).IsAssignableFrom(convertAttr.ConverterType)) { throw new IniException("Provided custom converter is not a subclass of IniConverter."); } IniConverter customConverter = (IniConverter)Activator.CreateInstance(convertAttr.ConverterType, convertAttr.Args); converter = customConverter.ToTypeConverter(); } if (listAttr != null) { converter = new CollectionConverter(converter, listAttr.Separator); } // Do conversion. try { object convertedValue; if (!converter.TryConvertTo(destProperty.PropertyType, kvp.Value, out convertedValue)) { throw new IniException($"['{section.InternalName}'.'{kvp.Key}'] No conversion for property."); } destProperty.SetValue(configSectionModel, convertedValue, null); } catch (NotSupportedException ex) { throw new IniException($"['{section.InternalName}'.'{kvp.Key}'] {ex.Message}"); } } return(configSectionModel); }
public Converter(IniConverter parentConverter) { this.parentConverter = parentConverter; }