He escrito un pequeño fragmento de código sobre la carga dinámica de ensamblajes y la creación de instancias de clase a partir de esos ensamblados, incluido un ejecutable, una lib de prueba para cargar dinámicamente y una biblioteca de cargadores para cargar ensamblaje dinámico en un nuevo Appdomain
. Los archivos ejecutables y la biblioteca dinámica hacen referencia a la biblioteca Loader.Efecto de LoaderOptimizationAttribute
//executable
[System.STAThreadAttribute()]
[System.LoaderOptimization(LoaderOptimization.MultiDomain)]
static void Main(string[] args)
{
AppDomainSetup domainSetup = new AppDomainSetup()
{
ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
LoaderOptimization = LoaderOptimization.MultiDomain
};
AppDomain childDomain = AppDomain.CreateDomain("MyDomain", null, domainSetup);
Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString());
Console.WriteLine(childDomain.SetupInformation.LoaderOptimization.ToString());
byte[] assembly = null;
string assemblyName = "CSTestLib";
using (FileStream fs = new FileStream(assemblyName+".dll",FileMode.Open))
{
byte[] byt = new byte[fs.Length];
fs.Read(byt,0,(int)fs.Length);
assembly = byt;
}
object[] pararmeters = {assemblyName,assembly};
string LoaderAssemblyName = typeof(AssemblyLoader).Assembly.FullName;
string LoaderClassName = typeof(AssemblyLoader).FullName;
AssemblyLoader assloader = (AssemblyLoader)childDomain.CreateInstanceAndUnwrap(LoaderAssemblyName,LoaderClassName , true, BindingFlags.CreateInstance, null, parameters, null, null);
object obj = assloader.Load("CSTestLib.Class1");
object obj2 = assloader.Load("CSTestLib.Class2");
AppDomain.Unload(childDomain);
Console.ReadKey();
}
//Dynamic Lib
using System;
namespace CSTestLib
{
public class Class1 :MarshalByRefObject
{
public Class1() { }
}
public class Class2 : MarshalByRefObject
{
public Class2() { }
}
}
//Loader Library
using System;
namespace LoaderLibrary
{
public class AssemblyLoader : MarshalByRefObject
{
string assemblyName;
public AssemblyLoader(string assName, byte[] ass)
{
assemblyName = assName;
AppDomain.CurrentDomain.Load(ass);
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + " " + AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString());
}
public object Load(string className)
{
object ret = null;
try
{
ret = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyName, className);
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
return ret;
}
}
}
Aquí me puse
LoaderOptimizationAttribute
enmain()
método, peroAppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString();
dice que esNotSpecified
¿Por qué?Las diferencias entre
MultiDomain
yMultiDomainHost
no son tan claras para mí. ¿EsMultiDomainHost
solo para ensambles GAC? Para mi situación, ¿cuál es más adecuada?Según this
código JIT-compilado no puede ser compartido por ensamblados cargados en la carga de contexto, utilizando el método LoadFrom de la clase de ensamblado, o carga desde imágenes utilizando sobrecargas del método Load que especifica arrays de bytes.
Entonces, ¿cómo puedo detectar si un ensamblado se carga de dominio neutral o no? ¿Cómo puedo asegurar que esté cargado de dominio neutral?
Me parece que el atributo realmente tiene un efecto. Ejecutar con depurador adjunto devuelve 'NotSpecified' ... ejecutando sin depurador devuelve' MultiDomain' ... Tal vez alguien puede confirmar eso. – Matthias