powered by simpleCommunicator - 2.0.27     © 2024 Programmizd 02
Map
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Reflection не отдупляет
40 сообщений из 40, показаны все 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
Reflection не отдупляет
    #39740597
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79fkthat,

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




Antonariy, может у тебя платформа не та? разные версии фреймворков?То есть я руками копирую бинарник, не работающий в одной папке, в другую папку, где он работает, а у него магическим образом в процессе копирования меняется версия фреймворка?
Уже обвиняли неуникальный ключ в пустом Dictionary, потом Linq, теперь эзотерику... Больше ада и оригинальных предположений! :))
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740600
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Телепатов тут нет, информации недостаточно
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740603
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Телепатов тут нет, информации недостаточноинформации достаточно, чтобы исключать абсурдные причины.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740646
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyArm79Телепатов тут нет, информации недостаточноинформации достаточно, чтобы исключать абсурдные причины.
Проза жизни:
авторЕсть такой бородатый анекдот: Стоит новый русский около своего мерса, грустно так. Останавливается еще один: че, типа, стоишь? Да вот, сломалась — не едет. А стекла протирал? Протирал. А колеса пинал? Пинал. Ну тогда, братан, не знаю. anekdotov.net
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740651
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyБольше ада и оригинальных предположений! :))если у самого не получается, тебе нужно выключить мозги и делать все что предлагают. Как в больнице.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740673
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy
Код: 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();


работает
во втором случае - задан абсолютный путь

ass.CodeBase - корректный? (ass - это сильно)
https://stackoverflow.com/questions/1477843/difference-between-loadfile-and-loadfrom-with-net-assemblies
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740683
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилво втором случае - задан абсолютный путьБез разницы, изначально в обоих случаях путь начинался с GetCurrentDirectory.

Изопропилass.CodeBase - корректный?Проверю.

Изопропил (ass - это сильно)это ты еще на plug внимание не обратил)
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740684
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123AntonariyБольше ада и оригинальных предположений! :))если у самого не получается, тебе нужно выключить мозги и делать все что предлагают. Как в больнице.в этой больнице половина советчиков сами пациентами являются.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740685
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariyв этой больнице половина советчиков сами пациентами являются.ответ ты сам знаешь - тогда в платную клинику или в личку.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #39740688
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй так:

Код: c#
1.
var ass = Assembly.LoadFrom(Path.GetFullPath("Plugin.dll"));
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Reflection не отдупляет
    #40076988
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно ли через Reflection отдуплить инициализирующее значение свойства?

Код: c#
1.
public int Depth { get; set; } = 3;



Троечку хочу вытащить.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #40076999
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это ж сахар. Фактически, ЕМНИП, компилятор просто запихивает инициализацию поля в конструктор, так что к метаданным это не имеет отношения
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #40077001
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разве что инстанцировать класс через рефлексию и посмотреть значение поля... ))
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #40077002
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, так и думал. Придется объект создавать.
...
Рейтинг: 0 / 0
Reflection не отдупляет
    #40077029
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy
В общем, так и думал. Придется объект создавать.


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


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