Fengzhimei@Dot.Net
Designing My Colorful Dream
    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 application
    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  
1using 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}
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".
posted on 2004-05-27 11:49  fengzhimei  阅读(2671)  评论(4编辑  收藏  举报