Почему ReflectionOnlyAssemblyResolve не выполняется при попытке Assembly.ReflectionOnlyLoad? - PullRequest
8 голосов
/ 20 февраля 2009

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

8 голосов
/ 20 февраля 2009

Может показаться, что событие 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 голосов
/ 07 сентября 2018

Вы можете принудительно вызвать его, вызвав 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);
}
0 голосов
/ 20 февраля 2009

Расширение ответа 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 
}
...