In this post, ghj mentioned a few problems about using ConfigurationSettings.AppSettings[""] in our web or windows forms applications.
    The config files are only loaded when an application loads, so any changes in it will not take effect immediately.
    For web application, asp.net restarts the application any time the config file changes, ghj think it doesn't matter, but I can't say that I agree with him, In fact, restarting the application has a couple of bad effects, i.e. the application loses its cache and session state.
    For windows application, only one thing you can do is that prompte the user to reboot the applicationWrite a custom config class.
    I found a solution to this problem, Just write a custom class that would give me access to a configuration file, Ok, Let's start it.

Rich Code Plain Code  
Write a custom config class.
using System; 2using System.IO; 3using System.Xml; 4using System.Configuration; 5 6namespace Custom 7{ 8 /// <summary> 9 /// Provides a global Settings mechanism 10 /// </summary> 11 public class Settings 12 { 13 private XmlDocument configSource; 14 private string xpathTemplate; 15 private FileSystemWatcher configWatcher; 16 private string configpath; 17 18 19 /// <summary> 20 /// Loads the config file ... private so you can't instantiate this object 21 /// </summary> 22 private Settings() 23 { 24 configSource = null; 25 xpathTemplate = "//configuration/appSettings/add[@key='{0}']"; 26 configpath = string.Empty; 27 28 LoadconfigSource(); 29 30 configWatcher = new FileSystemWatcher(Path.GetDirectoryName(this.configpath), 31 Path.GetFileName(this.configpath)); 32 configWatcher.Changed +=new FileSystemEventHandler(watcher_Changed); 33 } 34 35 /// <summary> 36 /// Gets or Sets the value of a //configuration/appSettings/add node 37 /// </summary> 38 public string this[string key] 39 { 40 get 41 { 42 string xpath = string.Format(this.xpathTemplate,key); 43 XmlNodeList nodes = configSource.SelectNodes(xpath); 44 45 if (nodes.Count <= 0) 46 return null; 47 48 if (nodes.Count > 1) 49 throw new Exception("Ambiguous key in config file"); 50 51 string addvalue = nodes[0].Attributes["value"].InnerText; 52 return addvalue; 53 } 54 set 55 { 56 string xpath = string.Format(this.xpathTemplate,key); 57 XmlNodeList nodes = configSource.SelectNodes(xpath); 58 59 if (nodes.Count > 1) 60 throw new Exception("Ambiguous key in config file"); 61 62 if (nodes.Count <= 0) 63 {//insert 64 65 XmlAttribute keyattrib = configSource.CreateAttribute("key"); 66 keyattrib.InnerText = key; 67 XmlAttribute valattrib = configSource.CreateAttribute("value"); 68 valattrib.InnerText = value; 69 70 XmlNode add = configSource.CreateElement("add"); 71 add.Attributes.Append(keyattrib); 72 add.Attributes.Append(valattrib); 73 74 XmlNode appsettings = configSource.GetElementsByTagName("appSettings")[0]; 75 appsettings.AppendChild(add); 76 } 77 else //edit 78 { 79 nodes[0].Attributes["value"].InnerText = value; 80 } 81 82 //persist changes 83 configSource.Save(this.configpath); 84 } 85 } 86 87 /// <summary> 88 /// Loads the config file into memory 89 /// </summary> 90 private void LoadconfigSource() 91 { 92 System.Diagnostics.Debug.Write("Loading the config file"); 93 string dllpath = System.Reflection.Assembly.GetExecutingAssembly().Location; 94 string filename = ConfigurationSettings.AppSettings["configfile"].ToString(); 95 configpath = string.Format(@"{0}\{1}",Path.GetDirectoryName(dllpath),filename); 96 configSource = new XmlDocument(); 97 98 Stream cstream = null; 99 100 //Attempt to open and load the configuration file 101 try 102 { 103 cstream = (Stream)File.OpenRead(configpath); 104 configSource.Load(cstream); 105 } 106 catch (FileNotFoundException fnfe) 107 { 108 throw fnfe; 109 } 110 catch (FileLoadException fle) 111 { 112 throw fle; 113 } 114 catch (XmlException xe) 115 { 116 throw xe; 117 } 118 catch (Exception e) 119 { 120 throw e; 121 } 122 finally 123 { 124 //make sure if the file stream get's opened that we close it. 125 if (cstream != null) 126 cstream.Close(); 127 } 128 } 129 130 /// <summary> 131 /// this event is triggered by the FileSystemWatcher.Changed event 132 /// </summary> 133 private void watcher_Changed(object sender, FileSystemEventArgs e) 134 { 135 LoadconfigSource(); 136 } 137 138 private static Settings privateInstance = null; 139 140 /// <summary> 141 /// Gets a global instance of the Settings object 142 /// </summary> 143 public static Settings Instance 144 { 145 get 146 { 147 if (privateInstance == null) 148 privateInstance = new Settings(); 149 150 return privateInstance; 151 } 152 } 153 } 154}
using System;
using System.IO;
using System.Xml;
using System.Configuration;
namespace Custom
{
 /// 
 /// Provides a global Settings mechanism
 /// 
 public class Settings
 {
  private XmlDocument configSource;
  private string xpathTemplate;
  private FileSystemWatcher configWatcher;
  private string configpath;

  /// 
  /// Loads the config file ... private so you can't instantiate this object
  /// 
  private Settings()
  {
   configSource = null;
   xpathTemplate = "//configuration/appSettings/add[@key='{0}']";
   configpath = string.Empty;
   LoadconfigSource();
   
   configWatcher = new FileSystemWatcher(Path.GetDirectoryName(this.configpath),
    Path.GetFileName(this.configpath));
   configWatcher.Changed +=new FileSystemEventHandler(watcher_Changed);
  }
  /// 
  /// Gets or Sets the value of a //configuration/appSettings/add node
  /// 
  public string this[string key] 
  {
   get
   {
    string xpath = string.Format(this.xpathTemplate,key);
    XmlNodeList nodes = configSource.SelectNodes(xpath);
    
    if (nodes.Count <= 0)
     return null;
    if (nodes.Count > 1)
     throw new Exception("Ambiguous key in config file");
    string addvalue = nodes[0].Attributes["value"].InnerText;
    return addvalue;
   }
   set
   {
    string xpath = string.Format(this.xpathTemplate,key);
    XmlNodeList nodes = configSource.SelectNodes(xpath);
    
    if (nodes.Count > 1)
     throw new Exception("Ambiguous key in config file");
    if (nodes.Count <= 0)
    {//insert
     
     XmlAttribute keyattrib = configSource.CreateAttribute("key");
     keyattrib.InnerText = key;
     XmlAttribute valattrib = configSource.CreateAttribute("value");
     valattrib.InnerText = value;
     XmlNode add = configSource.CreateElement("add");
     add.Attributes.Append(keyattrib);
     add.Attributes.Append(valattrib);
     XmlNode appsettings = configSource.GetElementsByTagName("appSettings")[0];
     appsettings.AppendChild(add);
    }
    else //edit
    {
     nodes[0].Attributes["value"].InnerText = value;
    }
    //persist changes
    configSource.Save(this.configpath);
   }
  }

  /// 
  /// Loads the config file into memory
  /// 
  private void LoadconfigSource()
  {
   System.Diagnostics.Debug.Write("Loading the config file");
   string dllpath = System.Reflection.Assembly.GetExecutingAssembly().Location;
   string filename = ConfigurationSettings.AppSettings["configfile"].ToString();
   configpath = string.Format(@"{0}\{1}",Path.GetDirectoryName(dllpath),filename);
   configSource = new XmlDocument();
   Stream cstream = null;
   
   /*
   Attempt to open and load the configuration file
   If an exception is found, throw it to make sure the 
   user/developer is aware of the problem, but make sure
   to close the stream if it's open.
   */
   try
   {
    cstream = (Stream)File.OpenRead(configpath);
    configSource.Load(cstream);
   }
   catch (FileNotFoundException fnfe)
   {
    throw fnfe;
   }
   catch (FileLoadException fle)
   {
    throw fle;
   }
   catch (XmlException xe)
   {
    throw xe;
   }
   catch (Exception e)
   {
    throw e;
   }
   finally
   {
    //make sure if the file stream get's opened that we close it.
    if (cstream != null)
     cstream.Close();
   }
  }
  /// 
  /// this event is triggered by the FileSystemWatcher.Changed event
  /// 
  private void watcher_Changed(object sender, FileSystemEventArgs e)
  {
   LoadconfigSource();
  }
  #region Singleton Stuff
  private static Settings privateInstance = null;
  /// 
  /// Gets a global instance of the Settings object
  /// 
  public static Settings Instance
  {
   get 
   {
    if (privateInstance == null)
     privateInstance = new Settings();
    return privateInstance;
   }
  }
  #endregion
 }
}
How to use this, All you have to do is provide an add node in either your app.config or web.config file that points to the config file you want to use.
<configuration>
  <appSettings>
    <add key="configfile" value="my.config"/>
  </appSettings>
</configuration>
Note : This file path is relative to the exe or dll that contains the class. If you were using this file in a web application, you'd have to use "..\my.config".

相关文章:

  • 2022-12-23
  • 2022-02-27
  • 2021-09-12
  • 2021-09-27
  • 2022-12-23
  • 2022-12-23
  • 2022-02-13
  • 2022-01-27
猜你喜欢
  • 2021-11-14
  • 2021-09-26
  • 2021-04-21
  • 2021-08-03
  • 2022-12-23
  • 2021-07-03
  • 2021-10-07
相关资源
相似解决方案