Почему ReflectionOnlyAssemblyResolve не выполняется при попытке Assembly.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.
Если вы хотите перехватить прямые события 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
}
Вы можете принудительно вызвать его, вызвав 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);
}