Configuration 将运行时创建的节配置与系统配置合并

Configuration 将运行时创建的节配置与系统配置合并,configuration,app-config,enterprise-library,Configuration,App Config,Enterprise Library,我在一个环境中使用EntLib,在这个环境中,数据库连接字符串是从一个单独的库调用中检索的,该库调用将解密一个专有的配置文件。我对这种做法或配置文件的格式没有发言权 我想在此设置中对数据库执行EntLib异常日志记录。因此,我需要使用数据库名称和连接字符串设置一个EntLib数据库配置实例。由于在运行时之前无法获取连接字符串,但EntLib允许运行时配置,因此我使用以下代码,如中所述: 参数connectionString是我从单独的库中检索到的参数 示例代码继续将创建的配置信息与空Dictio

我在一个环境中使用EntLib,在这个环境中,数据库连接字符串是从一个单独的库调用中检索的,该库调用将解密一个专有的配置文件。我对这种做法或配置文件的格式没有发言权

我想在此设置中对数据库执行EntLib异常日志记录。因此,我需要使用数据库名称和连接字符串设置一个EntLib数据库配置实例。由于在运行时之前无法获取连接字符串,但EntLib允许运行时配置,因此我使用以下代码,如中所述:

参数
connectionString
是我从单独的库中检索到的参数

示例代码继续将创建的配置信息与空DictionaryConfiguration源合并。一、 但是,需要将其与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();
。。。其中“节”是“连接字符串”。代码在Add方法调用时失败,表示无法添加重复的节。检查表明,即使在拆卸后,连接管柱部分仍然存在

我从经验中知道,在实际读取和解释配置文件时,ConnectionString下总是有一个默认条目,从machine.config继承。因此,也许您永远无法真正删除ConnectionString部分

不过,这似乎让我很不走运,除非我想修改EntLib源代码,而我不想修改

我也许可以在运行时使用fluentapi构建EntLib的所有配置信息。但我不想。用户希望他们的操作人员能够在不需要开发人员参与的情况下对日志进行小的更改


因此,我的问题分为几个部分:是否有一个简单的解决方法?是否需要更改EntLib源代码?还是我错过了一些可以解决问题的简单方法

多亏了你,我找到了一个解决办法。我将在
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);
    }
//
///将配置节从SystemConfigurationSource复制到ConfigurationSourceBuilder。
/// 
/// 
/// 
/// 
私有静态void CopyConfigSettings(字符串节名、ConfigurationSourceBuilder生成器、SystemConfigurationSource configSource)
{
ConfigurationSection节=configSource.GetSection(节名);
建造商.添加区段(区段名称,区段);
}

您是否尝试过在配置文件的ConnectionString部分清除连接字符串?另外,如果您在进行日志记录时知道连接字符串,那么在初始化日志记录组件时,您能否直接设置它,而不是更新配置?@podiluska-是的,我尝试过清除连接字符串。这没什么区别。@podiluska-是EntLib在做日志记录,而不是我直接做的。因此,我从不亲自初始化日志组件。从我的代码的角度来看,它只是请求一个ExceptionManager实例并向其传递一个委托,ExceptionManager应该处理这些异常。它如何处理它们取决于配置。我知道。但是,当您通过unity或其他方式初始化exceptionmanager时,您不能在那里设置一些参数吗。。。?(我是凭记忆做的,你知道:))你能提供一个完整的代码样本吗?非常感谢。ty@David我认为这是完整的。你认为遗漏了什么?
    /// <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);
    }