AssemblyLoadContext.Default в netcore 3.1 разрешает тип плагина, но не может извинить его экземпляр, когда плагин использует транзитивную зависимость - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть консольное приложение в netcoreapp3.1, которое использует плагин netstandard2.0. Плагин ссылается на библиотеку классов и реализует интерфейс. Все зависимости dll находятся в папке плагина и plugin.dep. json включают в себя все библиотеки, на которые есть ссылки.

Когда я запускаю:

AssemblyLoadContext.Default.LoadFromAssemblyPath("path/to/main_myplugin.dll");//load plugin

он разрешает тип интерфейса

Когда я пытаюсь запустить экземпляр, как указано ниже, происходит сбой:

 if (type != null)  //type is resolved and not null
            {
                var instance = (IContract)Activator.CreateInstance(type); //instance is created
                Console.WriteLine($"Create instance  : {instance.GetType()}"); // ok instance is created
                var ret = instance.Execute(); //!!!fire exception here
                Console.WriteLine(ret);
            }

и сообщение об ошибке:

System.IO.FileNotFoundException: «Не удалось загрузить файл или сборку» MyLibObjectsLib, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = null '. Система не может найти указанный файл. '

Если я загрузил все зависимости, все работает нормально.

Должен ли я загружать все зависимости при использовании AssemblyLoadContext.Default или это ошибка?

1 Ответ

0 голосов
/ 11 марта 2020

Я задал этот вопрос в проекте do tnet

Весь кредит go @vitek-karas.

Подробный ответ:

В настоящее время это дизайн. LoadFromAssemblyPath, как и любые другие методы, подобные LoadAssembly, только загружают эту сборку, они не пытаются загрузить «плагин». Для этого случая вам понадобится AssemblyDependencyResolver и подключить его к AL C по умолчанию (возможно, через событие Resolving), и надеяться, что между приложением хоста и плагином нет коллизий (поскольку они будут совместно использовать все зависимости). ) и так далее. Как правило, именно поэтому лучше загружать плагины в их собственные ALC, так как это создает необходимую изоляцию и облегчает подключение AssemblyDependencyResolver.

Ответ более высокого уровня - в версии 3.0 мы не пытались предоставить API "загрузки плагинов", так как было слишком много открытых вопросов о том, как он должен себя вести (точное поведение изоляции очень сложно понять, так как оно будет работать в большинстве случаев использования). Вместо этого мы предоставили необходимые строительные блоки (AL C, ADR, улучшения diag и т. Д.) И полагаемся на то, что пользователи напишут приблизительно 20 строк кода для реализации пользовательского AL C. В версии 5.0 мы улучшаем диагностику, добавляя подробную трассировку по всему процессу связывания сборок, что должно помочь в устранении проблем при загрузке сборок в целом, но особенно при реализации пользовательских ALC.

...