.net 是否有方法覆盖ConfigurationManager.AppSettings?
我真的希望能够找到一种方法,使用ConfigurationManager.AppSettings[“mysettingkey”]获取当前设置的应用程序,使这些设置实际上来自一个集中的数据库,而不是app.config文件。我可以创建一个自定义配置节来处理这类事情,但我真的不希望我的团队中的其他开发人员必须更改他们的代码才能使用我的新DbConfiguration自定义节。我只是希望他们能够像往常一样调用AppSettings,但要从中央数据库加载它.net 是否有方法覆盖ConfigurationManager.AppSettings?,.net,configuration,app-config,.net,Configuration,App Config,我真的希望能够找到一种方法,使用ConfigurationManager.AppSettings[“mysettingkey”]获取当前设置的应用程序,使这些设置实际上来自一个集中的数据库,而不是app.config文件。我可以创建一个自定义配置节来处理这类事情,但我真的不希望我的团队中的其他开发人员必须更改他们的代码才能使用我的新DbConfiguration自定义节。我只是希望他们能够像往常一样调用AppSettings,但要从中央数据库加载它 有什么想法吗?我不确定您是否可以覆盖它,但您可
有什么想法吗?我不确定您是否可以覆盖它,但您可以尝试AppSettings的Add方法,在应用程序启动时添加DB设置。无论您做什么,都需要添加一层重定向?ConfigurationManager.AppSettings[“key”]将始终在配置文件中查找。您可以从DatabaseManager进行配置,但这将导致使用不同的调用语法:
ConfigurationFromDatabaseManager.AppSettings["key"] instead of ConfigurationSettings["key"].
在.NET 3.5中,似乎可以通过在machine.config的appSettings定义部分中设置allowOverride属性来实现这一点。这允许您覆盖自己的app.config文件中的整个部分,并指定一个新类型来处理它。如果您不介意对框架进行黑客攻击,并且可以合理地假设应用程序运行的是.net framework版本(即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!");
}
}
我将尝试编写一个应用程序启动器,并将设置从数据库加载到应用程序域。因此,应用程序不知道它的配置是如何生成的。
使用machiene.config直接导入dll hell 2.0。如果可以将修改后的配置文件保存到磁盘,则可以在不同的应用程序域中加载替代配置文件:
AppDomain.CreateDomain("second", null, new AppDomainSetup
{
ConfigurationFile = options.ConfigPath,
}).DoCallBack(...);
我认为这个问题的原因是需要覆盖代码中的现有用法,以消除对大量代码基更改的需要。可能是错误的。但是,这是唯一存在的干净解决方案(除非您正在创建Azure web应用程序,您可以通过Azure门户设置应用程序设置)。私有反射。。。非常淘气。NETFramework版本与上面的示例有什么特别的关系?i、 我正在尝试一个类似的例子,但是尽管SetValue似乎正在设置值,但最终尝试检索配置设置失败-那么,在什么情况下,上面的代码可能不起作用?谢谢
s_configSystem
private字段是ConfigurationManager
的一个实现细节,它可能会在未来的框架版本中更改,或者根本不存在(例如mono有一个名为的字段)。这太复杂了,并且有很多问题,比如无限递归(如果您在GetSection中使用数据库上下文)并且仅适用于在运行时不会更改的静态配置。您正在谈论的applicationstarter是什么?我认为这没有抓住问题的重点。我对这个问题的理解是如何覆盖app.config,而不是如何使用app.config覆盖machine.config。