如何解决读取C#Framework 4.0中的自定义配置文件
| 我正在Framework 4.0下的C#中开发应用程序。 在我的应用程序中,我想创建一个独立的配置文件,而不是app.config文件。配置文件包含我们为产品开发的自定义配置部分。 我不想使用configSource从app.config引用此文件。 我想在运行时加载它并阅读其内容。 我的意思是一个示例log4net,它允许您将配置写入log4net.config文件中。 任何人都可以在不编写类似于框架中存在代码的代码的情况下帮助实现该目标吗? 更新: 根据Kaido的回答,我编写了实用程序类,该类读取自定义配置文件,并具有在文件系统上的文件更改时刷新Config内容的功能。 该类的用法如下: 获取配置文件内容// Create configuration reader that reads the files once
var configFileReader = new CustomConfigurationFileReader(\"c:\\\\myconfig.config\");
var config = configFileReader.Config;
// Do any action you want with the config object like:
config.GetSection(\"my.custom.section\");
// or,var someVal = config.AppSettings.Settings[\"someKey\"];
当配置文件更改时获取通知
// Create configuration reader that notifies when the configuraiton file changes
var configFileReader = new CustomConfigurationFileReader(\"c:\\\\myconfig.config\",true);
// Register to the FileChanged event
configFileReader.FileChanged += MyEventHandler;
...
private void MyEventHanler(object sender,EventArgs e)
{
// You can safely access the Config property here,it is already contains the new content
}
在代码中,我使用PostSharp来验证构造函数的输入参数,以验证日志文件不为null且该文件存在。您可以更改代码以使代码内联这些验证(尽管我建议使用PostSharp将应用程序划分为各个方面)。
这是代码:
using System;
using System.Configuration;
using System.IO;
using CSG.Core.Validation;
namespace CSG.Core.Configuration
{
/// <summary>
/// Reads customer configuration file
/// </summary>
public class CustomConfigurationFileReader
{
// By default,don\'t notify on file change
private const bool DEFAULT_NOTIFY_BEHAVIOUR = false;
#region Fields
// The configuration file name
private readonly string _configFileName;
/// <summary>
/// Raises when the configuraiton file is modified
/// </summary>
public event System.EventHandler FileChanged;
#endregion Fields
#region Constructor
/// <summary>
/// Initialize a new instance of the CustomConfigurationFileReader class that notifies
/// when the configuration file changes.
/// </summary>
/// <param name=\"configFileName\">The full path to the custom configuration file</param>
public CustomConfigurationFileReader(string configFileName)
: this(configFileName,DEFAULT_NOTIFY_BEHAVIOUR)
{
}
/// <summary>
/// Initialize a new instance of the CustomConfigurationFileReader class
/// </summary>
/// <param name=\"configFileName\">The full path to the custom configuration file</param>
/// <param name=\"notifyOnFileChange\">Indicate if to raise the FileChange event when the configuraiton file changes</param>
[ValidateParameters]
public CustomConfigurationFileReader([NotNull,FileExists]string configFileName,bool notifyOnFileChange)
{
// Set the configuration file name
_configFileName = configFileName;
// Read the configuration File
ReadConfiguration();
// Start watch the configuration file (if notifyOnFileChanged is true)
if(notifyOnFileChange)
WatchConfigFile();
}
#endregion Constructor
/// <summary>
/// Get the configuration that represents the content of the configuration file
/// </summary>
public System.Configuration.Configuration Config
{
get;
set;
}
#region Helper Methods
/// <summary>
/// Watch the configuraiton file for changes
/// </summary>
private void WatchConfigFile()
{
var watcher = new FileSystemWatcher(_configFileName);
watcher.Changed += ConfigFileChangedEvent;
}
/// <summary>
/// Read the configuration file
/// </summary>
public void ReadConfiguration()
{
// Create config file map to point to the configuration file
var configFileMap = new ExeConfigurationFileMap
{
ExeConfigFilename = _configFileName
};
// Create configuration object that contains the content of the custom configuration file
Config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap,ConfigurationUserLevel.None);
}
/// <summary>
/// Called when the configuration file changed.
/// </summary>
/// <param name=\"sender\"></param>
/// <param name=\"e\"></param>
private void ConfigFileChangedEvent(object sender,FileSystemEventArgs e)
{
// Check if the file changed event has listeners
if (FileChanged != null)
// Raise the event
FileChanged(this,new EventArgs());
}
#endregion Helper Methods
}
}
解决方法
// Map the roaming configuration file. This
// enables the application to access
// the configuration file using the
// System.Configuration.Configuration class
ExeConfigurationFileMap configFileMap =
new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename =
roamingConfig.FilePath;
// Get the mapped configuration file.
Configuration config =
ConfigurationManager.OpenMappedExeConfiguration(
configFileMap,ConfigurationUserLevel.None);
来自http://msdn.microsoft.com/zh-cn/library/system.configuration.configurationmanager.aspx
, 过去,我使用Nini-http://nini.sourceforge.net/manual.php,它允许您在运行时读取/写入自定义配置文件(XML / Ini / Registry / .Config)。
希望这可以帮助。
, 我对配置的建议是创建您自己的组件以进行阅读。
如果在某个时候您决定要从数据库或Web服务等其他来源获取配置,则可能会简化开发。
这种抽象还可以帮助您模拟配置并提高可测试性(.NET框架根本无法很好地完成某些工作)。
如果您使用XML作为配置格式,则建议使用Linq to XML。
阅读和解析XML文件更加容易。
, 您可以根据需要尝试Cinchoo框架。它通过代码优先方法简化了开发工作。如下定义一个类,
namespace HelloWorld
{
#region NameSpaces
using System;
using Cinchoo.Core.Configuration;
#endregion NameSpaces
[ChoConfigurationSection(\"sample\")]
public class SampleConfigSection : ChoConfigurableObject
{
#region Instance Data Members (Public)
[ChoPropertyInfo(\"name\",DefaultValue=\"Mark\")]
public string Name;
[ChoPropertyInfo(\"message\",DefaultValue=\"Hello World!\")]
public string Message;
#endregion
}
static void Main(string[] args)
{
SampleConfigSection sampleConfigSection = new SampleConfigSection();
Console.WriteLine(sampleConfigSection.ToString());
}
}
首次运行该应用程序时,它将在[appexename] .xml文件中创建配置部分,如下所示。然后,对该文件所做的任何更改将自动被拾取
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<configuration>
<configSections>
<section name=\"sample\" type=\"Cinchoo.Core.Configuration.ChoNameValueSectionHandler,Cinchoo.Core,Version=1.0.0.0,Culture=neutral,PublicKeyToken=b7dacd80ff3e33de\" />
</configSections>
<sample>
<add key=\"name\" value=\"Mark\" />
<add key=\"message\" value=\"Hello World!\" />
</sample>
</configuration>
, 或使用NameValueCollection更容易
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。