【问题标题】:Can `System.Configuration.ConfigurationManager.ConnectionStrings` be updated with non-default configuration file values?可以使用非默认配置文件值更新“System.Configuration.ConfigurationManager.ConnectionStrings”吗?
【发布时间】:2018-02-22 01:04:34
【问题描述】:

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

我已经确定我可以使用System.Configuration.ConfigurationManager.OpenMappedExeConfiguration 通过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 属性的值?或者,有什么方法可以将默认配置重新定义为一个新的配置文件在运行时定义,希望能得到想要的最终结果?

【问题讨论】:

  • 紧接着 - ConfigurationManager.OpenMappedExeConfiguration - 检查configHasFile 属性。有时它会做诸如 not 之类的坏事,即使它没有加载文件也会抛出异常。它会给你一个Configuration 对象,其中不包含你文件中的内容。
  • 是的,HasFile 属性是 trueFilePath 是我的连接字符串的非默认配置文件。
  • 你不能改变应用程序的设计,为你的连接使用专门的服务,连接管理器或配置服务之类的。
  • 当然可以,但我知道我可以做到。我问这个问题是为了看看是否有任何我不熟悉的配置技巧可以在这种情况下工作。

标签: c# .net connection-string configurationmanager


【解决方案1】:

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

如果这个Configuration 被正确加载:

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

然后就可以从那里得到连接字符串了。

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

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

【讨论】:

  • 我不认为这就是他所追求的。他想映射ConfigurationManager.ConnectionStrings 指向更动态的东西,在运行时设置,至少这是我正在阅读的内容。
  • 如果我有机会更改此代码,知道我对 .NET 配置的了解,我将删除对 ConfigurationManager 静态集合的依赖。目前,我正在探索现有的代码替代方案。
【解决方案2】:

一个有趣的反射解决方法我discovered 允许通过使用反射更改System.Configuration.ConfigurationManager.ConnectionStrings 的非公共System.Configuration.ConfigurationElementCollection.bReadOnly 属性:

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 属性的预期用途。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2012-08-16
    • 2016-06-10
    • 2018-08-29
    • 1970-01-01
    相关资源
    最近更新 更多