将运行时创建的部分配置与系统配置合并

时间:2012-07-30 19:34:10

标签: configuration app-config enterprise-library

我在一个环境中使用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源?或者我错过了一些可以解决问题的简单方法?

1 个答案:

答案 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);
    }