I need to create new AppDomain and pass executing assembly to it, without any access to the assembly file itself. I have tried to use a binary serializer to transfer the loaded assembly, but it can't be done with the assembly existing only in memory.
The problem is that new AppDomain throws assembly load exception because there is no such a file in current directory.
Update: Even if I found a way to get the actual assembly byte array, saved it to disk and forced it to be loaded into new AppDomain - there is a casting error - I can't cast it from proxy type to actual class or interface.
Example project: https://drive.google.com/open?id=16z9nr8W5D8HjkBABgOCe5MIZKJSpFOul
Update 2:
The example below is working when executed from assembly on the hard drive - there is no need to search the assembly file, and assembly FullName
is enough in CreateInstanceFromAndUnwrap
method. All errors occur when the assembly containing this code is loaded from byte array.
Usage:
public sealed class LoadDomain: IDisposable
{
private AppDomain _domain;
private IFacade _value;
public IFacade Value
{
get
{
return _value;
}
}
public void Dispose()
{
if (_domain != null)
{
AppDomain.Unload(_domain);
_domain = null;
}
}
public void Load(byte[] assemblyBytes,string assemblyPath,string assemmblyDir)
{
var domainSetup = new AppDomainSetup()
{
ShadowCopyDirectories = "true",
ShadowCopyFiles = "true",
ApplicationName = Assembly.GetExecutingAssembly().ManifestModule.ScopeName,
DynamicBase = assemmblyDir,
LoaderOptimization = LoaderOptimization.MultiDomainHost,
};
_domain = AppDomain.CreateDomain("Isolated:" + Guid.NewGuid(), null, domainSetup);
// _domain.Load(assemblyBytes); not working
// _domain.AssemblyResolve+=.. not working
Type type = typeof(Facade);
_value = (IFacade)_domain.CreateInstanceFromAndUnwrap(assemblyPath, type.FullName);
//assemlby path working, but casting error : InvalidCastException
//assembly FullName not working: FileNotFoundException
}
}
public class Facade : MarshalByRefObject, IFacade
{
public void DoSomething()
{
MessageBox.Show("new domain");
}
}