在运行时更改默认的app.config

我有以下问题:

我们有一个加载模块(附加组件)的应用程序。这些模块可能需要在app.config中输入(例如WCF配置)。因为模块是动态加载的,所以我不想在应用程序的app.config文件中包含这些条目。

我想做的是以下几点:

  • 在内存中创建一个新的app.config,其中包含模块中的config部分
  • 告诉我的应用程序使用该新的app.config

注意:我不想覆盖默认的app.config!

它应该透明地工作,以便例如ConfigurationManager.AppSettings使用该新文件。

在评估此问题的过程中,我想出了与此处提供的解决方案相同的解决方案:使用nunit重新加载app.config。

不幸的是,它似乎没有任何作用,因为我仍然从正常的app.config中获取数据。

我使用以下代码对其进行了测试:

Console.WriteLine(ConfigurationManager.AppSettings["SettingA"]);

Console.WriteLine(Settings.Default.Setting);

var combinedConfig = string.Format(CONFIG2, CONFIG);

var tempFileName = Path.GetTempFileName();

using (var writer = new StreamWriter(tempFileName))

{

writer.Write(combinedConfig);

}

using(AppConfig.Change(tempFileName))

{

Console.WriteLine(ConfigurationManager.AppSettings["SettingA"]);

Console.WriteLine(Settings.Default.Setting);

}

它打印两次相同的值,尽管它combinedConfig包含普通app.config之外的其他值。

回答:

如果在首次使用配置系统之前就使用了链接问题中的技巧,则该技巧是可行的。在那之后,它不再起作用了。

原因:

存在一个ClientConfigPaths可缓存路径的类。因此,即使使用更改了路径SetData,也不会重新读取它,因为已经存在缓存的值。解决方案是也删除这些:

using System;

using System.Configuration;

using System.Linq;

using System.Reflection;

public abstract class AppConfig : IDisposable

{

public static AppConfig Change(string path)

{

return new ChangeAppConfig(path);

}

public abstract void Dispose();

private class ChangeAppConfig : AppConfig

{

private readonly string oldConfig =

AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();

private bool disposedValue;

public ChangeAppConfig(string path)

{

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);

ResetConfigMechanism();

}

public override void Dispose()

{

if (!disposedValue)

{

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);

ResetConfigMechanism();

disposedValue = true;

}

GC.SuppressFinalize(this);

}

private static void ResetConfigMechanism()

{

typeof(ConfigurationManager)

.GetField("s_initState", BindingFlags.NonPublic |

BindingFlags.Static)

.SetValue(null, 0);

typeof(ConfigurationManager)

.GetField("s_configSystem", BindingFlags.NonPublic |

BindingFlags.Static)

.SetValue(null, null);

typeof(ConfigurationManager)

.Assembly.GetTypes()

.Where(x => x.FullName ==

"System.Configuration.ClientConfigPaths")

.First()

.GetField("s_current", BindingFlags.NonPublic |

BindingFlags.Static)

.SetValue(null, null);

}

}

}

用法是这样的:

// the default app.config is used.

using(AppConfig.Change(tempFileName))

{

// the app.config in tempFileName is used

}

// the default app.config is used.

如果要在整个应用程序运行时更改使用的app.config,只需AppConfig.Change(tempFileName)在应用程序开始处放置而不使用的位置即可。

以上是 在运行时更改默认的app.config 的全部内容, 来源链接: utcz.com/qa/412679.html

回到顶部