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?
The appSettings element is primarily for custom app settings that are unique to your app, and have no . NET (or ASP.NET) equivalents, like a list of your clients' email addresses, or the tagline and copyright info for your cat blog.
ConfigurationManager was added to support ASP.NET Core's new WebApplication model, used for simplifying the ASP.NET Core startup code.
The ConfigurationManager class enables you to access machine, application, and user configuration information. This class replaces the ConfigurationSettings class, which is deprecated. For web applications, use the WebConfigurationManager class.
Namespace: System.Configuration To use the ConfigurationManager class, your project must reference the System. Configuration assembly. By default, some project templates, like Console Application, do not reference this assembly so you must manually reference it.
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!"); } }
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"].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With