Is there a way to override ConfigurationManager.AppSettings?

倾然丶 夕夏残阳落幕 提交于 2019-11-26 20:34:49

问题


I really want to be able to have a way to take an app that currently gets its settings using ConfigurationManager.AppSettings["mysettingkey"] to actually have those settings come from a centralized database instead of the app.config file. I can make a custom config section for handling this sort of thing, but I really don't want other developers on my team to have to change their code to use my new DbConfiguration custom section. I just want them to be able to call AppSettings the way they always have but have it be loaded from a central database.

Any ideas?


回答1:


If you don't mind hacking around the framework and you can reasonably assume the .net framework version the application is running on (i.e. it's a web application or an intranet application) then you could try something like this:

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!");
  }
}



回答2:


Whatever you do you will need to add one layer of redirection? ConfigurationManager.AppSettings["key"] will always look in the configuration file. You can make a ConfigurationFromDatabaseManager but this will result in using different calling syntax:

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



回答3:


I'm not sure you can override it, but you can try the Add method of AppSettings to add your DB settings when the applications starts.




回答4:


I would try to write an application starter and load the settings from the database to the application domain. So the app doesn't know anything about how it's configuration is generated. Using machiene.config leads directly into dll-hell 2.0.




回答5:


If you can save you modified config file to disk - you can load alternative config file in different application domain:

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



回答6:


It appears there is a way to do this in .NET 3.5 by setting the allowOverride attribute in the appSettings definition section of machine.config. This allows you to override the entire section in your own app.config file and specify a new type to handle it.



来源:https://stackoverflow.com/questions/158783/is-there-a-way-to-override-configurationmanager-appsettings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!