Разрешение сборок, нечеткий путь - PullRequest
11 голосов
/ 28 апреля 2010

Вот настройки:

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

Assembly asm = Assembly.Load(COFF_Image);

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

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

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

Ответы [ 3 ]

7 голосов
/ 28 апреля 2010

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

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

1 голос
/ 28 апреля 2010

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

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