我在一个环境中使用EntLib,在这个环境中,从一个解密专有配置文件的单独库调用中检索数据库连接字符串。我对这种做法或配置文件的格式没有发言权。
我想在此设置中对数据库执行EntLib异常日志记录。因此,我需要使用连接字符串设置具有数据库名称的EntLib数据库配置实例。由于我无法在运行时获取连接字符串,但EntLib允许运行时配置,因此我使用以下代码,如this中所述:
builder.ConfigureData()
.ForDatabaseNamed("Ann")
.ThatIs.ASqlDatabase()
.WithConnectionString(connectionString)
.AsDefault();
参数connectionString
是我从单独的库中检索到的参数。
示例代码继续将创建的配置信息与空的DictionaryConfigurationSource合并。但是,我需要将它与app.config中的其余配置代码合并。所以我这样做:
var configSource = new SystemConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
EnterpriseLibraryContainer.Current
= EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
...它非常依赖于示例代码。
但是:我在Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource.Save中收到内部错误。失败的代码是:
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = ConfigurationFilePath };
var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
config.Sections.Remove(section);
config.Sections.Add(section, configurationSection);
config.Save();
...其中'部分'是" connectionStrings"。代码在Add方法调用上失败,表示您无法添加重复的部分。检查显示即使在删除后,connectionStrings部分仍然存在。
我从经验中知道,当实际读取和解释配置文件时,connectStrings下始终存在默认条目,继承自machine.config。所以也许你永远不能真正删除connectionStrings部分。
但是,这似乎让我失去了运气,除非我想修改EntLib源,我不这样做。
我可以使用fluent API在运行时为EntLib构建所有配置信息。但我不愿意。用户希望他们的操作人员能够对日志记录进行小的更改,而无需涉及开发人员。
所以我的问题,在几个部分:这有一个很好的简单解决方法吗?是否需要更改EntLib源?或者我错过了一些可以解决问题的简单方法?
答案 0 :(得分:2)
由于this post,我找到了解决方法。我将我在app.config
中设置的部分复制到构建器中,然后在空虚拟配置源对象上执行UpdateConfigurationWithReplace
,而不是从构建器中获取系统配置源并尝试更新它。命令创建可用于创建默认容器的ConfigurationSource
。
var builder = new ConfigurationSourceBuilder();
var configSource = new SystemConfigurationSource();
CopyConfigSettings("loggingConfiguration", builder, configSource);
CopyConfigSettings("exceptionHandling", builder, configSource);
// Manually configure the database settings
builder.ConfigureData()
.ForDatabaseNamed("Ann")
.ThatIs.ASqlDatabase()
.WithConnectionString(connectionString)
.AsDefault();
// Update a dummy, empty ConfigSource object with the settings we have built up.
// Remember, this is a config settings object for the EntLib, not for the entire program.
// So it doesn't need all 24 sections or however many you can set in the app.config.
DictionaryConfigurationSource dummySource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(dummySource);
// Create the default container using our new ConfigurationSource object.
EnterpriseLibraryContainer.Current
= EnterpriseLibraryContainer.CreateDefaultContainer(dummySource);
关键是这个子程序:
/// <summary>
/// Copies a configuration section from the SystemConfigurationSource to the ConfigurationSourceBuilder.
/// </summary>
/// <param name="sectionName"></param>
/// <param name="builder"></param>
/// <param name="configSource"></param>
private static void CopyConfigSettings(string sectionName, ConfigurationSourceBuilder builder, SystemConfigurationSource configSource)
{
ConfigurationSection section = configSource.GetSection(sectionName);
builder.AddSection(sectionName, section);
}