有沒有什麼方法可以在運行時從默認App.config
文件以外的其他文件加載設置?我想在加載默認配置文件後執行此操作。加載屬性。在運行時從另一個文件中設置
我在Visual Studio中使用Settings.Settings
GUI來爲我創建我的App.config
文件。該配置文件最終看起來像這樣:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="SnipetTester.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<SnipetTester.Properties.Settings>
<setting name="SettingSomething" serializeAs="String">
<value>1234</value>
</setting>
</SnipetTester.Properties.Settings>
</applicationSettings>
</configuration>
在代碼中,我能夠獲得這樣的設置:
Console.WriteLine("Default setting value: " + Properties.Settings.Default.SettingSomething);
的想法是,在應用程序運行的時候,我應該是能夠在運行時指定配置文件,並讓應用程序將配置文件加載到Properties.Settings.Default
對象中,而不是使用默認的app.config
文件。配置文件的格式將是相同的,但設置的值將會不同。
我知道用ConfigurationManager.OpenExeConfiguration(configFile);
這樣做的方法。但是,在我運行的測試中,它不會更新Properties.Settings.Default
對象以反映配置文件中的新值。
考慮了這一點後,我已經能夠想出一個我喜歡更好一點的解決方案。我相信它有一些陷阱,但我認爲它會爲我需要它做的工作。
本質上,Properties.Settings
類是由Visual Studio自動生成的;它爲你生成類的代碼。我能夠找到代碼的生成位置,並添加一些函數調用來自行加載配置文件。這裏是我的加法:
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
//Parses a config file and loads its settings
public void Load(string filename)
{
System.Xml.Linq.XElement xml = null;
try
{
string text = System.IO.File.ReadAllText(filename);
xml = System.Xml.Linq.XElement.Parse(text);
}
catch
{
//Pokemon catch statement (gotta catch 'em all)
//If some exception occurs while loading the file,
//assume either the file was unable to be read or
//the config file is not in the right format.
//The xml variable will be null and none of the
//settings will be loaded.
}
if(xml != null)
{
foreach(System.Xml.Linq.XElement currentElement in xml.Elements())
{
switch (currentElement.Name.LocalName)
{
case "userSettings":
case "applicationSettings":
foreach (System.Xml.Linq.XElement settingNamespace in currentElement.Elements())
{
if (settingNamespace.Name.LocalName == "SnipetTester.Properties.Settings")
{
foreach (System.Xml.Linq.XElement setting in settingNamespace.Elements())
{
LoadSetting(setting);
}
}
}
break;
default:
break;
}
}
}
}
//Loads a setting based on it's xml representation in the config file
private void LoadSetting(System.Xml.Linq.XElement setting)
{
string name = null, type = null, value = null;
if (setting.Name.LocalName == "setting")
{
System.Xml.Linq.XAttribute xName = setting.Attribute("name");
if (xName != null)
{
name = xName.Value;
}
System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs");
if (xSerialize != null)
{
type = xSerialize.Value;
}
System.Xml.Linq.XElement xValue = setting.Element("value");
if (xValue != null)
{
value = xValue.Value;
}
}
if (string.IsNullOrEmpty(name) == false &&
string.IsNullOrEmpty(type) == false &&
string.IsNullOrEmpty(value) == false)
{
switch (name)
{
//One of the pitfalls is that everytime you add a new
//setting to the config file, you will need to add another
//case to the switch statement.
case "SettingSomething":
this[name] = value;
break;
default:
break;
}
}
}
}
我添加的代碼暴露了Properties.Settings.Load(string filename)
函數。該函數接受一個配置文件名作爲參數。它將解析該文件並加載它在配置文件中遇到的任何設置。要恢復到原始配置,只需致電Properties.Settings.Reload()
即可。
希望這可以幫助別人!
這似乎真的很有希望,但我們如何使用類型 – tofutim 2015-09-21 22:57:07