舞步者

天行健,君子以自强不息;地势坤,君子以厚德载物
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

write a custum class

Posted on 2006-02-23 13:55  舞步者  阅读(288)  评论(0)    收藏  举报
    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  
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".
posted on 2004-05-27 11:49 fengzhimei 阅读(1444) 评论(5)  编辑 收藏 收藏至365Key 所属分类: Asp.netCode Snippet

Feedback

# re: 2004-05-27 12:57 陈叙远
使用System.Web.Caching.CacheDependency关联config就可以了吧  回复
  

# re: Write a custom config class. 2004-05-27 13:28 fengzhimei
yes,That's for sure in theory.
you can store your own items in a custom config file and use your own CacheDependency to monitor changes,but i never test:)  回复
  

# Another way to retrieve a custom key's value from web.config in web form application[TrackBack] 2004-05-27 14:21 Fengzhimei@Dot.Net
Another way to retrieve a custom key's value from web.config in web form application
Fengzhimei@Dot.Net引用了该文章,地址:http://www.cnblogs.com/fengzhimei/archive/2004/05/27/11780.aspx  回复
  

# re: Write a custom config class. 2004-05-27 14:39 ghj1976
1、 如果是 Web 应用程序,它并不是在当前路径下执行的:

Path.GetDirectoryName(dllpath)
返回的是:
@"c:\windows\microsoft.net\framework\v1.1.4322\temporary asp.net files\testweb\02da89a5\6e4314f7\assembly\dl2\beeff702\089d3d91_b443c401"
而不是你需要的路径

应该为:
AppDomain.CurrentDomain.BaseDirectory
  回复
  

# re: Write a custom config class. 2004-05-27 14:44 ghj1976
2、 Web 应用程序我试验了你上面的代码,在 my.config 被修改的时候,并不会 触发 watcher_Changed ,这应该是 Web 应用程序的运行机制所决定的。