/// <summary>读取配置文件</summary> /// <param name="fileName">文件名</param> /// <param name="section">配置段</param> protected override void OnRead(String fileName, IConfigSection section) { var lines = File.ReadAllLines(fileName); var currentSection = section; var remark = ""; foreach (var item in lines) { var str = item.Trim(); if (str.IsNullOrEmpty()) { continue; } // 读取注释 if (str[0] is '#' or ';') { remark = str.TrimStart('#', ';').Trim(); continue; } if (str[0] == '[' && str[^ 1] == ']') { currentSection = section.GetOrAddChild(str.Trim('[', ']')); currentSection.Comment = remark; } else { var p = str.IndexOf('='); if (p > 0) { var name = str[..p].Trim();
/// <summary>从实例公有属性映射到配置树</summary> /// <param name="section"></param> /// <param name="model"></param> public static void MapFrom(this IConfigSection section, Object model) { if (section == null) { return; } // 反射公有实例属性 foreach (var pi in model.GetType().GetProperties(true)) { if (!pi.CanRead || !pi.CanWrite) { continue; } //if (pi.GetIndexParameters().Length > 0) continue; //if (pi.GetCustomAttribute<IgnoreDataMemberAttribute>(false) != null) continue; //if (pi.GetCustomAttribute<XmlIgnoreAttribute>() != null) continue; var name = SerialHelper.GetName(pi); if (name.EqualIgnoreCase("ConfigFile", "IsNew")) { continue; } // 名称前面加上命名空间 var cfg = section.GetOrAddChild(name); // 反射获取属性值 var val = pi.GetValue(model, null); var att = pi.GetCustomAttribute <DescriptionAttribute>(); cfg.Comment = att?.Description; if (cfg.Comment.IsNullOrEmpty()) { var att2 = pi.GetCustomAttribute <DisplayNameAttribute>(); cfg.Comment = att2?.DisplayName; } //!! 即使模型字段值为空,也必须拷贝,否则修改设置时,无法清空某字段 //if (val == null) continue; // 分别处理基本类型、数组类型、复杂类型 if (pi.PropertyType.GetTypeCode() != TypeCode.Object) { cfg.SetValue(val); } else if (pi.PropertyType.As <IList>()) { if (val is IList list) { MapArray(section, cfg, list, pi.PropertyType.GetElementTypeEx()); } } else { // 递归映射 MapFrom(cfg, val); } } }
/// <summary>字典映射到配置树</summary> /// <param name="src"></param> /// <param name="section"></param> protected virtual void Map(IDictionary <String, Object> src, IConfigSection section) { foreach (var item in src) { var name = item.Key; if (name[0] == '#') { continue; } var cfg = section.GetOrAddChild(name); var cname = "#" + name; if (src.TryGetValue(cname, out var comment) && comment != null) { cfg.Comment = comment + ""; } // 支持字典 if (item.Value is IDictionary <String, Object> dic) { Map(dic, cfg); } else if (item.Value is IList <Object> list) { cfg.Childs = new List <IConfigSection>(); foreach (var elm in list) { // 复杂对象 if (elm is IDictionary <String, Object> dic2) { var cfg2 = new ConfigSection(); Map(dic2, cfg2); cfg.Childs.Add(cfg2); } // 简单基元类型 else { var cfg2 = new ConfigSection { Key = elm?.GetType()?.Name, Value = elm + "", }; cfg.Childs.Add(cfg2); } } } else { cfg.SetValue(item.Value); } } }
/// <summary>读取配置文件</summary> /// <param name="fileName">文件名</param> /// <param name="section">配置段</param> protected override void OnRead(String fileName, IConfigSection section) { var lines = File.ReadAllLines(fileName); var currentSection = section; var remark = ""; foreach (var item in lines) { var str = item.Trim(); if (str.IsNullOrEmpty()) { continue; } // 读取注释 if (str[0] == '#' || str[0] == ';') { remark = str.TrimStart('#', ';').Trim(); continue; } if (str[0] == '[' && str[str.Length - 1] == ']') { currentSection = section.GetOrAddChild(str.Trim('[', ']')); currentSection.Comment = remark; } else { var p = str.IndexOf('='); if (p > 0) { var name = str.Substring(0, p).Trim(); // 构建配置值和注释 var cfg = currentSection.AddChild(name); if (p + 1 < str.Length) { cfg.Value = str.Substring(p + 1).Trim(); } cfg.Comment = remark; } } // 清空注释 remark = null; } }