【问题标题】:Merging runtime-created section config with system config将运行时创建的部分配置与系统配置合并
【发布时间】:2012-07-28 12:34:20
【问题描述】:

我在从解密专有配置文件的单独库调用中检索数据库连接字符串的环境中使用 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();

... 其中“section”是“connectionStrings”。代码在 Add 方法调用上失败,说您不能添加重复的部分。检查显示,即使在 Remove 之后,connectionStrings 部分仍然存在。

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

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

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

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

【问题讨论】:

  • 您是否尝试过在配置文件的连接字符串部分清除?
  • 另外,如果你在做日志的时候知道连接字符串,是不是可以在初始化日志组件的时候不直接设置,而不是更新配置呢?
  • @podiluska - 是的,我已经尝试过清除。没有任何区别。
  • @podiluska - 进行日志记录的是 EntLib,而不是我。所以我从不自己初始化日志组件。从我的代码的角度来看,它只是请求一个 ExceptionManager 实例并向其传递一个委托,即 ExceptionManager 应该处理的异常。它如何处理它们取决于配置。
  • 我知道。但是当你通过统一或其他方式初始化异常管理器时,你不能在那里设置一些参数......? (我是凭记忆做的,你懂的:))

标签: configuration app-config enterprise-library


【解决方案1】:

感谢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);
    }

【讨论】:

  • 您能否为此发送/提供完整的代码示例?非常感谢。 ty
  • @David 我认为这是完整的。您认为缺少什么?
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
相关资源
最近更新 更多