Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behaviour when mixing loading of assemblies using Assembly.LoadFrom and Assembly.Load

Weird behavior when mixing loading of assemblies using Assembly.LoadFrom and Assembly.Load:

I have encountered a weird behavior when loading assemblies with Assembly.LoadFrom and later on with Assembly.Load. I am loading an assembly using Assembly.LoadFrom, where the assembly is located in a folder, which is not the execution folder.

Later on in my test code when I try to load once again this assembly with Assembly.Load, the load fails with a System.IO.FileNotFoundException (“Could not load file or assembly…”) despite the fact that the assembly is already loaded. The load fails both with the strong name and the non-strong name (the original reason for loading once again this assembly is a usage of a BinaryFormatter).

However, in case the assembly is located in the execution folder the later load succeeds in both cases, with the strong name and the non-strong name. In this case, you can see that two identical assemblies are loaded from two different locations.

A simple code sample that recreates this problem:

Assembly assembly1 = Assembly.LoadFrom(@"C:\a.dll");

// Loading with a strong-name fails
Assembly assembly2 = Assembly.Load(@"a, Version=1.0.0.0, Culture=neutral, PublicKeyToken=14986c3f172d1c2c");

// Also loading with a non-strong fails
Assembly assembly3 = Assembly.Load(@"a");
  1. Any explanation why the CLR ignores the already loaded assembly?
  2. Any idea how can I alleviate this problem?
like image 907
Hershi Avatar asked Jan 06 '09 13:01

Hershi


People also ask

How does assembly load work?

At runtime, when you use a type from a referenced project for the first time, the CLR looks in the application directory for the DLL file with the same name and version it expects. It then loads that assembly into the process. This is also called binding to the assembly.

Which of the following methods from the assembly class can be used to load an assembly from a byte array?

To load an assembly from a byte array with the trust level of the application domain, use the Load(Byte[], Byte[], SecurityContextSource) method overload.

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.

Is assembly loaded C#?

The referenced assemblies are in the dependency list and they are loadable, but they are not immediately loaded by the application. In other words the C# compiler and .


1 Answers

That's not weird. As per the documentation, loading with Load and LoadFrom will place the assemblies in different contexts. This might help.

  1. Any explanation why the CLR ignores the already loaded assembly?

Because they're in a different context.

  1. Any idea how can I alleviate this problem?

Load from the same context, or help the CLR find the assembly, perhaps by attaching a handler to AppDomain.AssemblyResolve.

Alternative

If the location you are loading assemblies from is a subfolder under AppDomain.BaseDirectory you can simply add an entry to your App.config:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

like image 170
Kent Boogaart Avatar answered Sep 27 '22 17:09

Kent Boogaart