有没有办法覆盖ConfigurationManager.AppSettings?

时间:2008-10-01 17:36:06

标签: .net configuration app-config

我真的希望有一种方法可以使用 ConfigurationManager.AppSettings [“mysettingkey”] 获取当前获取其设置的应用,实际上这些设置来自集中式数据库而不是app.config文件。我可以创建一个自定义配置部分来处理这类事情,但我真的不希望团队中的其他开发人员必须更改他们的代码以使用我的新DbConfiguration自定义部分。我只是希望他们能够以他们一直以来的方式调用AppSettings,但是可以从中央数据库加载它。

有什么想法吗?

6 个答案:

答案 0 :(得分:25)

如果您不介意破解框架并且您可以合理地假设应用程序正在运行的.net框架版本(即它是Web应用程序或Intranet应用程序),那么您可以尝试这样的事情:

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Internal;
using System.Reflection;

static class ConfigOverrideTest
{
  sealed class ConfigProxy:IInternalConfigSystem
  {
    readonly IInternalConfigSystem baseconf;

    public ConfigProxy(IInternalConfigSystem baseconf)
    {
      this.baseconf = baseconf;
    }

    object appsettings;
    public object GetSection(string configKey)
    {
      if(configKey == "appSettings" && this.appsettings != null) return this.appsettings;
      object o = baseconf.GetSection(configKey);
      if(configKey == "appSettings" && o is NameValueCollection)
      {
        // create a new collection because the underlying collection is read-only
        var cfg = new NameValueCollection((NameValueCollection)o);
        // add or replace your settings
        cfg["test"] = "Hello world";
        o = this.appsettings = cfg;
      }
      return o;
    }

    public void RefreshConfig(string sectionName)
    {
      if(sectionName == "appSettings") appsettings = null;
      baseconf.RefreshConfig(sectionName);
    }

    public bool SupportsUserConfig
    {
      get { return baseconf.SupportsUserConfig; }
    }
  }

  static void Main()
  {
    // initialize the ConfigurationManager
    object o = ConfigurationManager.AppSettings;
    // hack your proxy IInternalConfigSystem into the ConfigurationManager
    FieldInfo s_configSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic);
    s_configSystem.SetValue(null, new ConfigProxy((IInternalConfigSystem)s_configSystem.GetValue(null)));
    // test it
    Console.WriteLine(ConfigurationManager.AppSettings["test"] == "Hello world" ? "Success!" : "Failure!");
  }
}

答案 1 :(得分:1)

无论你做什么,你都需要添加一层重定向? ConfigurationManager.AppSettings [“key”]将始终查看配置文件。您可以创建ConfigurationFromDatabaseManager,但这将导致使用不同的调用语法:

ConfigurationFromDatabaseManager.AppSettings["key"] instead of ConfigurationSettings["key"].

答案 2 :(得分:0)

我不确定您是否可以覆盖它,但您可以尝试使用AppSettings的Add方法在应用程序启动时添加数据库设置。

答案 3 :(得分:0)

我会尝试编写应用程序启动器并将设置从数据库加载到应用程序域。因此,该应用程序不知道如何生成配置。 使用machiene.config直接进入dll-hell 2.0。

答案 4 :(得分:0)

如果您可以将修改后的配置文件保存到磁盘 - 您可以在不同的应用程序域中加载备用配置文件:

AppDomain.CreateDomain("second", null, new AppDomainSetup
{
    ConfigurationFile = options.ConfigPath,
}).DoCallBack(...);

答案 5 :(得分:-1)

通过在machine.config的appSettings定义部分设置allowOverride属性,似乎可以在.NET 3.5中执行此操作。这允许您覆盖自己的app.config文件中的整个部分,并指定一个新类型来处理它。