在不同的 AppDomain 中加载具有依赖项的程序集
Posted
技术标签:
【中文标题】在不同的 AppDomain 中加载具有依赖项的程序集【英文标题】:Load assemblies with dependencies in a different AppDomain 【发布时间】:2012-08-16 14:52:31 【问题描述】:我的目标是在 2 个给定文件夹之间进行缺失的依赖检查。 想象一下以下设置。
Root\DirA\A.dll
Root\DirB\B.dll
B 依赖于 A。
因此,鉴于这些文件夹,我想创建一个新的 AppDomain,加载 B.dll 并在新的 AppDomain 中自动解析和隔离来自 DirA(A.dll) 的依赖项。
这里的隔离是关键,因为当我卸载这个 AppDomain 时,我想创建一个新的 AppDomain,可能会再次将 DirA 作为依赖项,但 DirC 库需要它,因此如果 DirC 也依赖 DirB,我想要它抛出异常。
编辑:添加代码示例以帮助更好地描述我的问题。
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = @"C:\Root";
setup.ApplicationName = "Isolated Domain"
setup.PrivateBinPath = @"DirA;DirB";
setup.PrivateBinPathProbe = "";//disable search in AppBase..
var domain = AppDomain.CreateDomain(Guid.NewGuid().ToString(),
AppDomain.CurrentDomain.Evidence,
setup,
AppDomain.CurrentDomain.PermissionSet);
//The following statement in theory should pick B.dll's dependency from DirA.
var assembly = domain.Load(AssemblyName.GetAssemblyName(@"C:\Root\DirB\B.dll").Name);
//Do the same in a different domain for C.dll
感谢您对此的任何帮助。
【问题讨论】:
【参考方案1】:这看起来像是ResolveEventHandler 的工作(更多详情请参阅MSDN regarding resolving unknown assemblies)
所以,你可以写类似的东西
class MyResolver
public static Assembly MyResolveEventHandler( Object sender, ResolveEventArgs args )
// confirm args.Name contains A.dll
String dllName = args.Name.Split(',', SplitStringOptions.None)[0];
if (dllName == "A")
return Assembly.LoadFile(@"C:\Root\DirA\A.dll")
return null;
在您创建的域中,您将执行以下操作:
domain.AssemblyResolve += new ResolveEventHandler(MyResolver.MyResolveEventHandler);
确保在 B 中引用 A 之前绑定事件。
【讨论】:
是的,我知道该事件,但无法获得使用它来工作的实现:( 谢谢大佬,如果有机会我会告诉你它是否有效。 为未来的搜索者添加评论 - AssemblyResolve 事件必须在 父 AppDomain 上处理,而不是子 AppDomain。当解决程序集发生错误时,子 AppDomain 将在父 AppDomain 上触发事件。 仅适用于其他未来搜索者:我必须将解析处理程序添加到我新创建的域中,而不是父应用程序域中.. ;) 如果设置 setup.DisallowApplicationBaseProbing = true;新创建的域获取 AssemblyResolve 事件,否则父域获取它【参考方案2】:AppDomain 无法探测初始文件夹之外的 dll。他们可以在 GAC 和 PrivateBinPath 中更深入地探测文件夹,但无法探测其他文件夹。
【讨论】:
这个想法是AppDomain的基本路径将是上面示例中的根文件夹。以上是关于在不同的 AppDomain 中加载具有依赖项的程序集的主要内容,如果未能解决你的问题,请参考以下文章
在 Erlang 应用程序中加载依赖项的代码路径的正确方法是啥。
如果在同一个 AppDomain 中加载了多个版本,WPF 无法选择正确的 DLL