【问题标题】:Load assemblies with dependencies in a different AppDomain在不同的 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

感谢您对此的任何帮助。

【问题讨论】:

    标签: c# clr appdomain appdomainsetup


    【解决方案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的基本路径将是上面示例中的根文件夹。
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 2011-02-12
    相关资源
    最近更新 更多