Voy a escribir un pequeño artículo sobre algo que me ha hecho falta ya un par de veces, que es especificar por código el fichero de configuración que quiero que use un componente, que ¿por qué me ha hecho falta?, bueno la situación es un assembly de .NET que tenemos instalado en COM+ (si, aún hay cosas en COM+ y ASP por aquí) , y que hace una llamada a otro componente (de otra persona) que necesita extraer unos valores del fichero de configuración, y los assemblies que están registrados en COM+, no tienen fichero de configuración, bueno si lo tienen, se llama dllhost.exe.config, y está en el directorio Win32 si no recuerdo mal, y claro, poner ese fichero de configuración es poco elegante, así que investigando un poco, vi el modo de especificar por código el fichero .config que queremos usar, no es que sea lo más elegante, puesto que hay que crear un nuevo AppDomain, y en aplicaciones medianamente críticas, habría que ver las implicaciones a nivel de rendimiento y GC, pero para mi caso (aplicación pequeña, que casi no se usa, y que quiero migrar a .NET) para salir del paso me vale.
Al tema, la cosa en cuestión, como ya he comentado más arriba, es que el fichero de configuración usado por una aplicación no se puede cambiar en tiempo de ejecución, ya que es una propiedad del AppDomain actual, y durante la ejecución no está permitido cambiarlo, ¿solución?, bueno lo que yo he hecho es creo un nuevo AppDomain, esto lo hago en el método desde el cual creo la instancia a la clase que necesita leer los valores de configuración, copio las propiedades más importantes del AppDomain actual, excepto la que especifica el fichero de configuración, que se la cambio y le digo el path completo al fichero que quiero utilizar, , y con este nuevo AppDomain, creo la instancia a la clase que necesita leer los valores de configuración, pero lo más fácil es verlo en el código:
AppDomainSetup domainInfo = new
AppDomainSetup();
domainInfo.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
domainInfo.ConfigurationFile = @"C:\Users\lfraile\Documents\Visual Studio 2005\Projects\UsoFicheroConfig\UsoFicheroConfig\app1.config";
Evidence currentEvidence = AppDomain.CurrentDomain.Evidence;
AppDomain nuevoDomain = AppDomain.CreateDomain("NuevoDominio", currentEvidence, domainInfo);
Class1 clase1 = (Class1)nuevoDomain.CreateInstanceAndUnwrap(System.Reflection.Assembly.GetAssembly(typeof(Class1)).FullName, DemoFicheroConfig.Class1");
OJO: la clase que vayamos a instanciar, en este caso "Class1", ha de heredar de MarshalByRefObject, como podéis ver este sistema funciona exactamente igual que la activación de objetos de remoting, como ya os digo esto no es lo más elegante y hay que usarlo con mucha cautela, pero para ciertos apaños puede venir bien.