Устранение сборок, нечеткий способ

Здесь настройка:

Чистая библиотека классов DotNET загружается неуправляемым настольным приложением. Библиотека классов действует как плагин. Этот плагин загружает небольшие собственные плагины для ребенка (все библиотеки классов DotNET), и он делает это, читая dll в память в виде байтового потока, затем

Assembly asm = Assembly.Load(COFF_Image);

Проблема возникает, когда у этих маленьких плагинов есть ссылки на другие DLL. Поскольку они загружаются через память, а не непосредственно с диска, структура часто не может найти эти ссылочные сборки и, следовательно, неспособна загрузить их.

Я могу добавить обработчик AssemblyResolver в свой проект, и я вижу, что эти ссылочные сборки выпадают. У меня есть достаточно хорошая идея о том, где найти эти ссылочные сборки на диске, но как я могу убедиться, что Assmebly я load является правильным?

Короче говоря, как я могу надежно перейти из поля System.ResolveEventArgs.Name в путь к файлу dll, предположив, что у меня есть список всех папок, где эта dll могла скрываться)?

Ответ 1

Когда я использовал это в прошлом, мы просто сравнили имя файла с частью 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;
    }

Ответ 2

Managed Extensibility Framework (MEF) звучит как что-то, что решит все ваши проблемы. Он может сканировать папки для поиска DLL, разрешать зависимости для любой глубины и управлять композицией плагина в целом. Каждая часть (или "плагин" ) должна просто заявить, что ей нужно и что она предоставляет, и MEF заботится о проводке. Если MEF удалось укротить VS2010, то он сможет обрабатывать все.

Ответ 3

Мне никогда не повезло с AssemblyResolver. Обычно я делаю одно из этих трех:

  • Требовать, чтобы плагины не имели внешних ссылок, которые не находятся в GAC. Если они сука, скажите им ILMerge.
  • Требовать, чтобы плагины сбрасывали все свои DLL в известный каталог плагинов. Загрузите все сборки в этот каталог в память.
  • Требовать наличия зависимостей плагина в пути, который исследуется слиянием. Вы можете выяснить, где связующее ищет сборки, включите журнал слияния (fuslogvw.exe - не забывайте перезагружаться после включения регистрации!).