Работа с событием AppDomain.AssemblyResolve
Я пытаюсь использовать событие AppDomain.AssemblyResolve
для обработки исключений при разрешении сборок некоторых библиотек DLL, загруженных во время выполнения (SerializationException для динамически загружаемого типа).
Когда событие вызывается, я загружаю все библиотеки DLL в своем каталоге и создаю массив Assembly
, затем использую этот метод, чтобы получить Assembly
, содержащий указанный мной тип:
public static Assembly GetAssemblyContainingType(String completeTypeName,
Assembly[] assemblies)
{
Assembly assembly = null;
foreach (Assembly currentassembly in assemblies)
{
Type t = currentassembly.GetType(completeTypeName, false, true);
if (t != null)
{
assembly = currentassembly;
break;
}
}
return assembly;
}
Проблема в том, что этот код работает только с AssemblyQualifiedName
, а ResolveEventArgs.Name
, предоставленный событием, не очень полезен.
Можете ли вы предложить мне какое-то решение?
Есть ли способ передать некоторые другие аргументы событию при его запуске?
Ответы
Ответ 1
Вы можете определить словарь сборок из своего каталога, например:
private readonly IDictionary<string,Assembly> additional =
new Dictionary<string,Assembly>();
Загрузите этот словарь с помощью сборок из вашего известного каталога, например:
foreach ( var assemblyName ... corresponding to DLL names in your directory... ) {
var assembly = Assembly.Load(assemblyName);
additional.Add(assembly.FullName, assembly);
}
Предоставить реализацию для hook...
private Assembly ResolveAssembly(Object sender, ResolveEventArgs e) {
Assembly res;
additional.TryGetValue(e.Name, out res);
return res;
}
... и подключите его к событию:
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveAssembly;
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
Это должно сделать трюк.
Ответ 2
Если вы знаете список сборок, которые могут содержать тип, который вы планируете десериализовать, лучше просто предварительно загрузить все сборки, прежде чем выполнять сериализацию.
При запуске события AssemblyResolve у вас нет информации о том, какой тип вызвал загрузку, но только имя сборки. Непонятно, почему в этом случае вы должны искать сборку по определенному типу.
Обратите внимание, что если 2 сборки имеют одинаковый идентификатор (то есть имя файла в случае не строго подписанного), а одно уже загруженное событие не срабатывает, если вы ожидаете, даже если тип не найден в уже загруженной сборке.
Ссылка на статью для исторических целей: Разрешение сборок сборки.