├── Emrys.SuperConfig ├── Section.cs ├── Mapping │ ├── ITypeMapping.cs │ ├── IPropertyMapping.cs │ ├── Mappingers │ │ ├── BaseMappinger.cs │ │ ├── IMappinger.cs │ │ ├── EntityMappinger.cs │ │ ├── ValueMappinger.cs │ │ ├── ArrayMappinger.cs │ │ ├── ListMappinger.cs │ │ ├── KeyValueMappinger.cs │ │ ├── MappingerSelector.cs │ │ └── DictionaryMappinger.cs │ ├── TypeMapping.cs │ ├── MappingForAttributes.cs │ ├── MappingForElement.cs │ └── MappingFactory.cs ├── Strategy │ ├── IConvertCaseStrategy.cs │ ├── ISuperConfigStrategy.cs │ ├── DefaultConvertCaseStrategy.cs │ ├── SuperConfigStrategyManager.cs │ └── DefaultSuperConfigStrategy.cs ├── Exceptions │ └── SuperConfigException.cs ├── Emrys.SuperConfig.nuspec ├── Properties │ └── AssemblyInfo.cs ├── SuperConfigEngine.cs ├── Emrys.SuperConfig.csproj └── SuperConfig.cs ├── Emrys.SuperConfig.Tests ├── packages.config ├── Cfg │ ├── SectionUserInfo.config │ ├── SetSection.config │ └── UserInfo.config ├── Models │ └── UserInfo.cs ├── Properties │ └── AssemblyInfo.cs ├── App.config ├── SuperConfigTests.cs ├── MappingerTest.cs ├── Emrys.SuperConfig.Tests.csproj └── MappingerTests.cs ├── LICENSE ├── Emrys.SuperConfig.sln ├── README.md └── .gitignore /Emrys.SuperConfig/Section.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Emrys5/Emrys.SuperConfig/HEAD/Emrys.SuperConfig/Section.cs -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/ITypeMapping.cs: -------------------------------------------------------------------------------- 1 | namespace Emrys.SuperConfig.Mapping 2 | { 3 | public interface ITypeMapping 4 | { 5 | void Apply(object instance); 6 | void Add(IPropertyMapping propertyMapping); 7 | } 8 | } -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Cfg/SectionUserInfo.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | http://www.cnblogs.com/emrys5/ 4 | Blue 5 | 2 6 | 7 | 8 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/IPropertyMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Emrys.SuperConfig.Mapping 8 | { 9 | public interface IPropertyMapping 10 | { 11 | void Apply(object instance); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Strategy/IConvertCaseStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Emrys.SuperConfig.Strategy 8 | { 9 | public interface IConvertCaseStrategy 10 | { 11 | string ConvertCase(string name); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/BaseMappinger.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Strategy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Emrys.SuperConfig.Mapping.Mappingers 9 | { 10 | public class BaseMappinger 11 | { 12 | public IConvertCaseStrategy ConvertCaseStrategy { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Strategy/ISuperConfigStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Emrys.SuperConfig.Strategy 9 | { 10 | public interface ISuperConfigStrategy : IConvertCaseStrategy 11 | { 12 | Section GetSection(string sectionName, string filePath = null); 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Cfg/SetSection.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | http://www.cnblogs.com/emrys5/ 5 | Blue 6 | 2 7 | 8 | 9 | a 10 | b 11 | c 12 | d 13 | e 14 | 15 | 16 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Cfg/UserInfo.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | http://www.cnblogs.com/emrys5/ 9 | Blue 10 | 2 11 | 12 | 13 |
-------------------------------------------------------------------------------- /Emrys.SuperConfig/Exceptions/SuperConfigException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Emrys.SuperConfig.Exceptions 5 | { 6 | public class SuperConfigException : Exception 7 | { 8 | public SuperConfigException(string message) 9 | : base(message) 10 | { 11 | } 12 | 13 | public SuperConfigException(string message, Exception innerException) 14 | : base(message, innerException) 15 | { 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Emrys.SuperConfig/Strategy/DefaultConvertCaseStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Emrys.SuperConfig.Strategy 8 | { 9 | public class DefaultConvertCaseStrategy : IConvertCaseStrategy 10 | { 11 | public string ConvertCase(string name) 12 | { 13 | if (string.IsNullOrWhiteSpace(name)) 14 | { 15 | return ""; 16 | } 17 | return name.Substring(0, 1).ToLower() + name.Substring(1); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/IMappinger.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Strategy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Linq; 8 | 9 | namespace Emrys.SuperConfig.Mapping.Mappingers 10 | { 11 | /// 12 | /// xml element所对应的mapping 13 | /// 14 | public interface IMappinger 15 | { 16 | IConvertCaseStrategy ConvertCaseStrategy { get; set; } 17 | 18 | // 执行mapping 19 | object Mapping(XElement element, Type type); 20 | 21 | // 判断类型是否可以装成目标类型 22 | bool IsCanMapping(Type type); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Emrys.SuperConfig.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | $author$ 8 | $author$ 9 | https://github.com/Emrys5/Emrys.SuperConfig/blob/master/LICENSE 10 | https://github.com/Emrys5/Emrys.SuperConfig 11 | false 12 | $description$ 13 | Copyright 2018 14 | Emrys SuperConfig Web.config App.config Section Configuration easy config 15 | 16 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/TypeMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Emrys.SuperConfig.Mapping 8 | { 9 | public class TypeMapping : ITypeMapping 10 | { 11 | private readonly List _propertyMappings = new List(); 12 | 13 | public void Add(IPropertyMapping propertyMapping) 14 | { 15 | _propertyMappings.Add(propertyMapping); 16 | } 17 | 18 | public void Apply(object instance) 19 | { 20 | _propertyMappings.ForEach(mapping => mapping.Apply(instance)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/EntityMappinger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Xml.Linq; 7 | using Emrys.SuperConfig.Strategy; 8 | 9 | namespace Emrys.SuperConfig.Mapping.Mappingers 10 | { 11 | /// 12 | /// 实体Mappinger 13 | /// 14 | public class EntityMappinger : BaseMappinger, IMappinger 15 | { 16 | public bool IsCanMapping(Type type) 17 | { 18 | return false; 19 | } 20 | 21 | public object Mapping(XElement element, Type type) 22 | { 23 | return SuperConfig.Mapping(type, element, ConvertCaseStrategy); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Strategy/SuperConfigStrategyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Emrys.SuperConfig.Strategy 9 | { 10 | //public class SuperConfigStrategyManager 11 | //{ 12 | // public static ISuperConfigStrategy Get(ISuperConfigStrategy superConfigStrategy) 13 | // { 14 | // return Get(typeof(T), superConfigStrategy); 15 | // } 16 | 17 | // public static ISuperConfigStrategy Get(Type type, ISuperConfigStrategy superConfigStrategy) 18 | // { 19 | // return superConfigStrategy ?? new DefaultSuperConfigStrategy(new DefaultConvertCaseStrategy()); 20 | // } 21 | 22 | //} 23 | } 24 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/ValueMappinger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Linq; 8 | 9 | namespace Emrys.SuperConfig.Mapping.Mappingers 10 | { 11 | 12 | /// 13 | /// 直接取值(string,int,bool,int,enum等) 14 | /// 15 | public class ValueMappinger : BaseMappinger, IMappinger 16 | { 17 | public object Mapping(XElement element, Type type) 18 | { 19 | var converter = TypeDescriptor.GetConverter(type); 20 | return converter.ConvertFromInvariantString(element.Value); 21 | } 22 | 23 | public bool IsCanMapping(Type type) 24 | { 25 | var converter = TypeDescriptor.GetConverter(type); 26 | return converter.CanConvertFrom(typeof(string)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Models/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Emrys.SuperConfig.Tests.Models 8 | { 9 | class UserInfo 10 | { 11 | public string UserName { get; set; } 12 | 13 | public string Email { get; set; } 14 | 15 | public int Age { get; set; } 16 | 17 | public string BlogUrl { get; set; } 18 | 19 | public Color FavoriteColor { get; set; } 20 | public Color DislikeColor { get; set; } 21 | 22 | public KeyValuePair Sports { get; set; } 23 | 24 | public List Language { get; set; } 25 | 26 | public List Family { get; set; } 27 | 28 | public UserInfo[] Friends { get; set; } 29 | 30 | public Dictionary Colleagues { get; set; } 31 | 32 | 33 | } 34 | enum Color 35 | { 36 | Red, 37 | Blue, 38 | Black 39 | } 40 | 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Emrys 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Emrys.SuperConfig.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("Emrys.SuperConfig.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("6a4da5be-c5fb-4d56-af00-69e0837a6993")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Emrys.SuperConfig")] 9 | [assembly: AssemblyDescription("It is easier to use configuration in .Net/在.Net中更加容易的使用配置文件。")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Emrys")] 12 | [assembly: AssemblyProduct("Emrys.SuperConfig")] 13 | [assembly: AssemblyCopyright("Copyright © Emrys 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("13f36548-17a7-4198-808c-ddd05925efc1")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 33 | //通过使用 "*",如下所示: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/ArrayMappinger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Xml.Linq; 9 | 10 | namespace Emrys.SuperConfig.Mapping.Mappingers 11 | { 12 | /// 13 | /// List Mappinger 14 | /// 15 | public class ArrayMappinger : BaseMappinger, IMappinger 16 | { 17 | public object Mapping(XElement element, Type type) 18 | { 19 | 20 | var listType = typeof(List<>); 21 | var arrayType = type.GetElementType(); 22 | listType = listType.MakeGenericType(arrayType); 23 | 24 | IMappinger mappinger = MappingerSelector.Get(listType, ConvertCaseStrategy); 25 | 26 | var list = mappinger.Mapping(element, listType); 27 | 28 | 29 | return (Array)listType.GetMethod("ToArray").Invoke(list, null); 30 | 31 | } 32 | 33 | public bool IsCanMapping(Type type) 34 | { 35 | // 是数组而且是一维数组 36 | return type.IsArray && type.GetArrayRank() == 1; 37 | } 38 | } 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Strategy/DefaultSuperConfigStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Emrys.SuperConfig.Strategy 9 | { 10 | public class DefaultSuperConfigStrategy : ISuperConfigStrategy 11 | { 12 | private readonly IConvertCaseStrategy _convertCaseStrategy; 13 | 14 | public DefaultSuperConfigStrategy(IConvertCaseStrategy convertCaseStrategy) 15 | { 16 | _convertCaseStrategy = convertCaseStrategy; 17 | } 18 | 19 | public virtual Section GetSection(string sectionName, string filePath = null) 20 | { 21 | if (filePath == null) 22 | return ConfigurationManager.GetSection(sectionName) as Section; 23 | 24 | var fileMap = new ConfigurationFileMap(filePath); 25 | var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap); 26 | return configuration.GetSection(sectionName) as Section; 27 | } 28 | 29 | 30 | public virtual string ConvertCase(string name) 31 | { 32 | return _convertCaseStrategy.ConvertCase(name); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/MappingForAttributes.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Exceptions; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Xml.Linq; 10 | 11 | namespace Emrys.SuperConfig.Mapping 12 | { 13 | public class MappingForAttributes : IPropertyMapping 14 | { 15 | 16 | readonly XAttribute _attribute; 17 | readonly PropertyInfo _property; 18 | 19 | public MappingForAttributes(XAttribute attribute, PropertyInfo property) 20 | { 21 | _attribute = attribute; 22 | _property = property; 23 | } 24 | public void Apply(object instance) 25 | { 26 | try 27 | { 28 | var value = TypeDescriptor.GetConverter(_property.PropertyType).ConvertFromInvariantString(_attribute.Value); 29 | _property.SetValue(instance, value, null); 30 | } 31 | catch (Exception ex) 32 | { 33 | string msg = $"转换失败,attribute:{_attribute.Name.LocalName},value:{_attribute.Value}。在类型:{instance.GetType()}属性:{_property.Name}。更多详情请参考inner exception."; 34 | throw new SuperConfigException(msg, ex); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/ListMappinger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Xml.Linq; 9 | 10 | namespace Emrys.SuperConfig.Mapping.Mappingers 11 | { 12 | /// 13 | /// List Mappinger 14 | /// 15 | public class ListMappinger : BaseMappinger, IMappinger 16 | { 17 | public object Mapping(XElement element, Type type) 18 | { 19 | // 创建List的实例 20 | var listTypeInstance = (IList)Activator.CreateInstance(type); 21 | 22 | var genericArg = type.GetGenericArguments().Single(); 23 | var mappinger = MappingerSelector.Get(genericArg, ConvertCaseStrategy); 24 | 25 | // 获取所有的element子项 26 | foreach (var item in element.Elements()) 27 | { 28 | var itemMappinger = mappinger.Mapping(item, genericArg); 29 | listTypeInstance.Add(itemMappinger); 30 | } 31 | 32 | return listTypeInstance; 33 | 34 | } 35 | 36 | public bool IsCanMapping(Type type) 37 | { 38 | return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(List<>)); 39 | } 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/MappingForElement.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Exceptions; 2 | using Emrys.SuperConfig.Mapping.Mappingers; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Xml.Linq; 11 | 12 | namespace Emrys.SuperConfig.Mapping 13 | { 14 | public class MappingForElement : IPropertyMapping 15 | { 16 | 17 | private readonly XElement _element; 18 | private readonly PropertyInfo _property; 19 | private readonly IMappinger _mappinger; 20 | 21 | public MappingForElement(XElement element, PropertyInfo property, IMappinger mappinger) 22 | { 23 | _element = element; 24 | _property = property; 25 | _mappinger = mappinger; 26 | } 27 | public void Apply(object instance) 28 | { 29 | try 30 | { 31 | var value = _mappinger.Mapping(_element, _property.PropertyType); 32 | _property.SetValue(instance, value, null); 33 | } 34 | catch (Exception ex) 35 | { 36 | string msg = $"转换失败,element:{_element.Name.LocalName},value:{_element.Value}。在类型:{instance.GetType()}属性:{_property.Name}。更多详情请参考inner exception."; 37 | throw new SuperConfigException(msg, ex); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/KeyValueMappinger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Linq; 8 | 9 | namespace Emrys.SuperConfig.Mapping.Mappingers 10 | { 11 | /// 12 | /// KeyValuePair Mappinger 13 | /// 14 | public class KeyValueMappinger : BaseMappinger, IMappinger 15 | { 16 | public object Mapping(XElement element, Type type) 17 | { 18 | var typeArgs = type.GetGenericArguments(); 19 | var keyValueType = typeof(KeyValueBuild<,>).MakeGenericType(typeArgs); 20 | var keyValueInstance = MappingerSelector.Get(keyValueType, ConvertCaseStrategy).Mapping(element, keyValueType); 21 | var property = keyValueType.GetProperty("KeyValue"); 22 | return property.GetValue(keyValueInstance); 23 | } 24 | 25 | public bool IsCanMapping(Type type) 26 | { 27 | return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>); 28 | } 29 | } 30 | 31 | 32 | /// 33 | /// 创建一个具体的keyvalue类型,用于发射获取值 34 | /// 35 | /// 36 | /// 37 | public class KeyValueBuild 38 | { 39 | public TKey Key { get; set; } 40 | public TValue Value { get; set; } 41 | public KeyValuePair KeyValue 42 | { 43 | get 44 | { 45 | return new KeyValuePair(Key, Value); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2024 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emrys.SuperConfig", "Emrys.SuperConfig\Emrys.SuperConfig.csproj", "{13F36548-17A7-4198-808C-DDD05925EFC1}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emrys.SuperConfig.Tests", "Emrys.SuperConfig.Tests\Emrys.SuperConfig.Tests.csproj", "{6A4DA5BE-C5FB-4D56-AF00-69E0837A6993}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {13F36548-17A7-4198-808C-DDD05925EFC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {13F36548-17A7-4198-808C-DDD05925EFC1}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {13F36548-17A7-4198-808C-DDD05925EFC1}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {13F36548-17A7-4198-808C-DDD05925EFC1}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {6A4DA5BE-C5FB-4D56-AF00-69E0837A6993}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {6A4DA5BE-C5FB-4D56-AF00-69E0837A6993}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {6A4DA5BE-C5FB-4D56-AF00-69E0837A6993}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {6A4DA5BE-C5FB-4D56-AF00-69E0837A6993}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {F7716BF0-C948-4898-A5CC-00029F30773B} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/MappingerSelector.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Exceptions; 2 | using Emrys.SuperConfig.Strategy; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Emrys.SuperConfig.Mapping.Mappingers 10 | { 11 | 12 | /// 13 | /// Mapping选择器 14 | /// 15 | public class MappingerSelector 16 | { 17 | 18 | private static List _mappingers; 19 | 20 | 21 | /// 22 | /// 设置所有的Mappinger 23 | /// 24 | static MappingerSelector() 25 | { 26 | _mappingers = new List { 27 | new ValueMappinger(), 28 | new KeyValueMappinger(), 29 | new ListMappinger(), 30 | new ArrayMappinger(), 31 | new DictionaryMappinger() 32 | }; 33 | } 34 | 35 | 36 | /// 37 | /// 根据类型选择不同的Mappinger 38 | /// 39 | /// 40 | /// 41 | public static IMappinger Get(Type type, IConvertCaseStrategy convertCaseStrategy) 42 | { 43 | var canMappingers = _mappingers.Where(i => i.IsCanMapping(type)).ToList(); 44 | 45 | if (canMappingers.Count > 1) 46 | { 47 | throw new SuperConfigException($"出现多个Mapping选择器!"); 48 | } 49 | 50 | IMappinger mappinger = canMappingers.Count == 0 ? new EntityMappinger() : canMappingers.First(); 51 | mappinger.ConvertCaseStrategy = convertCaseStrategy; 52 | 53 | return mappinger; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/MappingFactory.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Mapping.Mappingers; 2 | using Emrys.SuperConfig.Strategy; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Xml.Linq; 10 | 11 | namespace Emrys.SuperConfig.Mapping 12 | { 13 | public class MappingFactory 14 | { 15 | public static ITypeMapping CreateMapping(Type type, XElement element, IConvertCaseStrategy convertCaseStrategy) 16 | { 17 | 18 | var elementList = element.Elements().ToList(); 19 | var attributeList = element.Attributes().ToList(); 20 | 21 | var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite && p.GetSetMethod(true).IsPublic).ToList(); 22 | 23 | ITypeMapping typeMapping = new TypeMapping(); 24 | 25 | foreach (var item in properties) 26 | { 27 | 28 | var xName = convertCaseStrategy.ConvertCase(item.Name); 29 | 30 | var attribute = attributeList.Where(i => i.Name == xName).FirstOrDefault(); 31 | if (attribute != null) 32 | { 33 | var mappingAttributes = new MappingForAttributes(attribute, item); 34 | typeMapping.Add(mappingAttributes); 35 | continue; 36 | } 37 | 38 | var ele = elementList.Where(i => i.Name == xName).FirstOrDefault(); 39 | if (ele != null) 40 | { 41 | var mappinger = MappingerSelector.Get(item.PropertyType, convertCaseStrategy); 42 | var mappingElement = new MappingForElement(ele, item, mappinger); 43 | typeMapping.Add(mappingElement); 44 | } 45 | } 46 | 47 | return typeMapping; 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 | 15 | http://www.cnblogs.com/emrys5/ 16 | Blue 17 | 2 18 | 19 | 20 | 21 | 22 | 2 23 | Football 24 | 25 | 26 | 7 27 | Jackchen 28 | 29 | 30 | 31 | a 32 | b 33 | c 34 | d 35 | 36 | 37 | 38 | 39 | 40 | 2 41 | b 42 | 43 | 44 | 45 | 46 | 47 | 48 | http://www.cnblogs.com/emrys5/ 49 | Blue 50 | 2 51 | 52 | 53 | 54 | 55 | 56 | http://www.cnblogs.com/emrys5/ 57 | Blue 58 | 2 59 | 60 | 61 | 62 |
-------------------------------------------------------------------------------- /Emrys.SuperConfig/SuperConfigEngine.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Mapping; 2 | using Emrys.SuperConfig.Mapping.Mappingers; 3 | using Emrys.SuperConfig.Strategy; 4 | using System; 5 | using System.Collections.Concurrent; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Xml.Linq; 11 | 12 | namespace Emrys.SuperConfig 13 | { 14 | 15 | /// 16 | /// 配置文件主类 17 | /// 18 | class SuperConfigEngine 19 | { 20 | 21 | /// 22 | /// Mapping配置实体类型。 23 | /// 24 | /// 25 | /// 26 | /// 27 | /// 28 | public T Mapping(string sectionName = null, string filePath = null, ISuperConfigStrategy superConfigStrategy = null) 29 | { 30 | superConfigStrategy = superConfigStrategy ?? new DefaultSuperConfigStrategy(new DefaultConvertCaseStrategy()); 31 | 32 | if (string.IsNullOrWhiteSpace(sectionName)) 33 | { 34 | // 如果传入的sectionName为空,则以类名第一个字母小写查找。 35 | sectionName = superConfigStrategy.ConvertCase(typeof(T).Name); 36 | } 37 | 38 | var xElement = (XElement)superConfigStrategy.GetSection(sectionName, filePath); 39 | 40 | // 执行mapping 41 | return (T)Mapping(typeof(T), xElement, superConfigStrategy); 42 | 43 | } 44 | 45 | /// 46 | /// Mapping配置实体类型。 47 | /// 48 | /// 49 | /// 50 | /// 51 | public object Mapping(Type type, XElement element, IConvertCaseStrategy convertCaseStrategy) 52 | { 53 | 54 | // 获取mappinger选择器 55 | IMappinger mappinger = MappingerSelector.Get(type, convertCaseStrategy); 56 | 57 | convertCaseStrategy = convertCaseStrategy ?? new DefaultConvertCaseStrategy(); 58 | 59 | // 如果不是entity,直接执行返回值 60 | if (!(mappinger is EntityMappinger)) 61 | { 62 | mappinger.ConvertCaseStrategy = convertCaseStrategy; 63 | return mappinger.Mapping(element, type); 64 | } 65 | 66 | 67 | // 创建实例 68 | var instance = Activator.CreateInstance(type); 69 | 70 | // 创建 mapping 71 | ITypeMapping typeMapping = MappingFactory.CreateMapping(type, element, convertCaseStrategy); 72 | 73 | // 执行 74 | typeMapping.Apply(instance); 75 | return instance; 76 | 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Emrys.SuperConfig 2 | 3 | It is easier to use configuration in .Net. 4 | 5 | 在.Net中更加容易的使用配置文件。 6 | 7 | ## Get Started 8 | 9 | ### 0. Install Package Emrys.SuperConfig 10 | ``` 11 | PM>Install-Package Emrys.SuperConfig 12 | ``` 13 | ### 1.A new class name is UserInfo 14 | ``` 15 | class UserInfo 16 | { 17 | public string UserName { get; set; } 18 | public string Email { get; set; } 19 | public int Age { get; set; } 20 | public string BlogUrl { get; set; } 21 | public Color FavoriteColor { get; set; } 22 | public Color DislikeColor { get; set; } 23 | public List Language { get; set; } 24 | 25 | } 26 | enum Color{Red,Blue,Black} 27 | ``` 28 | 29 | 30 | ### 2.Configuration in Web.config/App.config 31 | ``` 32 | 33 | 34 | 35 |
36 |
37 | 38 | http://www.cnblogs.com/emrys5/ 39 | Blue 40 | 2 41 | 42 | Putonghua 43 | Huaipu 44 | English 45 | 46 | 47 |
48 | ``` 49 | 50 | ### 3.Get config 51 | ``` 52 | var user = SuperConfig.Value; 53 | ``` 54 | 55 | Done!!!!! 56 | 57 | 58 | ## English wiki 59 | 1. [Get Started](https://github.com/Emrys5/Emrys.SuperConfig/wiki/1.-Get-Started) 60 | 2. [Support for data types](https://github.com/Emrys5/Emrys.SuperConfig/wiki/2.-Support-for-data-types) 61 | 3. [Custom config file location](https://github.com/Emrys5/Emrys.SuperConfig/wiki/3.-Custom-config-file-location) 62 | 4. [Custom config file naming rules](https://github.com/Emrys5/Emrys.SuperConfig/wiki/4.-Custom-config-file-naming-rules) 63 | 5. [Custom Section format](https://github.com/Emrys5/Emrys.SuperConfig/wiki/5.-Custom-Section-format) 64 | 6. [Custom location, naming rules, and Section format](https://github.com/Emrys5/Emrys.SuperConfig/wiki/6.-Custom-location,-naming-rules,-and-Section-format) 65 | ## Chinese wiki 66 | 1. [开始使用 入门](https://github.com/Emrys5/Emrys.SuperConfig/wiki/1.-%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8-%E5%85%A5%E9%97%A8) 67 | 2. [支持数据类型](https://github.com/Emrys5/Emrys.SuperConfig/wiki/2.-%E6%94%AF%E6%8C%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B) 68 | 3. [自定义配置文件位置](https://github.com/Emrys5/Emrys.SuperConfig/wiki/3.-%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE) 69 | 4. [自定义配置文件命名规则](https://github.com/Emrys5/Emrys.SuperConfig/wiki/4.-%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%91%BD%E5%90%8D%E8%A7%84%E5%88%99) 70 | 5. [自定义Section格式](https://github.com/Emrys5/Emrys.SuperConfig/wiki/5.-%E8%87%AA%E5%AE%9A%E4%B9%89Section%E6%A0%BC%E5%BC%8F) 71 | 6. [ 同时自定义位置、命名规则和Section格式](https://github.com/Emrys5/Emrys.SuperConfig/wiki/6.-%E5%90%8C%E6%97%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BD%8D%E7%BD%AE%E3%80%81%E5%91%BD%E5%90%8D%E8%A7%84%E5%88%99%E5%92%8CSection%E6%A0%BC%E5%BC%8F) 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Mapping/Mappingers/DictionaryMappinger.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Exceptions; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Xml.Linq; 10 | 11 | namespace Emrys.SuperConfig.Mapping.Mappingers 12 | { 13 | /// 14 | /// List Mappinger 15 | /// 16 | public class DictionaryMappinger : BaseMappinger, IMappinger 17 | { 18 | 19 | const string keyName = "Key"; 20 | const string valueName = "Value"; 21 | 22 | public object Mapping(XElement element, Type type) 23 | { 24 | // Dictionary 25 | var listTypeInstance = (IDictionary)Activator.CreateInstance(type); 26 | 27 | var genericArg = type.GetGenericArguments(); 28 | 29 | var keyType = genericArg.First(); 30 | var valueType = genericArg.Last(); 31 | 32 | var mappingerKey = MappingerSelector.Get(keyType, ConvertCaseStrategy); 33 | var mappingerValue = MappingerSelector.Get(valueType, ConvertCaseStrategy); 34 | 35 | var convertCaseKeyName = ConvertCaseStrategy.ConvertCase(keyName); 36 | var convertCaseValueName = ConvertCaseStrategy.ConvertCase(valueName); 37 | 38 | // 获取所有的element子项 39 | foreach (var item in element.Elements()) 40 | { 41 | var key = GetValue(item, mappingerKey, keyType, convertCaseKeyName); 42 | var value = GetValue(item, mappingerValue, valueType, convertCaseValueName); 43 | 44 | if (key != null && value != null) 45 | { 46 | object keyValue = Convert.ChangeType(key, keyType); 47 | object valueValue = Convert.ChangeType(value, valueType); 48 | 49 | if (listTypeInstance.Contains(keyValue)) 50 | { 51 | throw new SuperConfigException("Dictionary key 重复!"); 52 | } 53 | listTypeInstance.Add(keyValue, valueValue); 54 | } 55 | } 56 | 57 | return listTypeInstance; 58 | 59 | } 60 | 61 | public bool IsCanMapping(Type type) 62 | { 63 | return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(Dictionary<,>)); 64 | } 65 | 66 | 67 | /// 68 | /// 获取key value值 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | /// 75 | private object GetValue(XElement element, IMappinger mappinger, Type type, string name) 76 | { 77 | var attribute = element.Attributes().Where(i => i.Name == name).FirstOrDefault(); 78 | if (attribute != null) 79 | { 80 | return attribute.Value; 81 | } 82 | 83 | var ele = element.Elements().Where(i => i.Name == name).FirstOrDefault(); 84 | if (ele != null) 85 | { 86 | return mappinger.Mapping(ele, type); 87 | } 88 | 89 | return null; 90 | } 91 | } 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/Emrys.SuperConfig.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {13F36548-17A7-4198-808C-DDD05925EFC1} 8 | Library 9 | Properties 10 | Emrys.SuperConfig 11 | Emrys.SuperConfig 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /Emrys.SuperConfig/SuperConfig.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Mapping; 2 | using Emrys.SuperConfig.Strategy; 3 | using System; 4 | using System.Collections.Concurrent; 5 | using System.Collections.Generic; 6 | using System.Xml.Linq; 7 | 8 | namespace Emrys.SuperConfig 9 | { 10 | /// 11 | /// SuperClass class 12 | /// 13 | /// 14 | public static class SuperConfig where T : class, new() 15 | { 16 | private static readonly SuperConfigEngine _superConfigEngine = new SuperConfigEngine(); 17 | 18 | private static object _lock = new object(); 19 | private static T _T; 20 | public static T Value 21 | { 22 | get 23 | { 24 | if (_T == null) 25 | { 26 | lock (_lock) 27 | { 28 | if (_T == null) 29 | { 30 | _T = _superConfigEngine.Mapping(); 31 | } 32 | 33 | } 34 | } 35 | return _T; 36 | } 37 | } 38 | 39 | public static void Setting(string sectionName = null, string filePath = null, Func funcConvertCase = null, Func funcSection = null) 40 | { 41 | 42 | IConvertCaseStrategy convertCaseStrategy = 43 | funcConvertCase == null 44 | ? (IConvertCaseStrategy)new DefaultConvertCaseStrategy() 45 | : new SettingConvertCaseStrategy(funcConvertCase); 46 | 47 | ISuperConfigStrategy superConfigStrategy = 48 | funcSection == null 49 | ? (ISuperConfigStrategy)new DefaultSuperConfigStrategy(convertCaseStrategy) 50 | : new SettingSuperConfigStrategy(convertCaseStrategy, funcSection); 51 | 52 | _T = _superConfigEngine.Mapping(sectionName, filePath, superConfigStrategy); 53 | } 54 | 55 | public static void Setting(string sectionName) 56 | { 57 | Setting(sectionName, null, null, null); 58 | } 59 | 60 | public static void SettingFilePath(string filePath) 61 | { 62 | Setting(null, filePath, null, null); 63 | } 64 | 65 | public static void Setting(string filePath, Func funcSection) 66 | { 67 | Setting(null, filePath, null, funcSection); 68 | } 69 | 70 | public static void Setting(Func funcConvertCase) 71 | { 72 | Setting(null, null, funcConvertCase, null); 73 | } 74 | 75 | public static void Setting(string sectionName = null, Func funcConvertCase = null) 76 | { 77 | Setting(sectionName, null, funcConvertCase, null); 78 | } 79 | 80 | /// 81 | /// 获取配置信息 82 | /// 83 | /// XElement对象。 84 | /// 85 | public static T Mapping(XElement element, IConvertCaseStrategy convertCaseStrategy = null) 86 | { 87 | return (T)_superConfigEngine.Mapping(typeof(T), element, convertCaseStrategy); 88 | } 89 | } 90 | 91 | 92 | class SettingConvertCaseStrategy : IConvertCaseStrategy 93 | { 94 | private Func _func = null; 95 | public SettingConvertCaseStrategy(Func func) 96 | { 97 | _func = func; 98 | } 99 | public string ConvertCase(string name) 100 | { 101 | return _func(name); 102 | } 103 | } 104 | 105 | class SettingSuperConfigStrategy : ISuperConfigStrategy 106 | { 107 | 108 | private IConvertCaseStrategy _convertCaseStrategy; 109 | private Func _funcSection; 110 | 111 | public SettingSuperConfigStrategy(IConvertCaseStrategy convertCaseStrategy, Func funcSection) 112 | { 113 | _convertCaseStrategy = convertCaseStrategy; 114 | _funcSection = funcSection; 115 | } 116 | 117 | public string ConvertCase(string name) 118 | { 119 | return _convertCaseStrategy.ConvertCase(name); 120 | } 121 | 122 | public Section GetSection(string sectionName, string filePath = null) 123 | { 124 | return _funcSection(sectionName, filePath, _convertCaseStrategy); 125 | } 126 | } 127 | 128 | 129 | 130 | /// 131 | /// SuperClass class 132 | /// 133 | public static class SuperConfig 134 | { 135 | private static readonly SuperConfigEngine _superConfigEngine = new SuperConfigEngine(); 136 | /// 137 | /// 获取配置信息 138 | /// 139 | /// XElement对象。 140 | /// 141 | public static object Mapping(Type type, XElement element, IConvertCaseStrategy convertCaseStrategy = null) 142 | { 143 | return _superConfigEngine.Mapping(type, element, convertCaseStrategy); 144 | } 145 | 146 | 147 | public static T Mapping(XElement element, IConvertCaseStrategy convertCaseStrategy = null) 148 | { 149 | return (T)Mapping(typeof(T), element, convertCaseStrategy); 150 | } 151 | 152 | 153 | 154 | private static ConcurrentDictionary _dicSimpleType = new ConcurrentDictionary(); 155 | 156 | public static T Mapping(string sectionName, string filePath = null, Func funcConvertCase = null, Func funcSection = null) 157 | { 158 | if (!_dicSimpleType.ContainsKey(sectionName)) 159 | { 160 | IConvertCaseStrategy convertCaseStrategy = 161 | funcConvertCase == null 162 | ? (IConvertCaseStrategy)new DefaultConvertCaseStrategy() 163 | : new SettingConvertCaseStrategy(funcConvertCase); 164 | 165 | ISuperConfigStrategy superConfigStrategy = 166 | funcSection == null 167 | ? (ISuperConfigStrategy)new DefaultSuperConfigStrategy(convertCaseStrategy) 168 | : new SettingSuperConfigStrategy(convertCaseStrategy, funcSection); 169 | 170 | var value = _superConfigEngine.Mapping(sectionName, filePath, superConfigStrategy); 171 | _dicSimpleType.TryAdd(sectionName, value); 172 | } 173 | 174 | return (T)_dicSimpleType[sectionName]; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/SuperConfigTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Emrys.SuperConfig; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.IO; 9 | using Emrys.SuperConfig.Tests.Models; 10 | using System.Xml.Linq; 11 | 12 | namespace Emrys.SuperConfig.Tests 13 | { 14 | [TestClass()] 15 | public class SuperConfigTests 16 | { 17 | [TestMethod()] 18 | public void GettingStarted() 19 | { 20 | var user = SuperConfig.Value; 21 | 22 | 23 | Assert.AreEqual(user.UserName, "Emrys"); 24 | Assert.AreEqual(user.Email, "i@emrys.me"); 25 | Assert.AreEqual(user.Age, 27); 26 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 27 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 28 | Assert.AreEqual(user.DislikeColor, Color.Black); 29 | } 30 | 31 | [TestMethod()] 32 | public void TestKeyValueAndSimpleTypeCache() 33 | { 34 | var sport = SuperConfig.Mapping>("sport"); 35 | var superStar = SuperConfig.Mapping>("superStar"); 36 | Assert.AreEqual(sport.Key, 2); 37 | Assert.AreEqual(sport.Value, "Football"); 38 | Assert.AreEqual(superStar.Key, 7); 39 | Assert.AreEqual(superStar.Value, "Jackchen"); 40 | } 41 | 42 | [TestMethod()] 43 | public void TestListSimple() 44 | { 45 | var listString = SuperConfig.Mapping>("listString"); 46 | Assert.AreEqual(listString.First(), "a"); 47 | Assert.AreEqual(listString.Count, 4); 48 | } 49 | 50 | 51 | [TestMethod()] 52 | public void TestDictionarySimple() 53 | { 54 | var dic = SuperConfig.Mapping>("dictionaryIntString"); 55 | Assert.AreEqual(dic.First().Key, 1); 56 | Assert.AreEqual(dic.Last().Value, "b"); 57 | } 58 | 59 | [TestMethod()] 60 | public void TestSetSectionName() 61 | { 62 | SuperConfig.Setting("user"); 63 | var user = SuperConfig.Value; 64 | 65 | 66 | Assert.AreEqual(user.UserName, "Emrys"); 67 | Assert.AreEqual(user.Email, "i@emrys.me"); 68 | Assert.AreEqual(user.Age, 27); 69 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 70 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 71 | Assert.AreEqual(user.DislikeColor, Color.Black); 72 | } 73 | 74 | [TestMethod()] 75 | public void TestSetConvertCase() 76 | { 77 | SuperConfig.Setting(n => n); 78 | var user = SuperConfig.Value; 79 | 80 | 81 | Assert.AreEqual(user.UserName, "Emrys"); 82 | Assert.AreEqual(user.Email, "i@emrys.me"); 83 | Assert.AreEqual(user.Age, 27); 84 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 85 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 86 | Assert.AreEqual(user.DislikeColor, Color.Black); 87 | } 88 | 89 | [TestMethod()] 90 | public void TestSetConfigFilePath() 91 | { 92 | var configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cfg", "UserInfo.config"); 93 | 94 | SuperConfig.SettingFilePath(configFilePath); 95 | var user = SuperConfig.Value; 96 | 97 | 98 | Assert.AreEqual(user.UserName, "FEmrys"); 99 | Assert.AreEqual(user.Email, "i@emrys.me"); 100 | Assert.AreEqual(user.Age, 17); 101 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 102 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 103 | Assert.AreEqual(user.DislikeColor, Color.Black); 104 | } 105 | 106 | [TestMethod()] 107 | public void TestSetSection() 108 | { 109 | var configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cfg", "SetSection.config"); 110 | 111 | SuperConfig.Setting(configFilePath, (sectionName, filePath, convertCaseStrategy) => 112 | { 113 | XElement xElement = XElement.Load(filePath); 114 | var caseSectionName = convertCaseStrategy.ConvertCase(sectionName); 115 | var sectionElement = xElement.Elements().Where(i => i.Name == caseSectionName).FirstOrDefault(); 116 | if (sectionElement == null) 117 | { 118 | throw new Exception("dot find section:" + sectionName); 119 | } 120 | 121 | return new Section() { XElement = sectionElement }; 122 | }); 123 | var user = SuperConfig.Value; 124 | 125 | 126 | Assert.AreEqual(user.UserName, "CEmrys"); 127 | Assert.AreEqual(user.Email, "i@emrys.me"); 128 | Assert.AreEqual(user.Age, 17); 129 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 130 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 131 | Assert.AreEqual(user.DislikeColor, Color.Black); 132 | } 133 | 134 | 135 | [TestMethod()] 136 | public void TestSetSectionArray() 137 | { 138 | var configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cfg", "SetSection.config"); 139 | 140 | var array = SuperConfig.Mapping("arrayString", configFilePath, null, (sectionName, filePath, convertCaseStrategy) => 141 | { 142 | XElement xElement = XElement.Load(filePath); 143 | var caseSectionName = convertCaseStrategy.ConvertCase(sectionName); 144 | var sectionElement = xElement.Elements().Where(i => i.Name == caseSectionName).FirstOrDefault(); 145 | if (sectionElement == null) 146 | { 147 | throw new Exception("dot find section:" + sectionName); 148 | } 149 | 150 | return new Section() { XElement = sectionElement }; 151 | }); 152 | 153 | Assert.AreEqual(array.First(), "a"); 154 | } 155 | 156 | [TestMethod()] 157 | public void TestSetSectionUserInfo() 158 | { 159 | var configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cfg", "SectionUserInfo.config"); 160 | 161 | SuperConfig.Setting(configFilePath, (sectionName, filePath, convertCaseStrategy) => 162 | { 163 | return new Section() { XElement = XElement.Load(filePath) }; 164 | }); 165 | 166 | var user = SuperConfig.Value; 167 | 168 | 169 | Assert.AreEqual(user.UserName, "SUEmrys"); 170 | } 171 | 172 | 173 | } 174 | } -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/MappingerTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Linq; 8 | 9 | namespace Emrys.SuperConfig.Tests 10 | { 11 | 12 | 13 | [TestClass] 14 | public class MappingerTest 15 | { 16 | 17 | [TestMethod] 18 | public void TestValueAttributes() 19 | { 20 | string xml = "1"; 21 | XElement XElement = XElement.Parse(xml); 22 | TestValueClass testValueClass = SuperConfig.Mapping(typeof(TestValueClass), XElement) as TestValueClass; 23 | 24 | Assert.AreEqual(testValueClass.Name, "Emrys"); 25 | Assert.AreEqual(testValueClass.Age, 18); 26 | } 27 | 28 | 29 | [TestMethod] 30 | public void TestValueElement() 31 | { 32 | string xml = "Emrys18"; 33 | XElement XElement = XElement.Parse(xml); 34 | TestValueClass testValueClass = SuperConfig.Mapping(typeof(TestValueClass), XElement) as TestValueClass; 35 | 36 | Assert.AreEqual(testValueClass.Name, "Emrys"); 37 | Assert.AreEqual(testValueClass.Age, 18); 38 | } 39 | 40 | [TestMethod] 41 | public void TestKeyValue() 42 | { 43 | string xml = @" 44 | 45 | Emrys 46 | 18 47 | 48 | "; 49 | XElement XElement = XElement.Parse(xml); 50 | TestKeyValueClass testValueClass = (TestKeyValueClass)SuperConfig.Mapping(typeof(TestKeyValueClass), XElement); 51 | 52 | Assert.AreEqual(testValueClass.KeyValueTest.Key, "Emrys"); 53 | Assert.AreEqual(testValueClass.KeyValueTest.Value, 18); 54 | } 55 | 56 | 57 | //[TestMethod] 58 | //public void TestKeyValue2() 59 | //{ 60 | // string xml = @" 61 | // 62 | // Emrys 63 | // 18 64 | // 65 | // "; 66 | // XElement XElement = XElement.Parse(xml); 67 | // KeyValuePair testValueClass = SuperConfig>.Mapping(XElement); 68 | 69 | // Assert.AreEqual(testValueClass.Key, "Emrys"); 70 | // Assert.AreEqual(testValueClass.Value, 18); 71 | //} 72 | 73 | 74 | [TestMethod] 75 | public void TestListSimple() 76 | { 77 | string xml = @" 78 | 79 | blue 80 | red 81 | orgin 82 | 83 | "; 84 | XElement XElement = XElement.Parse(xml); 85 | TestListClass t = (TestListClass)SuperConfig.Mapping(typeof(TestListClass), XElement); 86 | 87 | Assert.AreEqual(t.Colors.First(), "blue"); 88 | Assert.AreEqual(t.Colors.Last(), "orgin"); 89 | } 90 | 91 | [TestMethod] 92 | public void TestListModel() 93 | { 94 | string xml = @" 95 | 96 | 1 97 | 1 98 | 1 99 | 100 | "; 101 | 102 | XElement XElement = XElement.Parse(xml); 103 | TestListModel t = (TestListModel)SuperConfig.Mapping(typeof(TestListModel), XElement); 104 | 105 | Assert.AreEqual(t.TestValue.First().Name, "Emrys"); 106 | Assert.AreEqual(t.TestValue.Last().Age, 180); 107 | } 108 | 109 | 110 | [TestMethod] 111 | public void TestArrayModel() 112 | { 113 | string xml = @" 114 | 115 | 1 116 | 1 117 | 1 118 | 119 | "; 120 | 121 | XElement XElement = XElement.Parse(xml); 122 | TestArrayModel t = (TestArrayModel)SuperConfig.Mapping(typeof(TestArrayModel), XElement); 123 | Assert.AreEqual(t.TestValue.First().Name, "Emrys"); 124 | Assert.AreEqual(t.TestValue.Last().Age, 180); 125 | } 126 | 127 | 128 | [TestMethod] 129 | public void TestDictionaryClass() 130 | { 131 | string xml = @" 132 | 133 | 134 | 135 | 136 | 137 | "; 138 | 139 | XElement XElement = XElement.Parse(xml); 140 | 141 | TestDictionaryClass t = SuperConfig.Mapping(XElement); 142 | 143 | 144 | Assert.AreEqual(t.TestDictionary["emrys"].Name, "Emrys"); 145 | Assert.AreEqual(t.TestDictionary["emrys"].Colors, Colors.Blue); 146 | } 147 | } 148 | 149 | 150 | public class TestValueClass 151 | { 152 | public string Name { get; set; } 153 | public int Age { get; set; } 154 | 155 | 156 | public Colors Colors { get; set; } 157 | } 158 | 159 | public enum Colors 160 | { 161 | Red, Blue 162 | } 163 | 164 | public class TestKeyValueClass 165 | { 166 | public KeyValuePair KeyValueTest { get; set; } 167 | } 168 | 169 | 170 | public class TestListClass 171 | { 172 | public List Colors { get; set; } 173 | } 174 | 175 | public class TestListModel 176 | { 177 | public List TestValue { get; set; } 178 | 179 | } 180 | 181 | public class TestArrayModel 182 | { 183 | public TestValueClass[] TestValue { get; set; } 184 | 185 | } 186 | 187 | public class TestDictionaryClass 188 | { 189 | 190 | public Dictionary TestDictionary { get; set; } 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/Emrys.SuperConfig.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6A4DA5BE-C5FB-4D56-AF00-69E0837A6993} 8 | Library 9 | Properties 10 | Emrys.SuperConfig.Tests 11 | Emrys.SuperConfig.Tests 12 | v4.5 13 | 512 14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 10.0 16 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 17 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 18 | False 19 | UnitTest 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll 46 | 47 | 48 | ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Always 71 | 72 | 73 | Always 74 | 75 | 76 | Always 77 | 78 | 79 | 80 | 81 | 82 | 83 | {13F36548-17A7-4198-808C-DDD05925EFC1} 84 | Emrys.SuperConfig 85 | 86 | 87 | 88 | 89 | 90 | 91 | False 92 | 93 | 94 | False 95 | 96 | 97 | False 98 | 99 | 100 | False 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 110 | 111 | 112 | 113 | 114 | 115 | 122 | -------------------------------------------------------------------------------- /Emrys.SuperConfig.Tests/MappingerTests.cs: -------------------------------------------------------------------------------- 1 | using Emrys.SuperConfig.Tests.Models; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Xml.Linq; 9 | 10 | namespace Emrys.SuperConfig.Tests 11 | { 12 | [TestClass] 13 | public class MappingerTests 14 | { 15 | [TestMethod] 16 | public void TestValueAttributes() 17 | { 18 | string xml = @""; 26 | 27 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 28 | 29 | Assert.AreEqual(user.UserName, "Emrys"); 30 | Assert.AreEqual(user.Email, "i@emrys.me"); 31 | Assert.AreEqual(user.Age, 27); 32 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 33 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 34 | Assert.AreEqual(user.DislikeColor, Color.Black); 35 | } 36 | 37 | [TestMethod] 38 | public void TestValueElements() 39 | { 40 | string xml = @" 41 | Emrys 42 | i@emrys.me 43 | 27 44 | http://www.cnblogs.com/emrys5/ 45 | Blue 46 | 2 47 | "; 48 | 49 | 50 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 51 | 52 | Assert.AreEqual(user.UserName, "Emrys"); 53 | Assert.AreEqual(user.Email, "i@emrys.me"); 54 | Assert.AreEqual(user.Age, 27); 55 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 56 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 57 | Assert.AreEqual(user.DislikeColor, Color.Black); 58 | } 59 | 60 | [TestMethod] 61 | public void TestValueAttributesElements() 62 | { 63 | string xml = @" 64 | http://www.cnblogs.com/emrys5/ 65 | Blue 66 | 2 67 | "; 68 | 69 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 70 | 71 | Assert.AreEqual(user.UserName, "Emrys"); 72 | Assert.AreEqual(user.Email, "i@emrys.me"); 73 | Assert.AreEqual(user.Age, 27); 74 | Assert.AreEqual(user.BlogUrl, "http://www.cnblogs.com/emrys5/"); 75 | Assert.AreEqual(user.FavoriteColor, Color.Blue); 76 | Assert.AreEqual(user.DislikeColor, Color.Black); 77 | } 78 | 79 | [TestMethod] 80 | public void TestKeyValueAttributes() 81 | { 82 | string xml = @" 83 | 84 | "; 85 | 86 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 87 | 88 | Assert.AreEqual(user.UserName, "Emrys"); 89 | Assert.AreEqual(user.Email, "i@emrys.me"); 90 | Assert.AreEqual(user.Age, 27); 91 | 92 | Assert.AreEqual(user.Sports.Key, 1); 93 | Assert.AreEqual(user.Sports.Value, "PingPong"); 94 | } 95 | 96 | [TestMethod] 97 | public void TestKeyValueElements() 98 | { 99 | string xml = @" 100 | 101 | 1 102 | PingPong 103 | 104 | "; 105 | 106 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 107 | 108 | Assert.AreEqual(user.UserName, "Emrys"); 109 | Assert.AreEqual(user.Email, "i@emrys.me"); 110 | Assert.AreEqual(user.Age, 27); 111 | 112 | Assert.AreEqual(user.Sports.Key, 1); 113 | Assert.AreEqual(user.Sports.Value, "PingPong"); 114 | } 115 | 116 | [TestMethod] 117 | public void TestKeyValueAttributesElements() 118 | { 119 | string xml = @" 120 | 121 | PingPong 122 | 123 | "; 124 | 125 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 126 | 127 | Assert.AreEqual(user.UserName, "Emrys"); 128 | Assert.AreEqual(user.Email, "i@emrys.me"); 129 | Assert.AreEqual(user.Age, 27); 130 | 131 | Assert.AreEqual(user.Sports.Key, 1); 132 | Assert.AreEqual(user.Sports.Value, "PingPong"); 133 | } 134 | 135 | [TestMethod] 136 | public void TestKeyValueNoEntity() 137 | { 138 | string xml = @" 139 | "; 140 | 141 | KeyValuePair keyValue = SuperConfig.Mapping>(XElement.Parse(xml)); 142 | 143 | Assert.AreEqual(keyValue.Key, 1); 144 | Assert.AreEqual(keyValue.Value, "PingPong"); 145 | 146 | } 147 | 148 | [TestMethod] 149 | public void TestListSimple() 150 | { 151 | string xml = @" 152 | 153 | Putonghua 154 | Huaipu 155 | English 156 | 157 | "; 158 | 159 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 160 | 161 | Assert.AreEqual(user.UserName, "Emrys"); 162 | Assert.AreEqual(user.Email, "i@emrys.me"); 163 | Assert.AreEqual(user.Age, 27); 164 | 165 | Assert.AreEqual(user.Language.First(), "Putonghua"); 166 | Assert.AreEqual(user.Language.Last(), "English"); 167 | } 168 | 169 | [TestMethod] 170 | public void TestList() 171 | { 172 | string xml = @" 173 | 174 | 175 | 176 | ly 177 | ly@qq.com 178 | 30 179 | 180 | 181 | "; 182 | 183 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 184 | 185 | Assert.AreEqual(user.UserName, "Emrys"); 186 | Assert.AreEqual(user.Email, "i@emrys.me"); 187 | Assert.AreEqual(user.Age, 27); 188 | 189 | Assert.AreEqual(user.Family.First().Age, 50); 190 | Assert.AreEqual(user.Family.Last().UserName, "ly"); 191 | } 192 | 193 | [TestMethod] 194 | public void TestListNoEntity() 195 | { 196 | string xml = @" 197 | 1 198 | 2 199 | 3 200 | 4 201 | 5 202 | 6 203 | "; 204 | 205 | var list = SuperConfig.Mapping>(XElement.Parse(xml)); 206 | 207 | Assert.AreEqual(list.First(), 1); 208 | Assert.AreEqual(list.Count, 6); 209 | } 210 | 211 | [TestMethod] 212 | public void TestArray() 213 | { 214 | string xml = @" 215 | 216 | 217 | 218 | wy 219 | ly@qq.com 220 | 30 221 | 222 | 223 | "; 224 | 225 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 226 | 227 | Assert.AreEqual(user.UserName, "Emrys"); 228 | Assert.AreEqual(user.Email, "i@emrys.me"); 229 | Assert.AreEqual(user.Age, 27); 230 | 231 | Assert.AreEqual(user.Friends.First().Age, 35); 232 | Assert.AreEqual(user.Friends.Last().UserName, "wy"); 233 | } 234 | 235 | [TestMethod] 236 | public void TestArrayNoEntity() 237 | { 238 | string xml = @" 239 | 240 | 241 | wy 242 | ly@qq.com 243 | 30 244 | 245 | "; 246 | 247 | var array = SuperConfig.Mapping(XElement.Parse(xml)); 248 | 249 | 250 | Assert.AreEqual(array.First().UserName, "hx"); 251 | Assert.AreEqual(array.Last().Age, 30); 252 | } 253 | 254 | [TestMethod] 255 | public void TestDictionary() 256 | { 257 | string xml = @" 258 | 259 | 260 | 1 261 | 262 | zfx 263 | wy@qq.com 264 | 100 265 | 266 | 267 | 268 | 2 269 | 270 | zk 271 | zk@qq.com 272 | 30 273 | 274 | 275 | 276 | "; 277 | 278 | UserInfo user = SuperConfig.Mapping(XElement.Parse(xml)); 279 | 280 | Assert.AreEqual(user.UserName, "Emrys"); 281 | Assert.AreEqual(user.Email, "i@emrys.me"); 282 | Assert.AreEqual(user.Age, 27); 283 | 284 | Assert.AreEqual(user.Colleagues[1].Age, 100); 285 | Assert.AreEqual(user.Colleagues[1].UserName, "zfx"); 286 | Assert.AreEqual(user.Colleagues[2].Email, "zk@qq.com"); 287 | 288 | 289 | } 290 | 291 | [TestMethod] 292 | public void TestDictionaryNoEntity() 293 | { 294 | string xml = @" 295 | 296 | 1 297 | 298 | zfx 299 | wy@qq.com 300 | 100 301 | 302 | 303 | 304 | 2 305 | 306 | zk 307 | zk@qq.com 308 | 30 309 | 310 | 311 | "; 312 | 313 | var dic = SuperConfig.Mapping>(XElement.Parse(xml)); 314 | 315 | 316 | 317 | Assert.AreEqual(dic[1].Age, 100); 318 | Assert.AreEqual(dic[1].UserName, "zfx"); 319 | Assert.AreEqual(dic[2].Email, "zk@qq.com"); 320 | 321 | 322 | } 323 | 324 | } 325 | } 326 | --------------------------------------------------------------------------------