【发布时间】:2011-03-04 16:36:05
【问题描述】:
我正在尝试在不同于应用程序启动路径的路径中使用应用程序配置文件。我发现我可以更改配置文件名:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", NewConfigFullFilename);
在此之后,一些方法可以正常工作,例如。 ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) 加载正确的文件,其他方法不起作用,例如。 ConfigurationManager.GetSection("system.serviceModel/client") 不会从文件中加载该部分。
我发现这个是因为我需要使用配置文件创建服务或通道工厂。写作:
channelFactory = new ChannelFactory<TContract>(EndpointConfigurationName);
我发生了崩溃,我想是因为内部代码使用了 GetSection 方法。我查看了 ConfigurationManager 类中的私有字段,发现 ClientConfigPaths 的实例在 _applicationCongiUri 字段中具有旧的配置文件名,而静态 s_current 字段具有正确的文件名。我使用愚蠢的代码通过反射来更改 2 个字段的值,并且正确地从新的配置文件加载服务:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", NewConfigFullFilename);
FieldInfo field = typeof(ConfigurationManager).GetField("s_initLock", BindingFlags.Static | BindingFlags.NonPublic);
object lockobj = field.GetValue(null);
lock (lockobj)
{
typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, 0);
}
field = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic);
object s_configSystem = field.GetValue(null);
field = s_configSystem.GetType().GetField("_configHost", BindingFlags.Instance | BindingFlags.NonPublic);
object _configHost = field.GetValue(s_configSystem);
field = _configHost.GetType().GetField("_configPaths", BindingFlags.Instance | BindingFlags.NonPublic);
object _configPaths = field.GetValue(_configHost);
field = _configPaths.GetType().GetField("_applicationConfigUri", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(_configPaths, NewConfigFullFilename);
field = _configPaths.GetType().GetField("_localConfigFilename", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(_configPaths, NewConfigFullFilename);
现在我想知道是否有其他方法可以这样做,或者是否是 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE" 不够的错误,或任何其他建议。
谢谢
【问题讨论】:
标签: wcf app-config