当"DisallowApplicationBaseProbing=true"时,需要挂钩"AssemblyResolve"事件。

4

当我将DisallowApplicationBaseProbing = true设置为true时,我需要在创建的AppDomain上挂接AssemblyResolve事件。我这样做的原因是为了强制运行时调用它需要解析程序集的AssemblyResolve事件,而不是首先探测。这样,另一个开发人员就不能只把MyDllName.dll放在ApplicationBase目录中并覆盖我想要加载的程序集。

这样做的问题如下...

  class Program
  {
 static void Main()
 {
    AppDomainSetup ads = new AppDomainSetup();
    ads.DisallowApplicationBaseProbing = true;
    AppDomain appDomain = AppDomain.CreateDomain("SomeDomain", null, ads);
    appDomain.AssemblyResolve += OnAssemblyResolve;
    appDomain.DoCallBack(target);
 }

 static System.Reflection.Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
 {
    Console.WriteLine("Hello");
    return null;

 }

 private static void target()
 {
    Console.WriteLine(AppDomain.CurrentDomain);
 }
  }

代码从+= OnAssemblyResolve这一行就无法继续执行。
当代码尝试执行时,新的应用程序域会尝试解析我正在执行的程序集。由于DisallowApplicationBaseProbing = true,它不知道在哪里找到这个程序集。我好像遇到了鸡生蛋或蛋生鸡的问题。它需要解析我的程序集才能挂钩程序集解析器,但是需要程序集解析器来解析我的程序集。
感谢您所有的帮助。
-迈克

你看到了 Console.WriteLine("Hello"); 的输出吗?如果是的话,也许你应该实现一个能够解析程序集的逻辑。我遇到了这个问题,因为我有相同的困扰。如果我找到了解决方案,我会发布一个答案。 - No answer
1个回答

6

经过许多实验,我得到了以下的工作方案:

internal class AssemblyResolver : MarshalByRefObject
{
  static internal void Register(AppDomain domain)
  {
    AssemblyResolver resolver =
        domain.CreateInstanceFromAndUnwrap(
          Assembly.GetExecutingAssembly().Location,
          typeof(AssemblyResolver).FullName) as AssemblyResolver;

    resolver.RegisterDomain(domain);
  }

  private void RegisterDomain(AppDomain domain)
  {
    domain.AssemblyResolve += ResolveAssembly;
    domain.AssemblyLoad += LoadAssembly;
  }

  private Assembly ResolveAssembly(object sender, ResolveEventArgs args)
  {
    // implement assembly resolving here
    return null;
  }

  private void LoadAssembly(object sender, AssemblyLoadEventArgs args)
  {
    // implement assembly loading here
  }
}

域名的创建方式如下所示:
    AppDomainSetup setupInfo = AppDomain.CurrentDomain.SetupInformation;
    setupInfo.DisallowApplicationBaseProbing = true;

    domain = AppDomain.CreateDomain("Domain name. ", null, setupInfo);
    AssemblyResolver.Register(domain);

抱歉,我不能分享解决和加载程序集的代码。首先,它还没有工作。其次,在这种情况下与一般公众分享太过具体。

我将引导一个对象结构,该结构与所需的程序集一起序列化到单个文件中,以供反序列化使用。为此,我真的应该直接进入.dll地狱。


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