可以使用非默认配置文件值更新“System.Configuration.ConfigurationManager.ConnectionStrings”吗?

Can `System.Configuration.ConfigurationManager.ConnectionStrings` be updated with non-default configuration file values?

我正在尝试通过 ConfigurationManager.ConnectionStrings 静态 属性 在运行时 提供的任意配置文件中访问一组连接字符串 。应用程序代码需要连接字符串在此集合中,我需要在不编辑默认配置文件的情况下提供新值。

我确定可以使用System.Configuration.ConfigurationManager.OpenMappedExeConfiguration to load connection strings from an arbitrary configuration file by using System.Configuration.ExeConfigurationFileMap,例如:

using System.Configuration;

var config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap{ExeConfigFilename = 'some.config'}, ConfigurationUserLevel.None);

config.RefreshSection(config.ConnectionStrings.SectionInformation.SectionName);

在这种情况下,我希望能够从静态 ConfigurationManager.ConnectionStrings 属性 访问从 some.config 加载的连接字符串,但这似乎只包含可用的内容在应用程序配置默认值中。

是否可以屏蔽或复制到默认配置以更新静态 ConfigurationManager.ConnectionStrings 属性 的值?或者,是否有任何方法可以将默认配置重新定义为在运行时定义的新配置文件 ,从而有望获得所需的最终结果?

简短的回答是否定的。 ConfigurationManagerConnectionStringsAppSettings 属性只是为了方便从默认配置中读取。您可以加载其他配置,但不能更改这些方法的行为。

如果此 Configuration 已正确加载:

var config = ConfigurationManager.OpenMappedExeConfiguration(
    new ExeConfigurationFileMap{ExeConfigFilename = 'some.config'}.
        ConfigurationUserLevel.None);

然后您可以从那里获取连接字符串。

var connectionString = config.ConnectionStrings.ConnectionStrings["connectionName"]
    .ConnectionString;

部分答案是不要从 class 的深处使用 ConfigurationManagerConfiguration。您可以使用依赖注入,或者,在最坏的情况下,创建您自己的静态 class 来代替 ConfigurationManager。但这是一个完美的例子,说明了为什么您不希望 class 直接访问它,因为您无法更改其行为。

discovered allows changing the non-public System.Configuration.ConfigurationElementCollection.bReadOnly property of System.Configuration.ConfigurationManager.ConnectionStrings 一个有趣的反射解决方法,使用反射:

using System;
using System.Configuration;

var connectionString = "...";
var connectionStringSetting = new ConnectionStringSettings("OrionDB", connectionString);
var field = ConfigurationElementCollection.GetField("bReadOnly",
    Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance);
var connectionStrings = ConfigurationManager.ConnectionStrings;
field.SetValue(connectionStrings, false);
connectionStrings.Add(connectionStringSetting);

这给了我想要的行为,但不一定是静态 ConfigurationManager 属性的预期用途。