I apologize in advance if the title doesn't make sense. I'm very new to appdomains and assembly loading and don't really know how to state what I'm trying to ask.
I have been fiddling around with loading embedded DLLs into an application during runtime and I can't seem to figure out why it works one way but not the other. It seems like if you try to load DLLs (from a byte array) into the current appdomain, any objects/threads created after that will be able to resolve references against the newly loaded library, however objects in the original context will not resolve against the newly loaded library.
Here is my example library that will be loaded from as an embedded resource during runtime (requires a reference to the WPF PresentationFramework.dll for MessageBox):
namespace LoaderLibrary
{
public class LoaderLibrary
{
public static void Test()
{
System.Windows.MessageBox.Show("success");
}
}
}
In my console app .csproj file I manually add the following embedded resource for that project and include a project reference to LoaderLibrary as well:
<ItemGroup>
<EmbeddedResource Include="..\LoaderLibrary\bin\$(Configuration)\LoaderLibrary.dll">
<LogicalName>EmbeddedResource.LoaderLibrary.dll</LogicalName>
</EmbeddedResource>
</ItemGroup>
Here is the code for my console app that loads that library (requires a project reference to the LoaderLibrary csproj) ALSO: Need to set CopyLocal to false for LoaderLibrary reference:
namespace AssemblyLoaderTest
{
class Program
{
static void Main(string[] args)
{
EmbeddedAssembly.Load("EmbeddedResource.LoaderLibrary.dll");
System.AppDomain.CurrentDomain.AssemblyResolve += (s, a) => { return EmbeddedAssembly.Get(a.Name); };
var app = new TestApp();
}
}
public class TestApp
{
public TestApp()
{
LoaderLibrary.LoaderLibrary.Test();
}
}
public class EmbeddedAssembly
{
static System.Collections.Generic.Dictionary<string, System.Reflection.Assembly> assemblies = new System.Collections.Generic.Dictionary<string, System.Reflection.Assembly>();
public static void Load(string embeddedResource)
{
using (System.IO.Stream stm = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedResource))
using (var mstream = new System.IO.MemoryStream())
{
stm.CopyTo(mstream);
var assembly = System.Reflection.Assembly.Load(mstream.ToArray());
assemblies.Add(assembly.FullName, assembly);
return;
}
}
public static System.Reflection.Assembly Get(string assemblyFullName)
{
return (assemblies.Count == 0 || !assemblies.ContainsKey(assemblyFullName)) ? null : assemblies[assemblyFullName];
}
}
}
This code is able to successfully load and execute the LoaderLibrary.LoaderLibrary.Test() function.
My question is why does the following not work?
static void Main(string[] args)
{
EmbeddedAssembly.Load("EmbeddedResource.LoaderLibrary.dll");
System.AppDomain.CurrentDomain.AssemblyResolve += (s, a) => { return EmbeddedAssembly.Get(a.Name); };
LoaderLibrary.LoaderLibrary.Test(); // very unhappy line of code
}
This also doesn't work:
static void Main(string[] args)
{
EmbeddedAssembly.Load("EmbeddedResource.LoaderLibrary.dll");
System.AppDomain.CurrentDomain.AssemblyResolve += (s, a) => { return EmbeddedAssembly.Get(a.Name); };
var app = new TestApp();
LoaderLibrary.LoaderLibrary.Test(); // very unhappy line of code
}