App config for dynamically loaded assemblies

非 Y 不嫁゛ 提交于 2019-12-03 09:19:32

问题


I'm trying to load modules into my application dynamically, but I want to specify separate app.config files for each one.

Say I have following app.config setting for main app:

<appSettings>
  <add key="House" value="Stark"/>
  <add key="Motto" value="Winter is coming."/>
</appSettings>

And another for library that I load using Assembly.LoadFrom:

<appSettings>
  <add key="House" value="Lannister"/>
  <add key="Motto" value="Hear me roar!"/>
</appSettings>

Both libraries have a class implementing the same interface, with the following method:

public string Name
{
    get { return ConfigurationManager.AppSettings["House"]; }
}

And sure enough calls to Name from both main class and loaded assembly class output Stark.

Is there a way to make main app use its own app.config and each loaded assembly use theirs? Names of config files are different in the output, so that should be possible I think.


回答1:


Ok, here's the simple solution I ended up with: Create the follow function in the utility library:

public static Configuration LoadConfig()
{
    Assembly currentAssembly = Assembly.GetCallingAssembly();
    return ConfigurationManager.OpenExeConfiguration(currentAssembly.Location);
}

Using it in dynamically loaded libraries like this:

private static readonly Configuration Config = ConfigHelpers.LoadConfig();

No matter how that library gets loaded it uses the correct config file.

Edit: This might be the better solution for loading files into ASP.NET applications:

public static Configuration LoadConfig()
{
    Assembly currentAssembly = Assembly.GetCallingAssembly();
    string configPath = new Uri(currentAssembly.CodeBase).LocalPath;
    return ConfigurationManager.OpenExeConfiguration(configPath);
}

To copy file after build you might want to add the following line to post-build events for asp app (pulling the config from library):

copy "$(SolutionDir)<YourLibProjectName>\$(OutDir)$(Configuration)\<YourLibProjectName>.dll.config" "$(ProjectDir)$(OutDir)"



回答2:


As far as I know, you need separate application domains for the app.config to work separately. The creation of an AppDomainSetup allows you to specify which config file to use. Here's how I do it:

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);
}

Another way you could go about getting the desired effect would be to implement your configuration values inside a resource file compiled into each of your DLLs. A simple interface over the configuration object would allow you to switch out looking in an app.config versus looking in a resource file.




回答3:


It may work if you change the code little bit:

public string Name
{
    get { 
        Configuration conf = ConfigurationManager.OpenExeConfiguration("library.dll");
        return conf.AppSettings.Settings["House"].Value; 
    }
}


来源:https://stackoverflow.com/questions/11993546/app-config-for-dynamically-loaded-assemblies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!