• 利用反射进行xml文件配置参数管理


    引言:

        系统越来越大,配置文件越来越多。之前一直采用直接从xml文件里读取的方式:   

       XmlDocument doc = new XmlDocument();
           string fileName =  Application.StartupPath+@"\Settings\SystemConfig.xml";
           doc.Load(fileName);
           XmlNode SystemIDXml = doc.SelectSingleNode(@"ROOT/SystemID");
       return SystemIDXml .InnerText.Trim();

       使用时不方便,还容易因写错节点名称,形成bug。   

       并且每次系统升级,都还得写语句对原有配置文件节点进行升级,很是痛苦不堪。

       前几天终于忍受不了,琢磨了一下,遂利用反射,完成配置文件的管理。

      直接上码。

      正文:

     1、首先声明该配置文件类,叶子节点需采用属性形式。下面是示例.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Reflection;
    
    namespace Settings
    {
        public class ManagementSystemConfig
        {
            public class PageTime
            {
                public DateTime? BeginTime { get; set; }
                public DateTime? EndTime { get; set; }
                public int? DayGap { get; set; }
            }
            public PageTime BillPageTime = new PageTime();
    
            public string DepartmentID { get; set; }
    
    
            public class PrintSetting
            {
                public PrintSetting()
                {
                    //设置初始值
                    IsCombine = true;
                }
                public bool IsCombine { get; set; }
                public string TempletName { get; set; }
                public string PrinterName { get; set; }
                public string PaperName { get; set; }
                public string Orientation { get; set; }
                public double? Left { get; set; }
                public double? Right { get; set; }
                public double? Top { get; set; }
                public double? Bottom { get; set; }
            }
            public PrintSetting EnterPrintSetting = new PrintSetting();
            public PrintSetting OutPrintSetting = new PrintSetting();
    
    
            public void getProperties(string fullPathName)
            {
                XmlDocument xml = new XmlDocument();
                xml.Load(fullPathName);
                XmlNodeList xmList = xml.SelectSingleNode("Root").ChildNodes;
                Common.XmlSetting.MyXmlByReflection.GetPropertiesValue(this, xml.SelectSingleNode("Root"), "");
            }
    
    
            public void checkXml(string fullPathName)
            {
                XmlDocument xml = new XmlDocument();
                if (!System.IO.File.Exists(fullPathName))
                {
                    XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "utf-8", null);
                    xml.AppendChild(dec);
                    XmlElement root = xml.CreateElement("Root");
                    xml.AppendChild(root);
                    xml.Save(fullPathName);
                }
                xml.Load(fullPathName);
                bool isEdit = false;
                Common.XmlSetting.MyXmlByReflection.CheckXmlName(this, xml.SelectSingleNode("Root"), xml, ref isEdit);
                if (isEdit)
                    xml.Save(fullPathName);
            }
    
    
            public void updateXml(string fullPathName)
            {
                XmlDocument xml = new XmlDocument();
                xml.Load(fullPathName);
                Common.XmlSetting.MyXmlByReflection.UpdateXmlValue(this, xml.SelectSingleNode("Root"));
                xml.Save(fullPathName);
            }
    
    
        }
    
    
    
    }

      

    2、关键函数

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Reflection;
    
    namespace Common.XmlSetting
    {
        public static class MyXmlByReflection
        {
            /// <summary>
            /// 获取值
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="xln"></param>
            /// <param name="propertyNameParent"></param>
            public static void GetPropertiesValue(object obj, XmlNode xln, string propertyNameParent)
            {
                string propertyNameChildren = "";
                for (int j = 0; j < xln.ChildNodes.Count; j++)
                {
                    propertyNameChildren = xln.ChildNodes[j].LocalName;
                    XmlNodeList xlnList = xln.ChildNodes[j].ChildNodes;
                    if (xlnList.Count <= 1)
                    {
                        if (propertyNameChildren != "")
                        {
                            //配置文件类中有无此属性
                            if (obj.GetType().GetProperty(propertyNameChildren) != null)
                            {
                                //该属性是否可为空 如:int?
                                //赋值
                                if (Common.MyReg.IsNullableType(obj.GetType().GetProperty(propertyNameChildren).PropertyType) && xln.ChildNodes[j].InnerText.Trim().Length == 0)
                                {
                                    obj.GetType().GetProperty(propertyNameChildren).SetValue(obj, null, null);
                                }
                                else
                                    obj.GetType().GetProperty(propertyNameChildren).SetValue(obj, Convert.ChangeType(xln.ChildNodes[j].InnerText.Trim(), (Nullable.GetUnderlyingType(obj.GetType().GetProperty(propertyNameChildren).PropertyType) ?? obj.GetType().GetProperty(propertyNameChildren).PropertyType)), null);
                            }
                        }
                    }
                    else
                    {
                        //配置文件类中的子树
                        if (obj.GetType().GetField(propertyNameChildren) != null)
                        {
                            object o = obj.GetType().InvokeMember(propertyNameChildren, BindingFlags.GetField, null, obj, null);
                            GetPropertiesValue(o, xln.ChildNodes[j], propertyNameChildren);
                        }
                    }
                }
            }
            /// <summary>
            /// 根据配置文件类初始化配置文件
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="xn"></param>
            /// <param name="xml"></param>
            /// <param name="isEdit"></param>
            public static void CheckXmlName(object obj, XmlNode xn, XmlDocument xml, ref bool isEdit)
            {
                foreach (PropertyInfo pi in obj.GetType().GetProperties())
                {
                    XmlNode xltemp = xn.SelectSingleNode(pi.Name);
                    //有无此节点
                    if (xltemp == null)
                    {
                        XmlNode xe = xml.CreateNode(XmlNodeType.Element, pi.Name, null);
                        //有无初始值
                        if (pi.GetValue(obj, null) != null && xe.InnerText.Trim().Length == 0)
                            xe.InnerText = pi.GetValue(obj, null).ToString();
                        xn.AppendChild(xe);
                        isEdit = true;
                    }
                    else
                    {
                        //若有初始值,并且节点值为空,赋值
                        if (pi.GetValue(obj, null) != null && xltemp.InnerText.Trim().Length == 0)
                            xltemp.InnerText = pi.GetValue(obj, null).ToString();
                        isEdit = true;
                    }
                }
                //检索子节点
                foreach (FieldInfo fi in obj.GetType().GetFields())
                {
                    XmlNode xltemp = xn.SelectSingleNode(fi.Name);
                    if (xltemp == null)
                    {
                        XmlNode xe = xml.CreateNode(XmlNodeType.Element, fi.Name, null);
                        xn.AppendChild(xe);
                        isEdit = true;
                    }
                    object o = obj.GetType().InvokeMember(fi.Name, BindingFlags.GetField, null, obj, null);
                    CheckXmlName(o, xn.SelectSingleNode(fi.Name), xml, ref isEdit);
                }
            }
    
            /// <summary>
            /// 更新配置文件
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="xn"></param>
            public static void UpdateXmlValue(object obj, XmlNode xn)
            {
                foreach (PropertyInfo pi in obj.GetType().GetProperties())
                {
                    XmlNode xltemp = xn.SelectSingleNode(pi.Name);
                    object o = obj.GetType().InvokeMember(pi.Name, BindingFlags.GetProperty, null, obj, null);
                    if (o != null)
                        xltemp.InnerText = pi.GetValue(obj, null).ToString();
                    else
                        xltemp.InnerText = string.Empty;
    
                }
                foreach (FieldInfo fi in obj.GetType().GetFields())
                {
                    object o = obj.GetType().InvokeMember(fi.Name, BindingFlags.GetField, null, obj, null);
                    UpdateXmlValue(o, xn.SelectSingleNode(fi.Name));
                }
            }
    
        }
    }

      

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    
    using System.Runtime.InteropServices;
    
    namespace Common
    {
        public class MyReg
        {
            //type可空否
            public static bool IsNullableType(Type theType)
            {
                return (theType.IsGenericType && theType.
                  GetGenericTypeDefinition().Equals
                  (typeof(Nullable<>)));
            }
        }
    }

    使用方法

       先在程序里声明该静态对象,及其路径、名称。

    public static class PublicValue
    {
    public static Settings.ManagementSystemConfig SMSC = new Settings.ManagementSystemConfig();
    public static string SMSC_FullPath = System.Windows.Forms.Application.StartupPath + @"\Settings\SystemConfig.xml";
    }

      程序启动时初始化

      static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
    
                PublicValue.SMSC = new Settings.ManagementSystemConfig();
                //更新配置文件
                PublicValue.SMSC.checkXml(PublicValue.SMSC_FullPath);
                //获取值
                PublicValue.SMSC.getProperties(PublicValue.SMSC_FullPath);
    
                Application.Run(new MainForm());
             }
         }

      程序里使用

      

     Settings.ManagementSystemConfig t_SMSC = new Settings.ManagementSystemConfig();
    t_SMSC.getProperties(PublicValue.SMSC_FullPath);
    foreach (string fPrinterName in PrinterSettings.InstalledPrinters) { //使用时可直接利用vs的智能感知! if (t_SMSC.OutPrintSetting.PrinterName == fPrinterName) { System.Drawing.Printing.PrintDocument pd = new System.Drawing.Printing.PrintDocument(); pd.PrinterSettings.PrinterName = fPrinterName;

     程序里更新

     Settings.ManagementSystemConfig t_SMSC = new Settings.ManagementSystemConfig();

    t_SMSC.getProperties(PublicValue.SMSC_FullPath);

    t_SMSC.EnterPrintSetting.PrinterName = this.textBoxPrintName.Text.Trim();

    PublicValue.SMSC = t_SMSC;

    PublicValue.SMSC.updateXml(PublicValue.SMSC_FullPath);
      MessageBox.Show("保存成功!");

    over

    看来还是例子实在:

    源码

  • 相关阅读:
    红黑树(RBTree)
    js闭包简要分析
    html 5的localstorag
    浅析CSS中的haslayout
    初识sass框架
    BFC块级格式化上下文简述
    RESTful互联网框架
    javascript的框架演化
    浅析angular框架的cookie
    angular template浅析
  • 原文地址:https://www.cnblogs.com/qingse/p/2882407.html
Copyright © 2020-2023  润新知