程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 電子商務--配置管理

電子商務--配置管理

編輯:C#入門知識

   在大型項目開發中,我們需要配置各種各樣的信息。比如:在線支付方式有支付寶,網銀,財付通,快錢。我們需要配置支付寶賬號信息,需要配置財付通賬號信息,需要配置網銀賬號信息還有快錢賬號信息。發郵件呢?我們需要配置郵件服務器信息。發短信呢?我們需要配置短息服務器信息。對於各種各樣形形色色的配置信息,我們該如何配置呢?又該如何才能方便管理呢?我先介紹下.Net自帶的配置信息類,然後在使用反射技術自定義一個配置管理類。

  1)使用System.Configuration.AppSettingsSection類 

        .Net已經提供了AppSettingsSection類方便我們配置信息。我們可以把配置信息放在Web.confg或App.config的appSettings節點下。如下:

    <configuration>
        <appSettings>
            <!--支付寶合作身份者Id-->
            <add key="AlipayId" value="1234567890"/>
            <add key="AlipayKey" value="test1234567890"/>
            <add key="AlipayEmail" value="[email protected]"/>

            <!--財付通商戶號-->
            <add key="TenpayId" value="1234567890"></add>
            <!--財付通密鑰-->
            <add key="TenpayKey" value="test1234567890"/>

            <!--網銀商戶號-->
            <add key="ChinaBankId" value="1001"></add>
            <!--網銀密鑰-->
            <add key="ChinaBankKey" value="test"/>
        </appSettings>
    </configuration>

  這種配置方式是最基本的配置方式,也是我們最常用的配置方式,但這樣的配置方式顯然不能讓我們滿意。因為大量的配置信息放在一起,即無法對信息進行分組,也不方便管理,時間一長,我們自己可能已經不記得配置信息的意思,而且修改任何的配置內容都會導致Asp.Net站點重新啟動。

      2)使用System.Configuration.NameValueSectionHandler類 

         .Net在System下提供NameValueSectionHandler類可以對配置信息進行方便的分組。NameValueSectionHandler類的定義是這樣的:

  NameValueSectionHandler : IConfigurationSectionHandler
    {
        
          string defaultKeyAttribute = ;
          string defaultValueAttribute = ;

        
        [TargetedPatchingOptOut()]
         NameValueSectionHandler();
         object Create(object parent, object context, XmlNode section);
          object CreateStatic(object parent, XmlNode section);
          object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName);

        
          string KeyAttributeName { ; }
          string ValueAttributeName { ; }
    }

    NameValueSectionHandler類實現了接口IConfigurationSectionHandler的Create方法,返回一個ReadOnlyNameValueCollection

object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName)     {     ReadOnlyNameValueCollection values;      (parent == )     {     values = ReadOnlyNameValueCollection(StringComparer.OrdinalIgnoreCase);     }          {     ReadOnlyNameValueCollection values2 = (ReadOnlyNameValueCollection) parent;     values = ReadOnlyNameValueCollection(values2);     }     HandlerBase.CheckForUnrecognizedAttributes(section);      (XmlNode node section.ChildNodes)     {      (!HandlerBase.IsIgnorableAlsoCheckForNonElement(node))     {      (node.Name == )     {     string str = HandlerBase.RemoveRequiredAttribute(node, keyAttriuteName);      string str2 = HandlerBase.RemoveRequiredAttribute(node, valueAttributeName, );     HandlerBase.CheckForUnrecognizedAttributes(node);     values[str] = str2;     }      {     (node.Name == )     {     string name = HandlerBase.RemoveRequiredAttribute(node, keyAttriuteName);     HandlerBase.CheckForUnrecognizedAttributes(node);     values.Remove(name);     ;      }    (node.Name.Equals())     {     HandlerBase.CheckForUnrecognizedAttributes(node);     values.Clear();     ;     }    HandlerBase.ThrowUnrecognizedElement(node);    }   }   }   values.SetReadOnly();    values;   }

 從代碼中,可以看出需要一個Add節點,該節點包含一個Key和Value的屬性。我們可以這樣配置各種信息。 

     <configuration>
        <configSections>
            <section name="Alipay" type="System.Configuration.NameValueSectionHandler"/>
            <section name="TenPay" type="System.Configuration.NameValueSectionHandler"/>
            <section name="WebBank" type="System.Configuration.NameValueSectionHandler"/>
      </configSections>
        <Alipay>
            <!--合作身份者ID-->
            <add key="Id"  value="1234567890" />
            <!--安全檢驗碼-->
            <add key="key"  value="test1234567890" />
            <add key="email"  value="[email protected]" />
        </Alipay>
      <TenPay>
            <!--合作身份者ID-->
            <add key="Id"  value="1234567890" />
            <!--安全檢驗碼-->
            <add key="key"  value="test1234567890" />
      </TenPay>
      <WebBank>
            <!--合作身份者ID-->
            <add key="Id"  value="1001" />
            <!--安全檢驗碼-->
            <add key="key"  value="test1234567890" />
          </WebBank>
  </configuration>  

  可以這樣讀取配置信息:

   //支付寶配置信息
      var alipays = (NameValueCollection)ConfigurationManager.GetSection("Alipay");
      //支付寶Id
      string alipayId = alipays["Id"];
      //支付寶Key
      string alipaykey = alipays["key"];

  這種配置方式可以有效的對各種不同的配置信息進行分組,方便查看和修改。但不符合面向對象的開發,也無法對配置的信息進行類型檢查,修改配置信息一樣會導致Asp.Net站點重新啟動。

  3)自定義配置節點

     我們可以仿照AppSettingsSection類的實現方式,自定義節點配置類。可以繼承ConfigurationSection類實現自定義節點配置類。

   public class AlipaySetion : ConfigurationSection
    {
        [ConfigurationProperty("Id", IsKey = true)]
        public string Id
        {
            get { return (string)base["Id"]; }
            set { base["Id"] = value; }
        }

        [ConfigurationProperty("Key")]
        public string Key
        {
            get { return (string)base["Key"]; }
            set { base["Key"] = value; }
        }

        [ConfigurationProperty("Email")]
        public string Email
        {
            get { return (string)base["Email"]; }
            set { base["Email"] = value; }
        }
    }

  節點配置如下:

  <configuration>
      <configSections>
          <section name="Alipay" type="ConsoleApplication2.AlipaySetion,ConsoleApplication2"/>
      </configSections>
      <Alipay Id="1234567890" Key="test1234567890" Email="[email protected]"/>
  </configuration>

  讀取方式:

      var alipays = (AlipaySetion)ConfigurationManager.GetSection("Alipay");
              string id = alipays.Id;
              string key = alipays.Key;

  自定義配置節點方便查看和管理,也符合面向對象開發和進行類型檢查。但我們需要寫很多ConfigurationSection類的實現。

     4)使用反射技術自定義配置

  .Net中使用反射技術可以動態的創建一個對象,可以調用對象的方法,可以給對象屬性賦值。我們是不是可以根據這個特點動態的創建配置類,然後給配置類的屬性賦值呢?那需要什麼呢?需要2個基礎文件,一個是對象的映射關系文件,另一個是對象屬性映射文件,如圖:

  首先來看看對象的映射關系文件(文件名:System.config),內容如下:

 <configuration>
  <configMappings>
    <mapping  AssemblyName="ConsoleApplication2" ClassName="ConsoleApplication2.AlipayConfiguration"
             Name="AlipayConfiguration"
             section="AlipayConfiguration"
             fileName="Mapping.AlipayConfiguration.config">
        <field xmlName="Id" fieldName="Id" />
        <field xmlName="Key" fieldName="Key" />
        <field xmlName="Email" fieldName="Email" />
    </mapping>
    <mapping  AssemblyName="ConsoleApplication2" ClassName="ConsoleApplication2.TenpayConfiguration"
      Name="TenpayConfiguration"
            section="TenpayConfiguration"
            fileName="Mapping.TenpayConfiguration.config">
      <field xmlName="Id" fieldName="Id" />
      <field xmlName="Key" fieldName="Key" />
    </mapping>
  </configMappings>
</configuration>

   對象屬性映射文件:

  支付寶配置類文件(Mapping.AlipayConfiguration.config)

  <?xml version="1.0" encoding="utf-8" ?>
    <AlipayConfiguration>
        <node name="Id" value="1234567890"/>
        <node name="Key" value="test1234567890"/>
        <node name="Email" value="[email protected]" />
    </AlipayConfiguration>

  Tenpay配置類文件(Mapping.TenpayConfiguration.config)

  <?xml version="1.0" encoding="utf-8" ?>
    <TenpayConfiguration>
        <node name="Id" value="1234567890"/>
        <node name="Key" value="test1234567890"/>
    </TenpayConfiguration>

     xml文件我就不做過多說明了,很簡單。看到節點名稱基本就能猜出其意思。下面來設計映射類和配置管理類,配置管理類顧名思義就能知道是管理所有配置類的。那怎樣才能管理所有的配置類呢?我們知道object是所有對象的基類。當然我們的配置類也是繼承object的。我們可以設計一個鍵值對的集合來存放所有的配置信息。比如:private Dictionary<string, object> Mappings。其中的keyi就是配置的類名,value就是配置對象。我們先看看對象的映射類的定義:

   public class ConfigMapping
    {
        private Dictionary<string, string> fieldMappings;

        /// <summary>
        /// 配置名(唯一)
        /// </summary>
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 配置對象程序集名
        /// </summary>
        public string AssemblyName
        {
            get;
            set;
        }

        /// <summary>
        /// 配置對象類名
        /// </summary>
        public string ClassName
        {
            get;
            set;
        }

        /// <summary>
        /// 配置對象文件
        /// </summary>
        public string ConfigFile
        {
            get;
            set;
        }

        /// <summary>
        /// 類型
        /// </summary>
        private Type type;

        /// <summary>
        /// 配置對象類型
        /// </summary>
        public Type Type
        {
            get
            {
                return Type.GetType(ClassName + "," + AssemblyName);
            }
            set
            {
                type = value;
                Instance = Activator.CreateInstance(Type.GetType(ClassName + "," + AssemblyName));
            }
        }

        /// <summary>
        /// 配置對象實例
        /// </summary>
        public object Instance
        {
            get;
            private set;
        }

        //域集合
        public Dictionary<string, string> FieldMappings
        {
            get
            {
                return fieldMappings ?? (new Dictionary<string, string>());
            }
            set
            {
                fieldMappings = value;
            }
        }
    }

  配置管理類ConfigManager代碼:

     public class ConfigManager
    {
        private static readonly object sync = new object();
        private static ConfigManager manager;
        private Dictionary<string, object> Mappings;
        private const string configFile = "Configuration/System.config";

        private ConfigManager()
        {
            Mappings = new Dictionary<string, object>();
        }

        public static ConfigManager Instance
        {
            get
            {
                lock (sync)
                {
                    if (manager == null)
                    {
                        lock (sync)
                        {
                            manager = new ConfigManager();
                            manager.Init();
                        }
                    }
                }

                return manager;
            }
        }

        /// <summary>
        /// 初始化配置管理
        /// </summary>
        privatevoid Init()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + configFile;

            var document = new XmlDocument();
            document.Load(path);

            var nodes = document.SelectNodes("configuration/configMappings/mapping");

            foreach (XmlNode node in nodes)
            {
                var mapping = new ConfigMapping
                                  {
                                      Name = node.Attributes["Name"].InnerText,
                                      AssemblyName = node.Attributes["AssemblyName"].InnerText,
                                      ClassName = node.Attributes["ClassName"].InnerText,
                                      ConfigFile = node.Attributes["fileName"].InnerText,
                                      Type =
                                          Type.GetType(node.Attributes["ClassName"].InnerText + "," +
                                                       node.Attributes["AssemblyName"].InnerText)
                                  };

                foreach (XmlNode childNode in node.SelectNodes("field"))
                {
                    mapping.FieldMappings.Add(childNode.Attributes["xmlName"].InnerText,
                                              childNode.Attributes["fieldName"].InnerText);
                }

                SetProperty(mapping);

                Mappings.Add(mapping.Name, mapping.Instance);
            }
        }

        /// <summary>
        /// 設置對象屬性值
        /// </summary>
        /// <param name="mapping"></param>
        private void SetProperty(ConfigMapping mapping)
        {
            var xml = new XmlDocument();
            xml.Load(AppDomain.CurrentDomain.BaseDirectory + "Configuration/" + mapping.ConfigFile);
            var ns = xml.SelectSingleNode(mapping.Name);
            var infos = mapping.Instance.GetType().GetProperties();

            foreach (var info in infos)
            {
                foreach (XmlNode n in ns.ChildNodes)
                {
                    if (n.Attributes["name"].Value == info.Name)
                    {
                        object value = Convert.ChangeType(n.Attributes["value"].Value, info.PropertyType);
                        info.SetValue(mapping.Instance, value, null);
                    }
                }
            }
        }

        /// <summary>
        /// 獲取配置類實例
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetMappingByName(string name)
        {
            return Mappings[name];
        }
    }

  讀取配置信息很簡單,代碼如下:

   var alipay = (AlipayConfiguration) ConfigManager.Instance.GetMappingByName("AlipayConfiguration");
            long alipayId = alipay.Id;
            string alipayKey = alipay.Key;

            var tenpay = (TenpayConfiguration)ConfigManager.Instance.GetMappingByName("TenpayConfiguration");
            long tenpayId = tenpay.Id;
            string tenpayKey = tenpay.Key;

   總結:這篇文章主要是介紹了AppSettingsSection類,NameValueSectionHandler類,自定義節點類,和設計一個配置管理類,來配置我們的各種信息。各有優缺點。大家在實際的項目開發中,根據網站配置信息多少,選擇適合自己的配置方式。

  好了,感謝閱讀,希望這篇文章能給你帶來幫助!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved