在运行时更改默认app.config

在运行时更改默认app.config

我有以下问题:
我们有一个加载模块的应用程序(添加ON)。这些模块可能需要app.config中的条目(例如,WCF配置)。由于模块是动态加载的,所以我不希望应用程序的app.config文件中有这些条目。
我想做的是:

  • 在内存中创建一个新的app.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以外的其他值。


SMILET
浏览 758回答 3
3回答

有只小跳蛙

如果在第一次使用配置系统之前就使用了链接问题,那么链接问题中的黑客就能工作。在那之后,它就不再起作用了。原因:存在一个类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,查看更多内容
随时随地看视频慕课网APP