Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto load assemby at runtime before AssemblyResolve event?

Actually i tried to implement some kind of 'statically linked' assemblies, within my solution. So i tried the following:

  • Adding a reference to my assembly with CopyLocal = false
  • Adding the .dll file itself to my solution with 'Add as link'
  • Adding the .dll file itself to my resources with 'Add Resource' - 'Add Existing File'
  • Adding some type out of my assembly into Form1 as private MyObject temp = new MyObject();

After these steps i got the FileNotFoundException as expected. So let's try to load the assembly within the AssemblyResolveEvent with this quick hack

AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
    {
        Assembly MyAssembly = AppDomain.CurrentDomain.Load(Properties.Resources.ExternalAssembly);
        return MyAssembly;
    };

So this works! I'm able to load my assembly from a resource file within a AssemblyResolveEvent. But this event only happens, if it couldn't find my assembly anywhere else. But how can i get my assembly be loaded before .Net tries to search the different places??

Due to the facts from Checking for Previously Referenced Assemblies i thought it would be possible to load the assembly beforehand into the domain and this would be taken.

I tried this within program.cs by using the following Main() method

static void Main()
{
    LoadMyAssemblies();
    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => LoadMyAssemblies();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

private static Assembly LoadMyAssemblies()
{
    Assembly result = AppDomain.CurrentDomain.Load(Properties.Resources.MyStaticAssembly);
    return result;
}

But it still runs into the ResolveEventHandler. And far more better, if i load the assembly again and take a look into AppDomain.CurrentDomain.GetAssemblies() i can see that my assembly is loaded twice!!

So any idea why my loaded assembly won't be taken into account when it is loaded before the AssemblyResolve event?? With help of the debugger i also returned a null when the call came from AssemblyResolve, but in this case i got a FileNotFoundException as at the beginning.

like image 543
Oliver Avatar asked Jul 21 '09 13:07

Oliver


People also ask

When assembly will load on AppDomain?

If an assembly is loaded into the same AppDomain, then the class can be instantiated in the usual way. But if an assembly is loaded into a different AppDomain then it can be instantiated using reflection. Another way is an interface.

Which event allows you to intervene and manually load an assembly that the CLR Cannot find?

AssemblyResolve Event (System)

What is the method to load assembly given its file name and its path?

LoadFrom(String) Loads an assembly given its file name or path.


1 Answers

Just in case you didn't know, there is a tool called ILMerge from MS Research that merges assemblies into one file.

Also you can create Multi-file assemblies using the Assembly Linker tool.

Plus to answer you original question, the problem I think is that the runtime does not know that the assembly you loaded manually is the one it should be looking for. So in the assembly resolve event instead of loading the assembly again, just pass back the reference to the assembly that you've manually loaded.

like image 154
Sijin Avatar answered Oct 02 '22 13:10

Sijin