public static void SaveIniSectionToWriter(TextWriter writer, IniSection section, bool onlyProperties) { section.BeforeSave(); Type classType = section.GetType(); Attribute[] classAttributes = Attribute.GetCustomAttributes(classType); foreach (Attribute attribute in classAttributes) { if (attribute is IniSectionAttribute) { IniSectionAttribute iniSectionAttribute = (IniSectionAttribute)attribute; if (!onlyProperties) { writer.WriteLine("; {0}", iniSectionAttribute.Description); } writer.WriteLine("[{0}]", iniSectionAttribute.Name); // Iterate over the members and fill them List <MemberInfo> members = new List <MemberInfo>(); foreach (FieldInfo fieldInfo in classType.GetFields()) { members.Add(fieldInfo); } foreach (PropertyInfo propertyInfo in classType.GetProperties()) { members.Add(propertyInfo); } foreach (MemberInfo member in members) { if (Attribute.IsDefined(member, typeof(IniPropertyAttribute))) { IniPropertyAttribute iniPropertyAttribute = (IniPropertyAttribute)member.GetCustomAttributes(typeof(IniPropertyAttribute), false)[0]; if (!onlyProperties) { writer.WriteLine("; {0}", iniPropertyAttribute.Description); } object value; Type valueType; if (member is FieldInfo) { value = ((FieldInfo)member).GetValue(section); valueType = ((FieldInfo)member).FieldType; } else if (member is PropertyInfo) { value = ((PropertyInfo)member).GetValue(section, null); valueType = ((PropertyInfo)member).PropertyType; } else { continue; } if (value == null) { value = iniPropertyAttribute.DefaultValue; valueType = typeof(string); } if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(List <>)) { Type specificValueType = valueType.GetGenericArguments()[0]; writer.Write("{0}=", iniPropertyAttribute.Name); int listCount = (int)valueType.GetProperty("Count").GetValue(value, null); // Loop though generic list for (int index = 0; index < listCount; index++) { object item = valueType.GetMethod("get_Item").Invoke(value, new object[] { index }); // Now you have an instance of the item in the generic list if (index < listCount - 1) { writer.Write("{0}" + iniPropertyAttribute.Separator, ConvertValueToString(specificValueType, item)); } else { writer.Write("{0}", ConvertValueToString(specificValueType, item)); } } writer.WriteLine(); } else if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { // Handle dictionaries. Type valueType1 = valueType.GetGenericArguments()[0]; Type valueType2 = valueType.GetGenericArguments()[1]; // Get the methods we need to deal with dictionaries. var keys = valueType.GetProperty("Keys").GetValue(value, null); var item = valueType.GetProperty("Item"); var enumerator = keys.GetType().GetMethod("GetEnumerator").Invoke(keys, null); var moveNext = enumerator.GetType().GetMethod("MoveNext"); var current = enumerator.GetType().GetProperty("Current").GetGetMethod(); // Get all the values. while ((bool)moveNext.Invoke(enumerator, null)) { var key = current.Invoke(enumerator, null); var valueObject = item.GetValue(value, new object[] { key }); // Write to ini file! writer.WriteLine("{0}.{1}={2}", iniPropertyAttribute.Name, ConvertValueToString(valueType1, key), ConvertValueToString(valueType2, valueObject)); } } else { writer.WriteLine("{0}={1}", iniPropertyAttribute.Name, ConvertValueToString(valueType, value)); } } } } section.AfterSave(); } }
private static void FillIniSection(IniSection section) { Type iniSectionType = section.GetType(); string sectionName = getSectionName(iniSectionType); // Get the properties for the section Dictionary <string, string> properties = null; if (sections.ContainsKey(sectionName)) { properties = sections[sectionName]; } else { sections.Add(sectionName, new Dictionary <string, string>()); properties = sections[sectionName]; } // Iterate over the members and fill them List <MemberInfo> members = new List <MemberInfo>(); foreach (FieldInfo fieldInfo in iniSectionType.GetFields()) { members.Add(fieldInfo); } foreach (PropertyInfo propertyInfo in iniSectionType.GetProperties()) { members.Add(propertyInfo); } foreach (MemberInfo field in members) { if (Attribute.IsDefined(field, typeof(IniPropertyAttribute))) { IniPropertyAttribute iniPropertyAttribute = (IniPropertyAttribute)field.GetCustomAttributes(typeof(IniPropertyAttribute), false)[0]; string propertyName = iniPropertyAttribute.Name; string propertyDefaultValue = iniPropertyAttribute.DefaultValue; string fieldSeparator = iniPropertyAttribute.Separator; // Get the type, or the underlying type for nullables Type valueType; if (field is FieldInfo) { valueType = ((FieldInfo)field).FieldType; } else if (field is PropertyInfo) { valueType = ((PropertyInfo)field).PropertyType; } else { continue; } // Get the value from the ini file, if there is none take the default if (!properties.ContainsKey(propertyName) && propertyDefaultValue != null) { // Mark as dirty, we didn't use properties from the file (even defaults from the default file are allowed) section.IsDirty = true; //LOG.Debug("Passing default: " + propertyName + "=" + propertyDefaultValue); } // Try to get the field value from the properties or use the default value object fieldValue = null; try { fieldValue = CreateValue(valueType, section, sectionName, propertyName, propertyDefaultValue, fieldSeparator); } catch (Exception) { //LOG.Warn("Couldn't parse field: " + sectionName + "." + propertyName, e); } // If still no value, e.g. due to an exception, check if the GetDefault delivers a value if (fieldValue == null) { // Use GetDefault to fill the field if none is set fieldValue = section.GetDefault(propertyName); } // Still no value? Log warning if (fieldValue == null) { LOG.WarnFormat("Property {0} has no value or default value.", propertyName); } // Set the value try { if (field is FieldInfo) { ((FieldInfo)field).SetValue(section, fieldValue); } else if (field is PropertyInfo) { ((PropertyInfo)field).SetValue(section, fieldValue, null);; } } catch (Exception) { //LOG.Warn("Couldn't set field: " + sectionName + "." + propertyName, e); } } } section.AfterLoad(); }