Sto provando a caricare i moduli nella mia applicazione in modo dinamico, ma voglio specificare file app.config separati per ognuno.
Supponiamo che abbia le seguenti impostazioni app.config per l’app principale:
E un altro per la libreria che carico utilizzando Assembly.LoadFrom
:
Entrambe le librerie hanno una class che implementa la stessa interfaccia, con il seguente metodo:
public string Name { get { return ConfigurationManager.AppSettings["House"]; } }
E sicure chiamate al Name
sia dalla class principale che dall’output della class di assemblaggio caricato Stark
.
C’è un modo per fare in modo che l’app principale usi il proprio app.config e ogni assembly caricato ne usi? I nomi dei file di configurazione sono diversi nell’output, quindi dovrebbe essere ansible.
Ok, ecco la soluzione semplice che ho trovato: Crea la funzione follow nella libreria delle utility:
public static Configuration LoadConfig() { Assembly currentAssembly = Assembly.GetCallingAssembly(); return ConfigurationManager.OpenExeConfiguration(currentAssembly.Location); }
Usandolo in librerie caricate dynamicmente come questo:
private static readonly Configuration Config = ConfigHelpers.LoadConfig();
Indipendentemente dal modo in cui la libreria viene caricata, utilizza il file di configurazione corretto.
Modifica: questa potrebbe essere la soluzione migliore per caricare i file nelle applicazioni ASP.NET:
public static Configuration LoadConfig() { Assembly currentAssembly = Assembly.GetCallingAssembly(); string configPath = new Uri(currentAssembly.CodeBase).LocalPath; return ConfigurationManager.OpenExeConfiguration(configPath); }
Per copiare il file dopo la generazione, potresti voler aggiungere la seguente riga agli eventi post-build per l’app asp (estraendo la configurazione dalla libreria):
copy "$(SolutionDir)\$(OutDir)$(Configuration)\ .dll.config" "$(ProjectDir)$(OutDir)"
Per quanto ne so, sono necessari domini applicativi separati affinché app.config funzioni separatamente. La creazione di un AppDomainSetup consente di specificare quale file di configurazione utilizzare. Ecco come lo faccio:
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); }
Un altro modo per ottenere l’effetto desiderato consiste nell’implementare i valori di configurazione all’interno di un file di risorse compilato in ciascuna DLL. Una semplice interfaccia sull’object di configurazione ti consentirebbe di passare alla ricerca in un app.config rispetto a cercare in un file di risorse.
Potrebbe funzionare se cambi leggermente il codice:
public string Name { get { Configuration conf = ConfigurationManager.OpenExeConfiguration("library.dll"); return conf.AppSettings.Settings["House"].Value; } }