2012-10-18 64 views
3

我想從具有自己的app.config文件的MEF插件訪問ConfigurationManager.AppSettings對象中的值。從MEF插件中讀取AppSettings

但是,加載插件後,app.config文件中的密鑰不存在於AppSettings中。 加載插件的應用程序中的鍵仍然存在。

我注意到使用Settings.settings文件允許這種行爲,通過app.config文件,所以文件必須以某種方式加載。

我的插件看起來像:

[Export(IPlugin)] 
public class Plugin 
{ 
    public Plugin() 
    { 
     // reads successfully from app.config via Settings object 
     var value1 = Settings.Default["Key1"]; 

     // returns null from app.config via ConfigurationManager 
     var value1 = ConfigurationManager.AppSettings["Key2"] 
    } 
} 

app.config看起來是這樣的:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <sectionGroup name="applicationSettings" type="..." > 
     <section name="Plugin.Settings" type="..." /> 
    </sectionGroup> 
    </configSections> 

    <appSettings> 
    <add key="Key2" value="Fails" /> 
    </appSettings> 

    <applicationSettings> 
    <Plugin.Settings> 
     <setting name="Key1" serializeAs="String"> 
     <value>Works</value> 
     </setting> 
    </Plugin.Settings> 
    </applicationSettings> 
</configuration> 

我可以手動加載app.config文件:

var config = ConfigurationManager.OpenExeConfiguration("Plugin.dll"); 
var value = AppSettings.Settings["Key2"].Value 

但這似乎更像比解決方案更好的解決方法。

有沒有辦法直接從插件中訪問MEF插件的<appSettings>? 如果不是,建議什麼?

回答

8

默認情況下,ConfigurationManager加載入口程序集的.config,即啓動當前正在執行的程序的程序集。

正確的方式做,這將是這樣的:

[Export(IPlugin)] 
public class Plugin 
{ 
    public Plugin() 
    { 
     var config = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location); 
     var value = config.AppSettings.Settings["Key2"].Value; 
    } 
} 

這將使插件自動打開它被編譯在DLL中的.config,並從中獲取價值。

+0

我明白了。難道這是當我打電話給'Settings.Default'時'幕後'發生了什麼? –

+0

也許吧。我不確定,但是反射器可以肯定地說明了這一點。 –

+0

沒有從Reflector中學到很多東西,它變得相當複雜......但是'GetExecutingAssembly()'調用對於硬編碼DLL名稱更可取。看起來我會用這種技術。 –

2

我建議你使用像Unity這樣的依賴注入工具,以便爲插件提供他們所需的配置。通過這種方式進行操作,您的插件將不再需要引用System.Configuration.dll。

+1

不幸的是,我們不能將Unity用於當前的項目,但它看起來像是用於未來項目的東西。 –