我的可执行文件取决于库。我还有一个"加载程序"应用程序,该应用程序将可执行文件加载到单独的AppDomain(我的" Sandbox")中并在此处运行。库需要从沙箱外部初始化,因此我需要在加载可执行文件之前加载库。这是按预期工作的,但是当我现在加载可执行文件时,库会加载另一个时间,并且可执行文件使用非初始化的副本。
这仅在我加载这样的库时才会发生:
Assembly.Load(File.ReadAllBytes(assemblyFile.FullName));
而不是这样:
Assembly.LoadFrom(assemblyFile.FullName);
但是,使用loadfrom锁定文件。我需要能够删除/编写文件,因为我的应用程序需要能够重新加载整个沙盒和所有组件。
我还尝试了注册appdomain.semblyresolve,但是只有在没有找到该文件时才调用,这不是我想要的...
示例日志输出:
- 加载库x< - 手动负载
- 初始化库x
- 加载可执行的y
- 加载库x< - 不好,我想使用已加载的x!
所以我的问题是:如何强制.NET使用已加载的组件而不是加载重复?
来自 Assembly.Load(Byte[])
上的备注:
请注意,此方法过载总是用自己的映射创建一个新的汇编对象。
如果要重复使用已加载的程序集(无论如何都没有额外的工作 - 框架不会在此处自动为您做)。
您可能可以在此处使用Assembly.Load(string)
或仅使用Type.GetType(string)
方法,但是我怀疑这仍将最终锁定要修改的文件。我不确定如何在运行时修改这些文件以说实话 - 如果您删除或更改已加载的组件,那么预期的行为是什么?重新加载?修改后的代码是否已输入内存?
您可能需要创建自己的某种装配机制。如果组件不那么大,您有能力将它们保存在内存中,那么它可能像Dictionary<string, Assembly>
一样简单 - 只需检查字典在加载之前是否具有您的汇编,否则使用 Assembly.Load(Byte[])
加载它的方式现在。
我最终修改了我的appdomainsetup:
domainSetup.DisallowApplicationBaseProbing = true;
现在,每次都会调用汇编储层(无需自动发现组件)。现在,我可以从字节[]加载组件并缓存它们(感谢@danfield建议的缓存程序集)