- 声明
- 用法
- 1. 实现自定义Attribute
- 2.标注我们的配置文件
- 3.配置文件示例
- 4.核心处理函数
- 5.使用它
突发奇想的一个处理问题的方法,好不好用不用就仁者见仁智者见智了。
用法 1. 实现自定义Attributenamespace 秃顶韭菜的命名空间
{
public class XmlMapping : Attribute
{
///
/// xml属性地址
///
private string xmlAddress = string.Empty;
///
/// xml中存储值的类型
///
private ParamType xmlType = ParamType.OBJECT;
///
/// 指定参数处理函数
///
private string xmlFunc = string.Empty;
public string XmlAddress { get => xmlAddress; set => xmlAddress = value; }
public ParamType XmlType { get => xmlType; set => xmlType = value; }
public string XmlFunc { get => xmlFunc; set => xmlFunc = value; }
}
public enum ParamType
{
INT=1,
FLOAT=2,
DOUBLE=3,
STRING=4,
OBJECT=5,
USER=6
}
}
2.标注我们的配置文件
namespace 秃顶韭菜的命名空间
{
public class DemoConfig : ICustomizationConfig
{
[XmlMapping(XmlAddress = "//Id", XmlType =ParamType.INT)]
public int Id { get; set; }
[XmlMapping(XmlAddress = "//Code", XmlType = ParamType.STRING)]
public string Code { get; set; }
[XmlMapping(XmlAddress = "//Version", XmlType = ParamType.STRING)]
public string Version { get; set; }
[XmlMapping(XmlAddress = "//TestObject", XmlType = ParamType.USER, XmlFunc= "DemoUserParam")]
public List points { get; set; }
///
/// 示例,对于特殊参数使用自定义解析方法
///
/// 读取自xml的字符串配置信息
/// 注意这里的return类型必须要和你定义的属性类型一致,因为要填充的!
public List DemoUserParam(string xmlStr)
{
string[] pointStrs = xmlStr.Trim().Split('|');
List points = new List();
foreach (string pointStr in pointStrs)
{
string[] x_y = pointStr.Replace('(', ' ').Replace(')', ' ').Trim().Split(',');
if (x_y.Length != 2)
{
throw new Exception("娃,看看配置文件是不是整错了?中英文逗阔号啥的。");
}
else
{
PointF point = new PointF(int.Parse(x_y[0]), int.Parse(x_y[1]));
points.Add(point);
}
}
return points;
}
}
}
3.配置文件示例
4.核心处理函数100 DFT012020-12-31 19:06:00 pigger (1,1)|(2,4)|(3,5)
读取attribute配置参数,并使用反射执行相关功能。
namespace 秃顶韭菜的命名空间
{
public class ConfigReader
{
///
/// 从XML中读取配置
///
/// ICustomizationConfig 自定义的配置文件接口,可以不限定
/// 配置文件路径
/// xml根节点名称
/// 配置文件对象
///
public static bool ReadConfigFromXML(string path, string rootName, ref T configClass)
where T : ICustomizationConfig
{
XmlHelper xmlHelper = new XmlHelper(path, rootName);
Xmldocument xmldocument = xmlHelper.LoadXmldocument();
PropertyInfo[] propertyInfos = configClass.GetType().GetProperties();
foreach (PropertyInfo info in propertyInfos)
{
// TODO 我们假设只使用一个标签,不存在多个,所以用first来获取
XmlMapping mapping = info.GetCustomAttributes().First() as XmlMapping;
if (!string.IsNullOrEmpty(mapping.XmlAddress)) // 读取配置文件的地址
{
string value = xmlHelper.GetInnerText(xmldocument, mapping.XmlAddress);
switch (mapping.XmlType)
{
case ParamType.INT:
int valueInt = int.Parse(value);
info.SetValue(configClass, valueInt);
break;
case ParamType.DOUBLE:
double valueDouble = double.Parse(value);
info.SetValue(configClass, valueDouble);
break;
case ParamType.FLOAT:
float valueFloat = float.Parse(value);
info.SetValue(configClass, valueFloat);
break;
case ParamType.STRING:
info.SetValue(configClass, value);
break;
case ParamType.OBJECT:
info.SetValue(configClass, value);
break;
case ParamType.USER:
if (!string.IsNullOrEmpty(mapping.XmlFunc))
{
MethodInfo methodInfo = configClass.GetType().GetMethod(mapping.XmlFunc);
Object[] param = {value};
object res = methodInfo.Invoke(configClass, param);
info.SetValue(configClass, res);
}
else
{
throw new Exception("自定义处理函数时,XmlFunc指定的函数不能为空!");
}
break;
default:
info.SetValue(configClass, value);
break;
}
}
else
{
throw new Exception("XmlAddress不能为空!");
}
}
return true;
}
}
}
5.使用它
只要在系统启动时调用,将其注入到实例即可,具体什么时候调用构建实例和注入,看应用场景。
DemoConfig config = new DemoConfig(); ConfigReader.ReadConfigFromXML(configPath, rootName, ref config);



