powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Reflection не отдупляет
25 сообщений из 40, страница 1 из 2
Reflection не отдупляет
    #39740051
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пытаюсь сделать систему плагинов.
Проект 1 - набор интерфейсов и статический класс, перебирающий dll'ки в поисках классов, реализующих эти интерфейсы. Перебирает таким способом:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        private static readonly Dictionary<string, IPlugin> _plugins = new Dictionary<string, IPlugin>();

        public static Dictionary<string, IPlugin> RequestPlugins(IApiFactory factory)
        {
            foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory()))
            {
                if (file.Substring(file.Length - 4).ToLower() != ".dll")
                    continue;
                try
                {
                    var ass = Assembly.LoadFrom(file);
                    var plugType = ass.GetExportedTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).FirstOrDefault();
                    if (plugType == null)
                        continue;
                    IPlugin plugin = Activator.CreateInstance(plugType, factory) as IPlugin;
                    _plugins.Add(plugin.Id, plugin);
                }
                catch (Exception) {
                }
            }
            return _plugins;
        }



Проект 2 - потребитель плагинов, дергает RequestPlugins.
Проект 3 - плагин, один из классов которого реализует IPlugin.

2 и 3 зависят от 1, и не зависят друг от друга. 1 ни от кого не зависит.

Пока 3 лежит в отдельной папке, всё работает, а как только перемещается в bin проекта 2 - перестает. Обнаружил, что в точке останова внутри вышеуказанной процедуры TypeHandle у typeof(IPlugin) и plugType.ImplementedInterfaces[0] (если вручную присвоить plugType из GetExportedTypes, IsAssignableFrom перестает работать) - разные, то есть с точки зрения 1 и 3 IPlugin, который 1 предоставляет, а 3, соответственно, реализует - это разные IPlugin'ы. Соответственно и CreateInstance перестает работать - IApiFactory тоже становятся разными, возникает ошибка о том, что подходящий конструктор не найден.

Почему это происходит и как победить?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740056
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Antonariy,

Exception какой?

У меня подозрение на строку
Код: c#
1.
_plugins.Add(plugin.Id, plugin);


Возможно вылетает при попытке вставить неуникальный plugin.Id?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740069
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,
Попробуй без linq на циклах отладить.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740074
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем велосипеды? Есть ведь MEF .
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740075
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
fkthatЗачем велосипеды? Есть ведь MEF .
А что это за зверь, в двух словах?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740077
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

1. LoadFrom уже не верно. Надо ReflectionOnlyLoad.
2. Оставь это рукоблудие, используй System.ComponentModel.Composition
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740081
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2fkthatЗачем велосипеды? Есть ведь MEF .
А что это за зверь, в двух словах?

"Managed Extensibility Framework". Несложная приблуда (осваивается за час), специально, чтобы лепить приложения с плагинами.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740084
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
fkthatCat2пропущено...

А что это за зверь, в двух словах?

"Managed Extensibility Framework". Несложная приблуда (осваивается за час), специально, чтобы лепить приложения с плагинами.
Приложения с платинами или плагины к приложениям?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740085
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2Приложения с платинами или плагины к приложениям?


Приложения, в которые ты хочешь встроить свою систему плагинов.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740089
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
fkthatCat2Приложения с платинами или плагины к приложениям?

Приложения, в которые ты хочешь встроить свою систему плагинов.
Спасибо. Страшно далек я от плагинов и ничего о них не знаю
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740094
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Petro123Antonariy,
Попробуй без linq на циклах отладить.
+1
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740104
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyIPlugin, который 1 предоставляет, а 3, соответственно, реализует - это разные IPlugin'ы.

Чисто, в порядке мозгового штурма - может что-то не так с версиями сборок? Типа 3 собрана с какой-то другой версией 1, чем та, с которой собрана 2.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740154
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Antonariy,
Попробуй без linq на циклах отладить.linq тут вообще ни при чем, я же написал, что в ручном режиме не работает.

fkthat Зачем велосипеды? Есть ведь MEF.Хрень какая-то. В демонстрационном солюшене вынес интерфейсы в отдельный проект как у меня, перевел на него зависимости, и все перестало работать: "Не удалось загрузить тип "SimpleCalculator3.IOperation" из сборки "SimpleCalculator3". Вот же тупой Composition, не может по строчке new AssemblyCatalog(typeof(IOperation).Assembly) догадаться, в какой сборке лежит IOperation.

mikron 1. LoadFrom уже не верно. Надо ReflectionOnlyLoad. ок

fkthatЧисто, в порядке мозгового штурма - может что-то не так с версиями сборок?Нет, меняется только командная строка в событиях после сборки, которая копирует собранную длл в ту или иную папку. Копируешь в bin основного проекта - не пашет, копируешь в любую другую папку - пашет.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740180
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyPetro123Antonariy,
Попробуй без linq на циклах отладить.linq тут вообще ни при чем, я же написал, что в ручном режиме не работает.мы же код текущий смотрим.
Приведи код ручного режима и исключение на строке.
Если до сих пор не работает.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740213
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> file.Substring(file.Length - 4).ToLower() != ".dll"
Path.GetExtension

>> var ass = Assembly.LoadFrom(file);
Так делать некомильфо. Загруженный плагиг уже не выгрузить. Обычно создают отдельный AppDomain и грузят в него. И когда возникает надобность выгрузить ненужный плагин без перезапуска ПО, выгружают весь AppDomain

И уже правильно рекомендовали: MEF. Более сложная штука, но более устойчивая с сбоям - MAF.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740216
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Directory.GetFiles(Directory.GetCurrentDirectory())
Вы уверены, что такая конструкция верно с вашей точки зрения определяет текущую папку? Попробуйте явно задать путь, в целях отладки.

>> Обнаружил, что в точке останова внутри вышеуказанной процедуры TypeHandle ... разные
А какие?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740223
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Так делать некомильфо. Загруженный плагиг уже не выгрузить.не требуется

Arm79А какие? TypeHandle это число, какая разница, какие конкретно значения? Важно лишь то, что в разных папках они одинаковые, а в одной - отличаются. И это как-то указывает на причину проблемы, но пока не ясно как.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740234
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariymikron 1. LoadFrom уже не верно. Надо ReflectionOnlyLoad. окне катит, зависимые сборки не грузятся, сваливается в ошибку.

короче:

Код: c#
1.
2.
            var ass = Assembly.LoadFrom("Plugin.dll"); // текущая папка - bin
            var plug = ass.GetExportedTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).FirstOrDefault();

не работает
Код: c#
1.
2.
            var ass = Assembly.LoadFrom(Directory.GetCurrentDirectory() + "..\plugins\Plugin.dll");
            var plug = ass.GetExportedTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).FirstOrDefault();

работает
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740256
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79>> Directory.GetFiles(Directory.GetCurrentDirectory())
Вы уверены, что такая конструкция верно с вашей точки зрения определяет текущую папку? Попробуйте явно задать путь, в целях отладки.
Antonariy
Код: c#
1.
2.
var ass = Assembly.LoadFrom(Directory.GetCurrentDirectory() + "..\plugins\Plugin.dll");
            var plug = ass.GetExportedTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).FirstOrDefault();


работает

Накидал по быстрому проект, работает:

Основное приложение
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
    class Program
    {
        static void Main(string[] args)
        {
            var pls = PluginLoader.LoadPlugins(Directory.GetCurrentDirectory());

            foreach(var pl in pls)
            {
                pl.DoSmth("plugin call");
                pl.DoSmth("plugin call");
                pl.DoSmth("plugin call");
            }

            Console.ReadLine();
            
        }
    }




Общая сборка с интерфейсом
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
    public interface IPlugin
    {
        string Id { get; }
        void DoSmth(string txt);
    }

    public static class PluginLoader
    {
        public static IReadOnlyCollection<IPlugin> LoadPlugins(string path)
        {
            var result = new List<IPlugin>();
            var potencialPlugins = Directory.GetFiles(path, "*.dll");

            foreach (string item in potencialPlugins)
            {
                if (Path.GetFileName(item) == "PluginCommon.dll")
                    continue;

                Assembly ass = Assembly.LoadFrom(item);
                List<Type> targetTypes = ass.GetExportedTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).ToList();

                if (targetTypes.Count == 0)
                    continue;

                foreach (Type pluginType in targetTypes)
                    result.Add((IPlugin) Activator.CreateInstance(pluginType));
            }

            return result.AsReadOnly();
        }
    }



Две разные сборки с классами-наследниками от IPlugin
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
    public class PluginClass : IPlugin
    {
        public string Id { get => "Plugin1"; }

        public void DoSmth(string txt)
        {
            Console.WriteLine($"{Id} - {txt}");
        }
    }

    public class Plugin2 : IPlugin
    {
        public string Id => "Plugin2";

        public void DoSmth(string txt)
        {
            Console.WriteLine($"{Id} - {txt}");
        }
    }



Результат работы
Код: plaintext
1.
2.
3.
4.
5.
Plugin1 - plugin call
Plugin1 - plugin call
Plugin1 - plugin call
Plugin2 - plugin call
Plugin2 - plugin call
Plugin2 - plugin call
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740260
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл добавить - все 4 сборки в одном каталоге (bin хостового приложения)
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740312
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можете солюшен приложить?
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740339
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740408
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79,

Солюшен работает нормально. Попробуй выкосить все папки bin и по-новой собрать. Стопудово у тебя в bin лежит какая-то не та сборка.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740412
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сборка та, я ее руками копирую из bin наружу.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740420
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

у меня все хорошо ))) Это Antonariy мучается )




Antonariy, может у тебя платформа не та? разные версии фреймворков?
...
Рейтинг: 0 / 0
25 сообщений из 40, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Reflection не отдупляет
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]