2017-02-28 100 views
2

我有一个依赖于库的可执行文件。我还有一个“加载器”应用程序,它将可执行文件加载到单独的AppDomain(我的“沙箱”)中并在那里运行它。该库需要从沙箱外进行初始化,所以我需要在加载可执行文件之前加载库。这按预期工作,但是当我现在加载可执行文件时,该库会再次加载,并且可执行文件使用未初始化的副本。.net自动程序集解析加载重复程序集

Assembly.Load(File.ReadAllBytes(assemblyFile.FullName)); 

,而不是这样的::

Assembly.LoadFrom(assemblyFile.FullName); 

但是,使用LoadFrom锁定该文件

这只有当我加载像这样的库中出现。我需要能够删除/写入文件,因为我的应用程序需要能够重新加载整个沙箱及其中的所有程序集。

我也试过注册AppDomain.AssemblyResolve,但如果它没有找到该文件,这不正是我想要的它只是叫...

示例日志输出:

  • 加载库X < - 手工负载
  • 初始化库X
  • 加载可执行ý
  • 加载库X < - 不好,我想用加载的X!

所以我的问题是:我如何强制.net使用已加载的程序集,而不是加载重复?

+0

是在同一个AppDomain中出现的两个负载? –

+0

@DanField是的,我仔细检查了这 – Whosdatdev

回答

0

我结束了我的修改沙箱的AppDomainSetup:

domainSetup.DisallowApplicationBaseProbing = true; 

现在,AssemblyResolve将被称为每次(无自动发现的组件)。现在,我可以从一个byte []加载组件并缓存(感谢@DanField谁建议缓存组件)

1

remarks on Assembly.Load(Byte[])

注意,此方法重载始终将创建自己的地图新的装配对象。

如果你想重新使用你的加载的程序集(无需额外的工作 - 框架不会自动为你做)。

您也许可以在这里使用Assembly.Load(string)Type.GetType(string)方法,但我怀疑这仍然会锁定要修改的文件。我真的不确定如何在运行时修改这些文件,尽管如此 - 如果删除或更改加载的程序集,预期的行为是什么?重新加载?将修改的代码输入到内存中?

您可能需要创建某种自己的程序集缓存机制。如果程序集不是那么大,并且可以将它们放在内存中,它可能就像Dictionary<string, Assembly>一样简单 - 只需检查字典在加载之前是否有装配,否则使用Assembly.Load(Byte[])以您的方式加载现在。