为什么在尝试Assembly.ReflectionOnlyLoad时没有执行ReflectionOnlyAssemblyResolve?

问题描述 投票:8回答:3

我正在尝试通过挂钩进入AppDomain.AssemblyResolveAppDomain.ReflectionOnlyAssemblyResolve事件加载一些模块。虽然我让前者工作,但我对后者失败了。我把问题归结为这个小程序:

public static class AssemblyLoader
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += 
            ReflectionOnlyAssemblyResolve;

        // fails with FileNotFoundException
        Assembly.ReflectionOnlyLoad("Foo");
    }

    public static Assembly ReflectionOnlyAssemblyResolve(object sender, 
        ResolveEventArgs args)
    {
        Trace.TraceInformation(
            "Failed resolving Assembly {0} for reflection", args.Name);

        return null;
    }
}

在尝试使用FileNotFoundException时,运行此程序会失败并使用Assembly.ReflectionOnlyLoad,但它不会调用ReflectionOnlyAssemblyResolve处理程序。我很难过。

有没有人知道这可能是什么原因以及如何让它发挥作用?

谢谢!

c# .net assemblies clr assembly.reflectiononly
3个回答
8
投票

看起来ReflectionOnlyAssemblyResolve事件仅用于解析依赖关系,而不是顶级程序集,如下所示:

http://codeidol.com/csharp/net-framework/Assemblies,-Loading,-and-Deployment/Assembly-Loading/

和这里:

http://blogs.msdn.com/junfeng/archive/2004/08/24/219691.aspx


0
投票

扩展了casperOne的答案。

如果要拦截直接的Assembly Resolve事件,则需要挂钩到AppDomain.AssemblyResolve事件。这是一个全球性的钩子,但它不适合你的场景。但是,如果您的应用程序是单线程的,则可以进行短期连接以拦截特定的解析事件。

static void LoadWithIntercept(string assemblyName) {
  var domain = AppDomain.CurrentDomain;
  domain.AssemblyResolve += MyInterceptMethod;
  try {
    Assembly.ReflectionOnlyLoad(assemblyName);
  } finally {
    domain.AssemblyResolve -= MyInterceptMethod;
  }
}

private static Assembly MyInterceptMethod(object sender, ResolveEventArgs e) {
 // do custom code here 
}

0
投票

您可以通过调用程序集上的ExportedTypes来强制它,如下所示:

var dummy = asm.ExportedTypes;

因此,如果要以递归方式加载包含其所有引用的程序集:

 private void _forceAssemblyResolve(Assembly asm) { var dummy = asm.ExportedTypes; }

 var result= Assembly.ReflectionOnlyLoad("Foo");
 _forceAssemblyResolve(result);

public static Assembly ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
    var childAssembly = _resolve(args);
    _forceAssemblyResolve(childAssembly);
}
© www.soinside.com 2019 - 2024. All rights reserved.