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

旧城冷巷雨未停 提交于 2019-12-19 19:21:11

问题


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?

Thanks.


回答1:


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




回答2:


@Kent Boogart: That appears to be the correct explanation. For a full explanation, Suzanne Cook has this blog post which elaborates a little more than the original one you posted: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

Following is code leveraging AppDomain.AssemblyResolve -

 // register to listen to all assembly resolving attempts:
 AppDomain currentDomain = AppDomain.CurrentDomain;
 currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);


 // Check whether the desired assembly is already loaded
 private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly assembly in assemblies) {
       AssemblyName assemblyName = assembly.GetName();
       string desiredAssmebly = args.Name;
       if (assemblyName.FullName == desiredAssmebly) {
           return assembly;
       }
    }

    // Failed to find the desired assembly
    return null;
 }


来源:https://stackoverflow.com/questions/416468/weird-behaviour-when-mixing-loading-of-assemblies-using-assembly-loadfrom-and-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!