天天看點

C# 使用序列化+反射加載xml文檔到類執行個體對象

添加引用

using System.Threading;
using System.Xml.Serialization;
using System.IO;
using System.Reflection;
           
#region 通過反序列化和反射将xml配置文檔加載到類執行個體的公共屬性   反射測試類 + 單例模式
    public class SystemConfig
    {
        private static readonly string defaultFileName = "Test.xml";
        private string _ip;
        private string _port;
        private static readonly object _lockobj = new object();
        private static SystemConfig _instance;

        public string Ip
        {
            get => _ip;
            set => _ip = value;
        }

        public string Port
        {
            get => _port;
            set => _port = value;
        }

        private SystemConfig()
        {

        }

        public static SystemConfig Instance
        {
            get
            {
                lock(_lockobj)
                {
                    if (_instance==null)
                    {
                        _instance = new SystemConfig();
                        _instance.LoadConfig(defaultFileName);
                    }
                }
                return _instance;
            }
        }

        public void LoadConfig(string xmlFile)
        {
            try
            {
                //擷取xml路徑
                string path;
                path = AppDomain.CurrentDomain.BaseDirectory;
                path = path.Replace("netcoreapp2.1", "Config");
                path = Path.Combine(path, xmlFile);

                if (!File.Exists(path))
                {
                    Console.WriteLine("XmlFile not found !");
                    return;
                }

                //反序列化
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SystemConfig));
                SystemConfig systemConfig;
                using (FileStream fileStream = new FileStream(path, FileMode.Open))
                {
                    systemConfig = (SystemConfig)xmlSerializer.Deserialize(fileStream);
                }

                //擷取執行個體公共屬性
                PropertyInfo[] propertyInfos = SystemConfig.Instance.GetType().GetProperties();

                //設定Value
                for (int i = 0; i < propertyInfos.Length; i++)
                {
                    if (propertyInfos[i].CanWrite)
                    {
                        propertyInfos[i].SetValue(this, propertyInfos[i].GetValue(systemConfig));
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        
        /// <summary>
        /// 儲存SystemConfig 執行個體對象到xml配置檔案
        /// </summary>
        public void Save()
        {
            try
            {
                //擷取xml路徑
                string path;
                path = AppDomain.CurrentDomain.BaseDirectory;
                path = path.Replace("netcoreapp2.1", "Config");
                path = Path.Combine(path, defaultFileName);

                using (FileStream fileStream = new FileStream(path, FileMode.Truncate))
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(SystemConfig));
                    xmlSerializer.Serialize(fileStream, this);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
        }

    }

    #endregion
           
static void Main(string[] args)
         {
            //Mutex跨多個線程同步通路的類。隻有一個線程能獲得互斥鎖定,通路受互斥保護的同步代碼區域。
            //在Mutex類的構造函數中,可以指定互斥是否最初應由主調線程擁有,定義互斥的名稱,獲得互斥是否已存在的資訊。
            bool flag = false;
            Mutex mutex = new Mutex(true, "Main", out flag);
            //第一個參數:true--給調用線程賦予互斥體的初始所屬權
            //第一個參數:互斥體的名稱
            //第三個參數:傳回值,如果調用線程已被授予互斥體的初始所屬權,則傳回true
            if (!flag)
            {
                Console.WriteLine("程式已運作!");
                Console.ReadKey();
            }


            //測試屬性配置
            SystemConfig systemConfig = SystemConfig.Instance;
            Console.WriteLine($"IP:{systemConfig.Ip}");
            Console.WriteLine($"Port:{systemConfig.Port}");
            
            systemConfig.Ip="128.0.0.1";
            systemConfig.Save();
            Console.WriteLine($"修改後 IP:{systemConfig.Ip}");
            Console.ReadKey();
        }
           

運作結果:

C# 使用序列化+反射加載xml文檔到類執行個體對象

反射相關

Assembly assembly= Assembly.Load("CsharpSenior"); //通過程式集名稱加載程式集
            Assembly assembly_2 = Assembly.LoadFrom("CsharpSenior.dll"); //通過DLL檔案名稱傳回Assembly對象
            Type type= assembly.GetType("CsharpSenior.Reflection.ReflectionTest"); //通過Assembly擷取程式集中的類,參數必須是類的全名
            object instance= Activator.CreateInstance(type,new object[] {10 }); //用Activator的CreateInstance靜态方法,生成新對象
            ConstructorInfo[] constructorInfos = type.GetConstructors(); //擷取類的所有構造函數
            PropertyInfo[] propertyInfos= type.GetProperties(); //檢視類中的屬性
            propertyInfos[0].SetValue(instance,"xiaom");  //給屬性指派
            FieldInfo[] fieldInfos = type.GetFields();   //檢視類中的public字段
            fieldInfos[0].SetValue(instance,20);  //給字段指派
            MethodInfo methodInfo= type.GetMethod("Call"); //擷取類中的具體方法
            object[] para = new object[] { 1,"2"};
            methodInfo.Invoke(instance, para);  //方法調用