Почему ReflectionOnlyAssemblyResolve не выполняется при попытке сборки.ReflectionOnlyLoad?

Я пытаюсь загрузить несколько модулей через подключение в AppDomain.AssemblyResolve и AppDomain.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. Я довольно тупик там.

у кого-нибудь есть идеи что может быть причиной этого и как это сделать работа?

спасибо!

3 ответов


похоже, что событие ReflectionOnlyAssemblyResolve используется только для разрешения зависимостей, а не сборок верхнего уровня, как указано здесь:

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

и здесь:

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


расширение на ответ casperOne по.

Если вы хотите перехватить события разрешения прямой сборки, вам нужно подключиться к 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 
}

вы можете заставить его, вызвав ExportedTypes в сборке следующим образом:

var dummy = asm.ExportedTypes;

поэтому, если вы хотите загрузить сборку со всеми ее referecnes рекурсивно:

 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);
}