gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:33:17 26 4
gpt4 key购买 nike

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

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

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

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

在我评估这个问题的过程中,我想出了与这里提供的相同的解决方案:Reload app.config with nunit .
不幸的是,它似乎没有做任何事情,因为我仍然从正常的 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 不同的值,但它会打印相同的值两次。

最佳答案

如果在第一次使用配置系统之前使用链接问题中的 hack,它就会起作用。在那之后,它就不再起作用了。
原因:
存在一个缓存路径的类 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) 放在应用程序开始的某处即可。

关于c# - 在运行时更改默认的 app.config,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6150644/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com