I've been researching this for a few days now. I'm trying to properly create an instance of a class within an external assembly under it's own AppDomain.
I've been able to load the external assembly under the new AppDomain, however all of its dependencies appear to load in the parent AppDomain which defeats the purpose, as I want to unload the dll's later to release the lock on them (plugin system). Any idea as to why it would be doing this?
public MyCustomObject BindAssembly()
{
string currentAssemblyPath = @"C:\PathToMy\Assembly";
string currentAssemblyFile = @"C:\PathToMy\Assembly\MyAssembly.dll";
AssemblyName currentAssemblyName = AssemblyName.GetAssemblyName(currentAssemblyFile);
AppDomain domain = AppDomain.CurrentDomain;
domain.AssemblyResolve += domain_AssemblyResolve;
AppDomainSetup setup = new AppDomainSetup()
{
PrivateBinPath = currentAssemblyPath,
ApplicationBase = domain.BaseDirectory,
DynamicBase = domain.SetupInformation.DynamicBase,
ShadowCopyFiles = domain.SetupInformation.ShadowCopyFiles,
CachePath = domain.SetupInformation.CachePath,
AppDomainManagerAssembly = domain.SetupInformation.AppDomainManagerAssembly,
AppDomainManagerType = domain.SetupInformation.AppDomainManagerType
};
AppDomain newDomain = AppDomain.CreateDomain("NewDomain", AppDomain.CurrentDomain.Evidence, setup);
newDomain.AssemblyResolve += newDomain_AssemblyResolve;
currentAssembly = newDomain.Load(currentAssemblyName);
// tried this too
//var obj = domain.CreateInstanceFromAndUnwrap(currentAssemblyFile, className);
// list all of the assemblies inside the custom app domain
var newDomainAssemblies = newDomain.GetAssemblies(); // (contains my loaded assembly, but not dependencies)
// list all of the assemblies inside the parent app domain
var appAssemblies = AppDomain.CurrentDomain.GetAssemblies(); // (contains my loaded assembly as well as all dependencies)
return obj as MyCustomObject;
}
// resolve dependencies in custom domain
Assembly newDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// this never fires
AppDomain domain = (AppDomain)sender;
}
// resolve dependencies in parent domain
Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AppDomain domain = (AppDomain)sender;
string assemblyDependencyPath = String.Format(@"{0}", Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(args.RequestingAssembly.CodeBase).Path)));
string[] files = Directory.GetFiles(assemblyDependencyPath, "*.dll", SearchOption.AllDirectories);
foreach (string file in files)
{
// if we found it, load the assembly and cache it.
AssemblyName aname = AssemblyName.GetAssemblyName(file);
if (aname.FullName.Equals(args.Name))
{
Assembly assembly = domain.Load(aname);
//Assembly assembly = Assembly.LoadFrom(file); // also tried this, same result
return assembly;
}
}
}