Подтвердить что ты не робот

NUnit не может найти сборку, но консольное приложение может

У меня есть класс С#, который вызывает сборку .Net, построенную из функции Matlab. Я могу вызвать эту функцию из простого консольного приложения С# без проблем.

Однако, если я попытаюсь запустить unit test из NUnit, я получаю следующее исключение:

ClassLibrary1.Tests.UnitTests.TestPerformOptimization: System.Reflection.TargetInvocationException: Исключение было брошенный мишенью вызова. ---- > System.Exception: Ошибка сортировки объекта .NET. 'Сообщение: невозможно найти сборку 'ClassLibrary1, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = нуль. Источник: mscorlib HelpLink: '

Я получаю ту же ошибку, если попытаюсь вызвать класс из автономной консоли NUnit, из тестового бегуна ReSharper или если я попытаюсь вызвать функцию из Excel (используя Excel-DNA).

При вызове моего скомпилированного компонента Matlab я фактически завершаю метод С# (в объекте MWObjectArray) и вставляю его. Я думаю, что проблема возникает, когда скомпилированный компонент Matlab пытается вызвать этот введенный метод.

Единственное обходное решение, которое я нашел, - просто разместить копию моего класса (содержащего введенный метод) в том же месте, что и тестовый бегун NUnit, тестовый бег ReSharper или Excel. Однако это просто не практическое решение, так как мне нужно установить это приложение на компьютеры пользователей. Другой вариант, который я не могу использовать, - это копирование файлов на мой% DEVPATH% по той же причине.

Можно ли указать компонент Matlab, где можно найти сборку моего вложенного метода/класса?

ПРОСМОТР ПРОГРАММЫ ЗАГРУЗИТЬ

Здесь доступен образец проекта . Просто следуйте инструкциям в файле README.txt, расположенном в zip файле.

Обновление 1

Мне удалось получить мой unit test, чтобы распознать мою сборку, изменив мой класс, чтобы включить в его конструктор следующее:

AppDomain.CurrentDomain.AssemblyResolve +=
                 (sender, args) => typeof(OptimizationFunction).Assembly;

Однако теперь я получаю следующее исключение:

Исключение: System.Reflection.TargetInvocationException: Исключение имеет была выбрана целью вызова. --- > System.Exception: Ошибка сортировки объекта .NET. 'Сообщение: не удалось загрузить файл или сборка 'dotnetcli, Версия = 1.0.5488.33915, Культура = нейтральная, PublicKeyToken = da1231a838c93da4 'или одна из его зависимостей. требуется строго обозначенная сборка. (Исключение из HRESULT: 0x80131044) Источник: mscorlib HelpLink: 'at dotnetcli.throwNetExceptionID(BaseMsgID * msgId) в dotnetcli.DeployedDataConversion.GetMxArrayFromObject(данные объекта)
--- Конец внутренней проверки стека исключений --- в System.RuntimeMethodHandle.InvokeMethod(Object target, Object [] аргументы, Signature sig, Boolean constructor)

Итак, теперь у него есть проблема с разрешением dotnetclli.dll(см. Fusion log/exception ниже), который, насколько я знаю, должен находиться только в C:\Program Files (x86)\MATLAB\MATLAB Runtime\v85\bin\win32.

Здесь выдержка из журнала Fusion:

=== Информация о состоянии предварительной привязки ===

LOG: DisplayName = ClassLibrary1 (частично) WRN: Название сборки: ClassLibrary1 | Идентификатор домена: 1 WRN: частичное связывание происходит, когда предоставляется только часть отображаемого имени сборки. WRN: Это может привести к тому, что связующее загрузит неправильную сборку. WRN: рекомендуется предоставить полностью определенный текстовый идентификатор для сборки, WRN: состоит из простого имени, версии, культуры и токена открытого ключа. > WRN: см. Технический документ http://go.microsoft.com/fwlink/?LinkId=109270 для получения дополнительной информации и общих решений этой проблемы. LOG: Appbase = file:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/ LOG: Initial PrivatePath = NULL LOG: Dynamic Base = NULL LOG: Кэш-база = NULL LOG: AppName = nunit-agent-x86.exe Вызов сборки: (Неизвестно).

=== LOG: Это связывание начинается с контекста нагрузки по умолчанию. LOG: Использование файла конфигурации приложения: C:\Insight\TFS\Asg\ConsoleApplication4\пакеты\NUnit.Runners.2.6.3\инструменты\NUnit-агент-x86.exe.Config LOG: Использование файла конфигурации хоста: LOG: использование файла конфигурации машины из C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. LOG: политика не применяется к ссылке в это время (частное, пользовательское, частичное или привязку сборки на основе местоположения). LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication4/packages/NUnit.Runners.2.6.3/tools/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/ClassLibrary1/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/lib/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/lib/ClassLibrary1/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/addins/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/addins/ClassLibrary1/ClassLibrary1.DLL. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/ClassLibrary1.EXE. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/ClassLibrary1/ClassLibrary1.EXE. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/lib/ClassLibrary1.EXE. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/lib/ClassLibrary1/ClassLibrary1.EXE. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/addins/ClassLibrary1.EXE. LOG: попытка загрузки нового URL-адреса Файл:///C:/XXXXX/ConsoleApplication1/packages/NUnit.Runners.2.6.3/tools/addins/ClassLibrary1/ClassLibrary1.EXE. LOG: все пробные URL-адреса пытались и не выполнялись.

WRN: информация о частичной привязке была предоставлена ​​для сборки: Как мое консольное приложение может разрешить эту сборку по моему тесту NUnit, не может?

Обновление 2

Я получил следующий ответ от Matlab, когда я связался с ними:

Насколько я знаю, это поведение по умолчанию .NET, когда дело доходит до deserializations. Приложение, которое десериализует класс, выглядит для сборки в ее собственной текущей папке и GAC, где она не может Найди это. Это похоже на (когда вы читаете это, замените MATLAB на Nunit)

http://www.mathworks.com/matlabcentral/answers/101695-why-can-my-assembly-not-be-found-when-deserializing-a-net-object-in-matlab-7-10-r2010a

Вы, например, не видите ситуацию, когда задействован MATLAB. MATLAB отправляет класс через APPDomains. Ваш пример не делает что.

Используйте Fuslogvw, чтобы посмотреть на привязку. Вы увидите, что это не MATLAB, который не может найти сборку своим вызывающим приложением который не может решить зависимость (в вашем случае NUnit-агент-x86.exe).

4b9b3361

Ответ 1

Убедитесь, что все необходимые файлы создаются компиляцией ConsoleApplication4 и размещены помимо исполняемого файла (например, любой необходимой сборной DLL, DLL времени выполнения, файла .config и т.д.).

Как только вы убедитесь, что это произошло, запустите NUnit с помощью командной строки -no-shadow-copy или установите его как параметр конфигурации из вашего инструмента GUI. Как сказал Буш, NUnit обычно копирует тестируемые файлы в отдельный каталог и может оставлять важные файлы.

Если класс, созданный Matlab, нуждается в определенном времени выполнения, убедитесь, что он правильно установлен на компьютерах, где вы запускаете тесты/используя Excel/ReSharper.

Я бы не стал возиться на этом уровне с процессом резолюции Ассамблеи: пожалуйста, подведите итог содержания в связанной статье, потому что он платит, и попробуйте с настройкой NUnit no-shadow-copy.

Ответ 2

Предлагаем первую проблему:

  • Запустить regedit
  • перейти к HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion
  • Добавить DWORD ForceLog = 1
  • Добавить DWORD LogFailures = 1
  • Добавить DWORD LogResourceBinds = 1
  • Добавить String LogPath = C:\log\(последний должен быть там)
  • Создайте каталог для журналов (например, c:\logs)

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

Требуется вторая ошибка: требуется сборка строго названной сборки, означает, что библиотека, которую вы пытались использовать, не была подписана. Если это ваша сборка, вам просто нужно использовать визуальную студию, чтобы подписать сборку из свойств проекта. Если это не ваша сборка, вы можете декомпилировать ее и скомпилировать ее с сильным именем (с помощью этого метода), но поставщик третьей стороны dll должен дать вам сильная команда.

Ответ 3

Я предполагаю, что эта проблема связана с несовместимостью версии .NET CLR. Некоторые клиенты (я имею в виду клиент, который вызывает вашу сборку) загружают разные версии CLE, тогда разрешенная сборка может несовместимо с этой загруженной CLR. Это может привести к не найденной ошибке, потому что совместимая сборка действительно не найдена.

Попробуйте проверить/сыграть как с клиентскими версиями (консольное приложение), так и с версией сервера (ваша сборка) и диагностировать, что меняется.

Также проверьте, что ссылка на сборку отмечена как "Копировать в выходной каталог" во всех проектах

Ответ 4

Вам нужно будет изучить, как происходит операция зондирования во время загрузки .NET. Здесь правила для этого: https://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.110).aspx

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

Мы видели проблемы, подобные этому в прошлом, говорит один разработчик системному администратору, здесь Dlls вам нужно, чтобы приложение работало. Системный администратор следует инструкциям и стрелу, приложение не работает во время загрузки.

Причина. Некоторое дочернее событие дочернего элемента в сборке ссылается на DLL, что НЕ в системе на основе правил зондирования.

Решение 1) Получите (dll ребенка) dll, чтобы включить все зависимости в сборку 2) Измените новую главную сборку, чтобы включить все зависимости (если дочерние сборки не могут быть изменены). 3) Вручную скопируйте их. 4) Создайте установщик, который сделает все это.

Ответ 5

Является ли сборка в глобальном кэше сборок (GAC) или в любом месте, которое может быть переопределяющим сборку, которая, по вашему мнению, загружается? Обычно это результат загрузки неправильной сборки, для меня это означает, что у меня обычно есть что-то в GAC, переопределяющее версию, которую я имею в bin/Debug.

Ответ 6

Я предполагаю, что эта проблема связана с несовместимостью версии .NET CLR. Некоторые клиенты (я имею в виду клиент, который вызывает вашу сборку) загружают разные версии CLE, тогда разрешенная сборка может несовместимо с этой загруженной CLR. Это может привести к не найденной ошибке, потому что совместимая сборка действительно не найдена.

Попробуйте проверить/сыграть как с клиентскими версиями (консольное приложение), так и с версией сервера (ваша сборка) и диагностировать изменения.

Также проверьте, что ссылка на сборку отмечена как "Копировать в выходной каталог" во всех проектах