예제 #1
0
        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);
        }
예제 #2
0
 public Converter(IniConverter parentConverter)
 {
     this.parentConverter = parentConverter;
 }
예제 #3
0
 public Converter(IniConverter parentConverter)
 {
     this.parentConverter = parentConverter;
 }