1

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

我想在此设置中将 EntLib 异常记录到数据库中。因此,我需要使用数据库名称和连接字符串设置一个 EntLib 数据库配置实例。由于直到运行时我才能获得连接字符串,但 EntLib 确实允许运行时配置,所以我使用以下代码,如下所述

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 方法调用上失败,说您不能添加重复的部分。检查显示,即使在 Remove 之后,connectionStrings 部分仍然存在。

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

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

我或许可以在运行时使用 fluent API 构建 EntLib 的所有配置信息。但我宁愿不要。用户希望他们的操作人员能够对日志进行小的更改,而无需开发人员参与。

所以我的问题分为几个部分:是否有一个很好的简单解决方法?是否需要更改 EntLib 源?还是我错过了一些可以解决问题的非常简单的事情?

4

1 回答 1

2

多亏了这篇文章,我找到了解决方法。我没有获取系统配置源并尝试从构建器更新它,而是将我设置的部分复制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);
    }
于 2012-07-31T15:05:42.763 回答