2012-07-30 47 views
1

我在一個環境中使用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部分仍然存在。

我從經驗中知道,總會有下的ConnectionStrings當配置文件實際上閱讀和解釋,從machine.config中繼承了一個默認項。所以也許你永遠不會真的刪除connectionStrings部分。

雖然這似乎讓我失去了運氣,但是,除非我想修改EntLib源,我不這樣做。

我可以使用流利的API在運行時爲EntLib構建所有配置信息。但我寧願不。用戶希望他們的操作人員能夠對日誌進行小的更改,而無需涉及開發人員。

所以我的問題,在幾個部分:是否有一個很好的簡單的解決方法呢?它是否需要更改EntLib源?還是我錯過了一些非常簡單的事情,可以消除這個問題?

+0

您已經嘗試了清除在配置文件的connectionStrings節? – podiluska 2012-07-30 19:59:22

+0

另外,如果您在進行日誌記錄時知道連接字符串,那麼在初始化日誌記錄組件時是否可以不直接設置它,而不是更新配置? – podiluska 2012-07-30 20:02:32

+0

@podiluska - 是的,我試過一個清除。它沒有任何區別。 – 2012-07-30 20:05:37

回答

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); 
    } 
+1

你能提供給你一個完整的代碼樣本嗎?非常感謝。 ty – David 2012-09-30 15:06:23

+0

@大衛我認爲這是完整的。你認爲失蹤了什麼? – 2012-10-01 14:44:38