我正在尝试动态地将模块加载到我的应用程序中,但我想为每个模块指定单独的app.config文件。
假设我有以下主应用程序的app.config设置:
<appSettings>
<add key="House" value="Stark"/>
<add key="Motto" value="Winter is coming."/>
</appSettings>
另一个用我使用Assembly.LoadFrom
加载的库:
<appSettings>
<add key="House" value="Lannister"/>
<add key="Motto" value="Hear me roar!"/>
</appSettings>
两个库都有一个实现相同接口的类,使用以下方法:
public string Name
{
get { return ConfigurationManager.AppSettings["House"]; }
}
确实从主类和加载的程序集类Name
调用Stark
。
有没有办法让主应用程序使用自己的app.config并且每个加载的程序集都使用他们的?配置文件的名称在输出中是不同的,所以我认为这应该是可能的。
答案 0 :(得分:13)
好的,这是我最终得到的简单解决方案: 在实用程序库中创建以下函数:
public static Configuration LoadConfig()
{
Assembly currentAssembly = Assembly.GetCallingAssembly();
return ConfigurationManager.OpenExeConfiguration(currentAssembly.Location);
}
在动态加载的库中使用它,如下所示:
private static readonly Configuration Config = ConfigHelpers.LoadConfig();
无论该库如何加载,它都使用正确的配置文件。
修改强> 这可能是将文件加载到ASP.NET应用程序的更好解决方案:
public static Configuration LoadConfig()
{
Assembly currentAssembly = Assembly.GetCallingAssembly();
string configPath = new Uri(currentAssembly.CodeBase).LocalPath;
return ConfigurationManager.OpenExeConfiguration(configPath);
}
要在构建后复制文件,您可能需要将以下行添加到asp app的后期构建事件中(从库中提取配置):
copy "$(SolutionDir)<YourLibProjectName>\$(OutDir)$(Configuration)\<YourLibProjectName>.dll.config" "$(ProjectDir)$(OutDir)"
答案 1 :(得分:4)
据我所知,您需要单独的应用程序域才能使app.config单独工作。通过创建AppDomainSetup,您可以指定要使用的配置文件。我是这样做的:
try
{
//Create the new application domain
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = Path.GetDirectoryName(config.ExePath) + @"\";
ads.ConfigurationFile =
Path.GetDirectoryName(config.ExePath) + @"\" + config.ExeName + ".config";
ads.ShadowCopyFiles = "false";
ads.ApplicationName = config.ExeName;
AppDomain newDomain = AppDomain.CreateDomain(config.ExeName + " Domain",
AppDomain.CurrentDomain.Evidence, ads);
//Execute the application in the new appdomain
retValue = newDomain.ExecuteAssembly(config.ExePath,
AppDomain.CurrentDomain.Evidence, null);
//Unload the application domain
AppDomain.Unload(newDomain);
}
catch (Exception e)
{
Trace.WriteLine("APPLICATION LOADER: Failed to start application at: " +
config.ExePath);
HandleTerminalError(e);
}
获得所需效果的另一种方法是在编译到每个DLL中的资源文件中实现配置值。通过配置对象的简单界面,您可以在app.config中查找,而不是查看资源文件。