System.Net.Http MethodNotFoundException при выполнении метода в библиотеке.NET Framework 4.7.1, загруженной через Reflection
Настроить
В рамках миграции большого решения VS с.Net 4.6 на 4.7.1 я заменил все файлы package.config на "PackageReferences" в каждом файле.csproj и удалил соответствующие стандартные теги "Reference", содержащие пути подсказок, указывающие на текущий момент. устаревший каталог "../packages/*". Я также добавил <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
а также <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
в каждый файл.csproj. Эта библиотека.Net 4.7.1 содержит различные ссылки на проекты на другие библиотеки.Net 4.7.1 и пакеты NuGet (некоторые из них предназначены для версий.NET Standard).
выполнение
У меня есть сценарий PowerShell, который загружает эту конкретную библиотеку.NET 4.7.1 через Assembly.LoadFrom("C:\Net471LibraryOutput\Net471Library.dll")
, создает экземпляр класса в этой сборке через new-object Net471Library.MyClass
и затем пытается выполнить асинхронный метод в этом классе, но встречается с "MethodNotFoundExcepion", говорящим, что метод, определенный в PackageReferenced NugetPackage, который ссылается на System.Net.Http, не может быть найден.
наблюдения
Моя библиотека.NET 4.7.1 ссылается на другой проект 4.7.1, который ссылается на System.Net.Http без конкретной версии, которую VS 2017 разрешает до версии 4.2.0.0, которую он нашел в C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll
Когда я смотрю на текущие сборки AppDomain после загрузки этой библиотеки через отражение, но перед выполнением команды я вижу.dll моей библиотеки 4.7.1 и не вижу System.Net.Http.dll
был загружен. После выполнения команды я обнаружил, что в приложение добавлено 2 записи для System.Net.Http, каждая из которых имеет свою версию.
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll
(версия 4.0.0.0)C:\Net471LibraryOutput\System.Net.Http.dll
(версия 4.2.0.0)
Если я скрываю System.Net.Http 4.2.0.0 от VS и перестраиваю, вывод Net471Library больше не содержит System.Net.Http.dll, и если я повторяю эти шаги без наличия.dll, метод выполняется успешно (без "MethodNotFoundException" на упомянутый метод пакета NuGet). Если я позволю VS найти System.Net.Http 4.2.0.0, даже если я настрою все ссылочные проекты на использование 4.0.0.0 (хотя я не могу настроить пакеты PackageReferenced NuGet), версия 4.2.0.0 по- прежнему помещается в вывод и я получаю ту же ошибку. Если я пытаюсь добавить ссылку на System.Net.Http непосредственно в библиотеку, чтобы попытаться форсировать вывод, я получаю ошибку сборки CS0433 "Тип 'HttpResponseMessage' существует в обоих файлах 'System.Net.Http, версия =4.2.0.0, Culture= нейтральный, PublicKeyToken=b03f5f7f11d50a3a'и' System.Net.Http, версия =4.0.0.0, Culture= нейтральный, PublicKeyToken=b03f5f7f11d50a3a'"
Я сделал несколько попыток воспроизвести проблему в упрощенном решении с меньшим количеством зависимостей, чтобы сузить проблему, но пока безуспешно.
2 ответа
Причина, по которой вы это видите, заключается в том, что, скорее всего, вы используете Visual Studio 15.5.* Для создания своего приложения, в котором отсутствует недавнее исправление, которое мы добавили для проектов, нацеленных на 4.7.1, для автоматического добавления перенаправлений привязки в несколько списков. фасады. Это изменение было добавлено сейчас и будет выпущено в VS 15.6 Preview 3 и более поздних версиях. Чтобы обойти проблему на данный момент, нужно вручную добавить необходимые перенаправления привязки, которые в данном случае:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
</assemblyBinding>
Можете ли вы проверить, если добавление решает вашу проблему? Если вам нужна дополнительная информация о исправлении, которое мы сделали, вы можете взглянуть на этот запрос на github: https://github.com/dotnet/corefx/pull/25786
Извините, это может быть лучше в качестве комментария, но у меня нет репутации, чтобы комментировать.
Натан Тёрнбоу, для применения перенаправления привязки он должен быть в файле app.config приложения, загружающего эти библиотеки. Это обычно означает в вашем app.config для вашего.exe, который будет автоматически переименован в ProgramName.exe.config или в ваш web.config.
В твоем случае я думаю, что это по-другому, потому что PowerShell загружает твои DLL. Я нашел это, что может помочь:
Перенаправление сборки конфигурации Powershell
PowerShell App.Config (в этом случае не обязательно перенаправление привязок)
Кстати, для устранения подобных проблем вы можете использовать fuslogvw, чтобы увидеть четкие логи того, что загружено и почему.
Надеюсь, это поможет,