Разрешение сборок, нечеткий путь
Вот настройки:
Чистая библиотека классов DotNET загружается неуправляемым настольным приложением. Библиотека классов действует как плагин. Этот плагин загружает маленькие собственные плагины ребенка (все библиотеки классов DotNET), и делает это, считывая dll в память как поток байтов, а затем
Assembly asm = Assembly.Load(COFF_Image);
Проблема возникает, когда у этих маленьких плагинов есть ссылки на другие библиотеки. Поскольку они загружаются через память, а не напрямую с диска, платформа часто не может найти эти ссылочные сборки и, следовательно, не может их загрузить.
Я могу добавить обработчик AssemblyResolver в свой проект и увидеть, как эти ссылочные сборки пропадают мимо. У меня есть достаточно хорошее представление о том, где найти эти сборки, на которые есть ссылки, на диске, но как я могу убедиться в том, что загружаемая программа Assmebly I является правильной?
Короче говоря, как мне надежно перейти от поля System.ResolveEventArgs.Name к пути к файлу DLL, если предположить, что у меня есть список всех папок, в которых эта DLL может скрываться)?
3 ответа
Когда я использовал это в прошлом, мы только что сравнили имя файла с частью ResolveEventArgs.Name, которая имеет имя. Если вы хотите быть уверены, что загружаете точно такую же версию, я полагаю, вы могли бы проверить, совпадают ли имена, если они есть, затем загрузить сборку, а затем проверить полное имя сборок по ResolveEventArgs.Name.
что-то вроде этого:
string name = GetAssemblyName (args); //gets just the name part of the assembly name
foreach (string searchDirectory in m_searchDirectories)
{
string assemblyPath = Path.Combine (executingAssemblyPath, searchDirectory);
assemblyPath = Path.Combine (assemblyPath, name + ".dll");
if (File.Exists (assemblyPath))
{
Assembly assembly = Assembly.LoadFrom (assemblyPath);
if (assembly.FullName == args.Name)
return assembly;
}
}
для полноты:
private string GetAssemblyName (ResolveEventArgs args)
{
String name;
if (args.Name.IndexOf (",") > -1)
{
name = args.Name.Substring (0, args.Name.IndexOf (","));
}
else
{
name = args.Name;
}
return name;
}
Managed Extensibility Framework (MEF) звучит как то, что решит все ваши проблемы. Он может сканировать папки, чтобы находить библиотеки DLL, разрешать зависимости для любой глубины и управлять композицией плагинов в целом. Каждая часть (или "плагин") просто должна декларировать, что ей нужно и что она предоставляет, а MEF заботится о проводке. Если MEF удалось укротить зверя расширяемости VS2010, то он может справиться с чем угодно.
Мне никогда не везло с AssemblyResolver. Я обычно делаю одно из этих трех:
- Требуемые плагины не имеют внешних ссылок, которых нет в GAC. Если они суки, скажи им ILMerge.
- Требовать плагины, чтобы сбросить все свои библиотеки в известный каталог плагинов. Загрузите все сборки в этом каталоге в память.
- Требовать, чтобы зависимости плагина существовали в пути, который исследуется слиянием. Вы можете выяснить, где механизм связывания ищет сборки, включив журнал Fusion (fuslogvw.exe- не забудьте перезагрузить компьютер после включения регистрации!).