Tuesday, January 22, 2008

about class library dll config file


Keywords: Class library, app configuration file


第一: 尽量不要为Class Library建立app.config文件


A dll will not have a config file, this is by design, because actually the app config file is per AppDomain while the dll did not have its own appdomain, it is loaded into the Exe's default appdomain by default.


上面的说明来自网上, 经试验, 确实不应用Visual studio 的向导为Class Library project中增加一个app config文件, 因为在dll的代码中直接使用ConfigurationManager对象是无法获取到ClassLibrary1.dll.config中的信息(假设类库为ClassLibrary1), 它所获取的是该dll的所属exe的app.config的信息.


测试实例:
下面是ClassLibrary1.dll.config的内容:



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="key1" value="value1"/>
<add key="key2" value="value2"/>
</appSettings>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="TestConfig.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<TestConfig.Properties.Settings>
<setting name="Setting1" serializeAs="String">
<value>abc</value>
</setting>
</TestConfig.Properties.Settings>
</userSettings>
</configuration>

在ClassLibrary1中读取配置文件的代码:


public string DirectUseConfigManager_In_Dll()
{
StringBuilder sb=new StringBuilder() ;
sb.Append("key1=" + ConfigurationManager.AppSettings.GetValues("key1"));
sb.Append(Environment.NewLine);
sb.Append("key2=" + ConfigurationManager.AppSettings.GetValues("key2"));
sb.Append(Environment.NewLine);
sb.Append("setting1=" + Settings.Default.Setting1);
sb.Append(Environment.NewLine);
return sb.ToString();
}

有一点需要说明的是: 如果你利用Visual Studio的Settings编辑器来编辑类库的App.config, 比如你增加了一个setting, 名为Setting1, 取值为"abc". 你也许会发现, 你的Exe项目在通过调用类库的DirectUseConfigManager_In_Dll(),可以读取到类库的app.config中的Setting1, 其实这只是一个假象. 打开类库的Settings.Designer.cs文件, 你会发现Setting1的有下面的代码.(注意第3行)


[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("abc")]
public string Setting1 {
get {
return ((string)(this["Setting1"]));
}
set {
this["Setting1"] = value;
}
}

从上面的代码可以看到, 其实Exe项目还是不能读取ClassLibrary1.dll.config文件.


第二: 怎样让ClassLibrary类库访问其app.config文件的方法.

直接用ConfigurationManager无法获取dll.config文件的原因是, ConfigurationManager确认会打开Exe的app.config文件, 如果ConfigurationManager能打开指定的配置文件, 问题就可以解决了.


在classLibrary1中通过下面代码, 就可以访问其app.config文件了.



public string UseConfigManager_OpenSpecificConfig_In_Dll()
{
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = @"ClassLibrary1.dll.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
//open appSettings section
AppSettingsSection section = (AppSettingsSection)config.GetSection("appSettings");

StringBuilder sb = new StringBuilder();
sb.Append("key1=" + section.Settings["key1"].Value);
return sb.ToString();
}

No comments: