Сборка, встроенная в библиотеку классов, не найдена основным приложением - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть библиотека классов C # .NET, ClassLib, в которой используются Newtonsoft.Json и RestSharp.

Идея библиотеки заключается в том, что это «суперобертка» API, которая включена в сторонние приложения конечных пользователей, например, приложения для настольных компьютеров, веб-приложения, службы Windows и т. Д.

Чтобы сохранить самодостаточность, я встроил Newtonsoft и RestSharp в ClassLib с использованием встроенных ресурсов и подхода AssemblyResolve , который обсуждался в нескольких потоках на SO.

Пока что все банально; Я использовал этот подход несколько раз в разных проектах, таких как плагины, и все в целом работает как положено.

Однако на этот раз я наткнулся на странную загадку. И это противоречиво.

Я использую ClassLib в нескольких небольших проектах настольных приложений, которые демонстрируют возможности ClassLib, а также основной производственный проект.

Все отлично работает в демонстрационных проектах, а прекрасно работал в производственном проекте. Но производственный проект только что начал бросать сборку не найдена ошибка:

«Не удалось загрузить файл или сборку» RestSharp, версия = 100.0.0.0, Культура = нейтральная, PublicKeyToken = 598062e77f915f75 'или одна из ее зависимостей. Общее исключение (исключение из HRESULT: 0x80131500) ":" RestSharp, версия = 100.0.0.0, культура = нейтральная, PublicKeyToken = 598062e77f915f75"

Я пытался заставить демонстрационный проект выдать эту ошибку, запустив его с ClassLib.dll на четырех других машинах, где RestSharp не зарегистрирован, где я могу найти, но он работает отлично.

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

Дело в том, что до вчерашнего дня все было хорошо.

Так что, конечно, что-то изменилось, чтобы создать проблему, я просто не знаю, что это такое.

Соответствующие баллы:

  1. ClassLib скрывается с помощью Obfuscar. Так было всегда, и ничего (что я могу точно определить) не изменилось.
  2. ClassLib, демонстрационные проекты и производственный проект нацелены на .NET 4.5, как и пакеты NuGet Newtonsoft и RestSharp.
  3. Все хорошо строит; ошибка во время выполнения при первом обращении к API.
  4. Если я включу RestSharp в качестве эталонной сборки в производственный проект, все будет хорошо.
  5. Я дважды проверил версии сборки повсюду.
  6. Я очистил кеши и даже открыл проект в других версиях VS (я использую VS2017 Community, но до недавнего времени использовал VS 2013 Pro).
  7. Да, я понимаю, что мог бы просто включить RestSharp в качестве зависимости ClassLib, но я не хочу этого делать, учитывая, что встроенный подход должен работать нормально.
  8. Я также пытался использовать Costura, который, насколько я могу судить, работает очень хорошо, но симптомы те же.

Есть идеи?

1 Ответ

0 голосов
/ 09 сентября 2018

Хорошо, понял.

И ClassLib, и основной производственный проект («Продукт») реализуют (ed *) AssemblyResolve:

    internal static Assembly GetMissingAssembly(
        object s, 
        ResolveEventArgs e)
    {
        Assembly oResult = null;
        if (!e.Name.ToLower().Contains("resources"))
        {
            string Name = e.Name; //e.Name is read-only
            if (moAssemblies != null && moAssemblies.Count > 0)
            {
                if (moAssemblies.ContainsKey(Name)) oResult = moAssemblies[Name];
                if (oResult == null) throw new Exception("Could not load assembly " + Name);
            }
        }
        return oResult;
    }

Однако демонстрационные проекты не имели, так как в них нет встроенных сборок для извлечения.

Итак, когда Product не находил RestSharp, он вызывал GetMissingAssembly, достаточно разумно, а когда он не был найден в сборке сборок, выдавал указанную ошибку.

Однако, если я просто продолжу через обработчик, возвращающий нулевой результат, ссылка в конечном итоге будет разрешена в ClassLib - как и должно быть - и все в порядке.

Что бы ни изменилось, я еще не знаю - и, честно говоря, я не буду беспокоиться о поиске, но решение состоит в том, чтобы либо: 1) не выдавать ошибку и просто возвращать ноль, 2) игнорировать любой поиск RestSharp явно или, возможно, лучше, 3) проверить, внедряет ли встроенная сборка саму отсутствующую сборку, и завершите работу, зная, что она будет решена.

* Как уже упоминалось, я перешел на Costura в ClassLib, а не обработал AssemblyResolve сам. Я сделаю то же самое в Product и посмотрю, работает ли это или нет, и отправлю ответ. Я надеюсь, что авторы на Костуре подумали об этом сценарии, но мы увидим.

PS Спасибо мужу Пэриш за предложение проверить битность; Я нашел пару вещей, которые мне нужно было исправить, хотя проблема была не в этом.

...