Задачки на подумать
Что то смотрю скучно стало. Решил подкинуть задачек из списка "решить когда нибудь".
Итак, есть некая система использующая принцип "плагинов" - динамически подгружаемых библиотек, которые в свою очередь пользуют общие библиотеки.
Например: П1 пользует Б1, Б2 и Б3, П2 пользует Б1 и Б3. Прога пользует Б1 и Б2.
1. Когда всё располагается в одном каталоге с прогой и компилируется одновременно, никаких проблем пока нет. Но хочется, чтобы при обновлении проги не нужно было обновлять старые плагины. Варианты?
2. У плагинов есть различные параметры настройки, которые должны отображатся в общем окне настроек приложения. Использование UserControl для WinForms в интерфейсе плагина решает задачу для WinForms. Но хочется чтобы плагины можно было пользовать и для WPF, либо пользовать окошки WPF в WinForms. При этом хотелось что бы параметры настройки остались личным делом плагина. Что же тогда передавать в интерефейсе плагина, что было проще использовать?
Предполагемые решения специально не привожу, может что более интересное найдётся.
1. Б1, Б2, Б3 - компилируется и апдейтятся вместе прогой. Плугины - они должны быть небольшими - грузятся и активируются по имени либы. Если совсем "правильно" - вешаем на класс аттрибутик и фильтруем по ним...
Код - могу сбросить позднее...
2. Не знаю - ВПФ - мимо...
Код - могу сбросить позднее
По постановке задачи вопросы есть?
Проблема не как сделать систему плагинов (там как раз по атрибуту и по принципу SOA), а как обеспечить взаимозаменяемость отдельных частей.
Ну типа, год назад поставили систему и все либы имели версию 1.0, а теперь парочка имеет версию 1.5 и требуется обновить ехе на меняя плагинов. Либо нужно только плагин обновить не меняя ехе и другой плагин.
2. Не знаю - ВПФ - мимо...
Это не важно, считай ASP.NET. Плагин хочется иметь платформно-независимым. Но приложение должно пользовать только вызов интерфейса плагина.
Еще одну вспомнил
3. Как отличить манагед от unmanged DLL без exception?
1. Когда всё располагается в одном каталоге с прогой и компилируется одновременно, никаких проблем пока нет. Но хочется, чтобы при обновлении проги не нужно было обновлять старые плагины. Варианты?
Мне кажется, Вы слишком вольно решили интерпретировать термин plug-in. Если Вы должны все компилировать вкуче, то это - вообще не плагин.
Плагин - это нечто, что Вы можете установить, не останавливая приложения. Но я уверен, Вы знаете, что такое плагин не хуже меня, но лучше придумайте другое слово, а то с толку сбивает.
Кроме того, плагин не обязательно имеет какое-то отношение к GUI, так что WinForms и WPF тоже - лишние детали в контексте плагинов.
Либо нужно только плагин обновить не меняя ехе и другой плагин.
-----
Пока не вижу что мешает.
У меня плугины делаются для двух версий 7-й и 11-й. Ожидается еще 17-я. Плугины лежат кучкой в отдельной папке.
Загрузчик плугинов читает заголовки и выбирает соответствующие версии,
Сколько их папке и какие именно - загрузчику без разницы - выберет подходящие по версии.
Объекты с которыми плугины работают - в отдельных ддлках вместе с ехе. Когда вносил изменения уже забыл - там все сделано по докам. Появится еще версия - напишу еще одну дллку.
Соответственно замена никакой проблемы не представляет - могу менять ехе, могу - плугины. Иногда так и делается - ручками закинул и ладно.
Ах, да... В проекте ссылок на плугины в референсах нет. Есть ссылки дллки плугинов как на файлы. Я вроде писал года полтора-два назад...
Или тебя деплоймент по частям интересует? Я это не смотрел, но никой проблемы нет - лишь бы плугин был доступен - загрузчик дллки может и не лочить...
все либы имели версию 1.0, а теперь парочка имеет версию 1.5
------
Единственная проблема - когда твои Б1, Б2, Б3 не совместимы или с ЕХЕ, или с плугинами - ну тут уже никак... На этот случай - имплементировано все через интерфейсы - пока они совпадают - все нормально.
Плагин хочется иметь платформно-независимым.
-----
Угу... но вин-форм и веб-форм несколько различаются по месту исполнения кода и хранения информации - реализация довольно различная...
3. Заголовок читать? Но Я не смотрел в чем там разница...
но лучше придумайте другое слово
ничего попроще, покороче и понятней не придумывается. Есть предложения?
Плагин - это нечто, что Вы можете установить, не останавливая приложения
В принципе так оно и есть, но где то все равно нужно держать общие аттрибуты и интерфейсы. И делать один единственный файл/проект со ссылками на целые либы, как то не очень...
так что WinForms и WPF тоже - лишние детали в контексте плагинов
Если писать только абстрактно - могут не понять, поэтому детали ввёл специально.
Плагин - это нечто, что Вы можете установить, не останавливая приложения.
-----
Не обязательно.
Возможность заменить дллку плугина зависит не от дллки, а от того каким методом она загружена.
Аналогично - выгрузка - от того как используется объекты из дллки - пока есть живые ссылки - не выгрузишь.
Так что плугин стоит определять как элемент, отсутствие которого не ведет к неработоспособности программы.
Пока не вижу что мешает.
Если плагин один единственный файл то ничего. Но предположим, два плагина пользуют либку для СОМ порта, а эти либки пользуют еще одну самую общую либку которую пользует и ехе.
При загрузке плагины попадают в аппликатион домаин со всеми либками. А там низзя держать одинаковые типы с разными версиями.
Поставили софт с версиями либок 1.0 пару лет назад. Теперь нужно один плагин заменить, а у него уже все общие либки другой версии 1.5
Значит один плагин пользует СОМ либку 1.0, а другой 1.5.
На этот случай - имплементировано все через интерфейсы - пока они совпадают - все нормально
не все может быть через интерфейсы, да даже пусть и так, но один и тот же тип будет иметь разную имплементацию, то бишь нужно раскидывать по разным апп-доменам.
но вин-форм и веб-форм несколько различаются по месту исполнения кода и хранения информации
безусловно и в этом то и есть проблема. Приложение не должно знать о настройках плагина они привязаны к плагину и только он знает как их отобразить пользователю в наиболее удобном виде. Конечно, для каждой платформы должна быть своя имплементация и вот ее то и нужно как то удобно абстрагировать.
3. Заголовок читать?
Да видимо прийдется, хотя очень не хотелось
А вы уверены что не изобретаете велосипед? Я плохо знаком с С#, но осталось в голове что есть для него от микрософта MAF, который "похож" на явовский OSGi, который ваши требования (в яве) выполняет.
При загрузке плагины попадают в аппликатион домаин
-----
Ну тут уже без деталей имплементации загрузчика не обойтись.
Такую задницу Я себе пока еще не создавал, но одноименные классы из разных дллок вроде уже инстанцировал,
Теперь нужно один плагин заменить, а у него уже все общие либки другой версии 1.5
-----
Ты еще попроси что бы и либы 1.5 на систему не копировались - тогда веселее будет.
Делаешь общую либу с интерфейсами. Пока все взаимодействует через них - проблемы не будет.
Если уж совсем выпал из синхронизации - замени и ехешник.
один и тот же тип будет иметь разную имплементацию, то бишь нужно раскидывать по разным апп-доменам
------
Это если ты грузишь стандартным способом по имени дллки.
Попробуй грузить из байт-массива.
вот ее то и нужно
как то удобно абстрагировать.
-----
Поделись как нарисуешь - Я ее в шаблоны загоню и забуду про различия в протоколах...
Замечательный ответ! Как раз согнать с рельсов. Всегда пользовали MEF. Да и в принципе реализовывался совсем другой концепт, а задачка получилась как бы по пути.
https://stackoverflow.com/questions/835182/choosing-betwee...
Надо попробовать, хотя народ грит что сильно сложный концепт.
но одноименные классы из разных дллок вроде уже инстанцировал
И куда они попадали после загрузки, и насколько сложной была иерархия классов?
Пока все взаимодействует через них - проблемы не будет.
Тут позволю не согласится. Вот в интерфейсе есть функция Run. В версии 1.0 она зажигает лампочку, а вот в версии 1.5 дополнительно еще и окно открывает (ошибка).
Сделал ты обновление в цех, а тебе звонят и говорят что толщина стекла не мерятся. А если бы плагин измерения толщины не менялся бы вообще (даже не перекомпилировался), то можно было сразу сказать что проблема у них. А так изменения в общей либе вполне могут затронуть что то "дружественное", то бишь тестить нужно опять по полной.
Попробуй грузить из байт-массива.
А разница то в чем? The assembly is loaded into the application domain of the caller.
https://msdn.microsoft.com/en-us/library/h538bck7(v=vs.110...
Поделись как нарисуешь
нет проблем, только как я уже сказал, задачки на будущее, когда время будет на их реализацию неясно.
Сейчас нужно совсем в другую сторону рыть - промышленный Ethernet
Сегодня долбил целый день контроллер от Сименса, а его ИП так и не нашел.
И куда они попадали после загрузки, и насколько сложной была иерархия классов?
-----
Куда попадали - не смотрел - без надобности было.
Иерархия, по классам, двух- и трех- уровневая. Все классы в иерархии - в пределах одной либы.
то бишь тестить нужно опять по полной.
-----
Ну так не путай две вещи - технику загрузки дллки и функциональность в дллке.
Первое мы можем обсуждать на уровне нашего опыта и знаний системы, а вот по второму знания только у тебя.
И это - про совместимость Я оговорил ранее - либо есть, либо нету.
тебе звонят и говорят что толщина стекла не мерятся.
-----
Ну и? Ну горит лямпочка - ошибка... ну дополнительно показал формочку - ошибка... стекло-то меряется не тут...
Сейчас как раз ковыряю именно меряющий код... 4-ре месяца назад все приостановили на средине модификации...
сейчас - снова возвратили... мрачно, однако...
А разница то в чем?
-----
Первая разница в том, что у тебя не лочится либа. Т.е. ты не оказываешься в ситуации, когда информация об составе либы полностью кешируется и создает проблемы. Хотя - может и не так...
долбил целый день контроллер от Сименса, а его ИП так и не нашел
-----
Когда-то ковырял Симатик от Сименса - не было там ИПов - там была своя идентификация контроллеров.
Все классы в иерархии - в пределах одной либы.
У нас обычно в разных. Базовая функциональность в общей, а конкретика в специализированной.
Первое мы можем обсуждать на уровне нашего опыта и знаний системы, а вот по второму знания только у тебя.
неа. Конкретика везде только у исполнителя, а вот принцип остается общим для всех.
Даже то что ты говорил о неизменности интерфейса это тоже может быть верно при определенном концепте. Мне то ведь ничто не мешает добавить новый интерфейс не меняя старого.
Просто ты не учитываешь еще одной вещи - даже используя одинаковые штекера нужно иметь одинаковые сигналы. Может измениться даже просто время отклика и это может повлечь изменения в работе проги.
Симатик от Сименса - не было там ИПов
Есть там всё просто они могут быть "прозрачными", так как работа начинается с броадкаста "а есть тут кто?".
Хотя это так в нашей системе.
У нас обычно в разных.
-----
Как повлияет на ситуацию - не знаю - надо тестить. Потому и подчеркнул что все в одном месте.
Мне то ведь ничто не мешает добавить новый интерфейс не меняя старого.
-----
Ну сознательно теряешь совместимость - нормальная практика.
Ненормальная практика - продолжать требовать совместимости в условиях когда она сознательно утрачена.
Просто ты не учитываешь еще одной вещи - даже используя одинаковые штекера нужно иметь одинаковые сигналы. Может измениться даже просто время отклика и это может повлечь изменения в работе проги.
-----
Разумеется - обсуждается - софт, а не детали аппаратной реализации незнамо чего.
То, что могут возникнуть проблемы из-за деталей внешних подключений - это плохо. Сильно плохо. Чем решать - надо смотреть по месту, но в общем случае периферия должна общаться с системой по одному из стандартных протоколов и прием/передача должны ему соответствовать.
Хотя это так в нашей системе.
-----
Ну так это в вашей системе.
Мне то ведь ничто не мешает добавить новый интерфейс не меняя старого.-----Ну сознательно теряешь совместимость
ничего подобного. Старый код не должен знать о новой функциональности, но продолжает спокойно работать. Именно то что и требуется
Разумеется - обсуждается - софт, а не детали аппаратной реализации незнамо чего.
Примерчик со штекером просто аналогия интерфейса и его имплементации.
Ты утверждаешь, что достаточно не менять интерфейса и всё будет хорошо. Я же говорю, что это недостаточное условие.
Была у меня как то либа с хорошим тестовым покрытием. Так бывало самые "безобидные" изменения приводили к сбою совсем не связанных вроде тестов.
но продолжает спокойно работать.
-----
Ну а новый код со старой либой вываливается с криком - неимплементировано...
Мне вот сейчас надо будет имплементить новый IEnumerator<T>
Такой, чтобы умел положить текущий элемент на вершинку треад-статического стека в потоке. А если там такой уже есть - заменил его.
И ты хочешь, чтобы он без сбоев работал при отсутствии стека?
А вот как прописать обязательность наличия - не представляю...
Так бывало самые "безобидные" изменения приводили к сбою совсем не связанных вроде тестов.
-----
Угу... бывало и по-другому - сбои в разные моменты и без всякого изменения в коде...
Но мы же не глюки обсуждаем, а как обновить плагины когда у них перехлест в используемых дллках?
Ну а новый код со старой либой вываливается с криком - неимплементировано
Не вываливается, а просто говорит что неимплементировано. То бишь нефиг меня трогать для новых работ.
Но в моем случае это не важно. У меня следующий случай:
1. Система поставлена заказчику Б в комбинации А.
2. Требуется заменить заказчику минимально возможный набор компонентнов из комбинации А.
Но мы же не глюки обсуждаем, а как обновить плагины когда у них перехлест в используемых дллках?
Не совсем. Меня лично интересует архитектура построения системы с минимальной зависимостью между частями при наличии общих библиотек.
с минимальной зависимостью между частями при наличии общих библиотек.
-----
Переформулировать не хочешь? Бо в этом варианте это точно не 1 по формулировке.
В общем случае, как ты и говорил выше, несовместимые либы грузятся в другой аппдомен.
Я бы не мучался и сделал первичную загрузку плугинов в аппдомен для конкретной версии - тогда голова не будет болеть вопросом Куда грузить?