Configurazione dell’app per gli assembly caricati dynamicmente

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