.NET自动程序集解析加载重复程序集

4
我有一个依赖库的可执行文件。我还有一个“加载器”应用程序,它将可执行文件加载到单独的AppDomain(我的“沙盒”)中并在那里运行。该库需要从沙盒外部进行初始化,因此我需要在加载可执行文件之前加载该库。这正常工作,但是当我现在加载可执行文件时,库会再次加载,并且可执行文件使用未初始化的副本。
只有在我像这样加载库时才会发生这种情况:
 Assembly.Load(File.ReadAllBytes(assemblyFile.FullName));

改为:

Assembly.LoadFrom(assemblyFile.FullName);

然而,使用LoadFrom会锁定文件。我需要能够删除/写入该文件,因为我的应用程序需要重新加载整个沙箱及其中的所有程序集。
我还尝试注册AppDomain.AssemblyResolve,但只有在找不到文件时才会调用它,这并不是我想要的...
示例日志输出:
- 加载库X <-手动加载 - 初始化库X - 加载可执行文件Y - 加载库X <-糟糕,我想使用已加载的X!
所以我的问题是:如何强制.NET使用已加载的程序集而不是加载重复的程序集?

这两个加载是否发生在同一个 AppDomain 中? - Dan Field
@DanField 是的,我已经做了双重检查。 - Whosdatdev
2个回答

3
我最终修改了沙盒的AppDomainSetup:
domainSetup.DisallowApplicationBaseProbing = true;

现在,每次调用AssemblyResolve(没有自动发现程序集)。现在我可以从byte []中加载程序集并将它们缓存起来(感谢@DanField建议缓存程序集)。

3
Assembly.Load(Byte[])的说明可以看出,这个方法始终会创建一个新的程序集对象,并进行自己的映射。如果你想重复使用已经加载过的程序集,就不能使用该重载方法(无论如何都需要额外的工作,框架不会在这里自动完成)。您可以尝试使用Assembly.Load(string) 或者 Type.GetType(string) 方法,但是我怀疑这些方法仍然会锁定您想要修改的文件。说实话,我并不确定如何在运行时修改这些文件 - 如果删除或更改已加载的程序集,预期的行为是什么?重新加载它?将修改后的代码输入到内存中?您可能需要创建一种自己的程序集缓存机制。如果这些程序集不是很大,而且您能够承受将它们存储在内存中,那么可能只需要一个Dictionary<string, Assembly>即可轻松实现 - 只需检查字典是否有您的程序集,如果没有,则使用您现在正在使用的Assembly.Load(Byte[])来加载程序集。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接