利用反射进行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

 

看来还是例子实在:

源码

posted on 2013-01-30 12:27  日暮青色  阅读(831)  评论(1编辑  收藏  举报

导航