C#程序中,不管是Dll还是exe程序,都有可能会有app.config的配置文件。
虽然IronPython可以和C#的Dll无缝引用,但是一旦DLL中使用到了app.config,还是会碰到问题的。
比如,创建了一个Dll(编译后,会生成一个TestClassLibrary.dll的类库)
namespace TestClassLibrary
{
public class TestDll
{
public void Outputconfig()
{
Console.WriteLine(ConfigurationManager.AppSettings.Get("testkey"));
}
}
}
方法Outputconfig会输出配置文件中的testkey节点信息
app.config的内容为
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="testkey" value="localhost" />
</appSettings>
</configuration>
此时如果简单的对这个Dll进行调用,如下
import clr
clr.AddReference("TestClassLibrary")
from TestClassLibrary import TestDll
t = TestDll()
t.Outputconfig()
运行后,发现没有任何输出。没有出现预期的localhost的值。
这里直接给出解决方法
import clr
clr.AddReference("System.Configuration")
from System.Configuration.Internal import IInternalConfigSystem
class ConfigurationProxy(IInternalConfigSystem):
def __init__(self, fileName):
from System import String
from System.Collections.Generic import Dictionary
from System.Configuration import IConfigurationSectionHandler, ConfigurationErrorsException
self.__customSections = Dictionary[String, IConfigurationSectionHandler]()
loaded = self.Load(fileName)
if not loaded:
raise ConfigurationErrorsException(String.Format("File: {0} could not be found or was not a valid cofiguration file.", fileName))
def Load(self, fileName):
from System.Configuration import ExeConfigurationFileMap, ConfigurationManager, ConfigurationUserLevel
exeMap = ExeConfigurationFileMap()
exeMap.ExeConfigFilename = fileName
self.__config = ConfigurationManager.OpenMappedExeConfiguration(exeMap, ConfigurationUserLevel.None);
return self.__config.HasFile;
def GetSection(self, configKey):
if configKey == "appSettings":
return self.__BuildAppSettings()
return self.__config.GetSection(configKey);
def __BuildAppSettings(self):
from System.Collections.Specialized import NameValueCollection
coll = NameValueCollection()
for key in self.__config.AppSettings.Settings.AllKeys:
coll.Add(key, self.__config.AppSettings.Settings[key].Value);
return coll
def RefreshConfig(self, sectionName):
self.Load(self.__config.FilePath)
def SupportsUserConfig(self):
return False
def InjectToConfigurationManager(self):
from System.Reflection import BindingFlags
from System.Configuration import ConfigurationManager
configSystem = clr.GetClrType(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic)
configSystem.SetValue(None, self);
通过上述的类,可以指定特定的app.config来加载
proxy = ConfigurationProxy(r"E:\TestClassLibrary.dll.config")
proxy.InjectToConfigurationManager()
import clr
clr.AddReference("TestClassLibrary")
from TestClassLibrary import TestDll
t = TestDll()
t.Outputconfig()
这样,就可以在控制台中看到输出的localhost值了
上述只是介绍一种简单的场景。实际在使用的过程中,可能是在初始化对象的时候,就需要从配置文件中获取信息。一旦对象初始化失败,待测方法就无法被正确的调用。
解决方法和上述一样。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。