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 メソッドの呼び出しで失敗し、重複するセクションを追加できないことを示しています。調べたところ、削除後も connectionStrings セクションがまだ残っていることがわかります。

経験から、構成ファイルが実際に読み取られて解釈され、machine.config から継承される場合、connectionStrings の下に常に既定のエントリがあることを知っています。したがって、connectionStrings セクションを実際に削除することはできません。

ただし、EntLib ソースを変更したくない場合を除いて、それは運が悪いように見えますが、私は変更しません。

流暢な API を使用して、実行時に EntLib のすべての構成情報を作成することもできます。しかし、私はむしろしたくありません。ユーザーは、運用スタッフが開発者を介さずにロギングに小さな変更を加えることができることを望んでいます。

だから私の質問は、いくつかの部分で: これに対する素敵な簡単な回避策はありますか? EntLib ソースを変更する必要がありますか? それとも、問題を解決する本当に簡単なことを見逃していませんか?

4

1 に答える 1

2

この投稿のおかげで、回避策を見つけました。システム構成ソースを取得してビルダーから更新しようとするのではなく、セットアップしたセクションをビルダーにコピーapp.configUpdateConfigurationWithReplace、空のダミー構成ソース オブジェクトに対して を実行して、作成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 に答える