Несколько плагинов с общими библиотеками

Автор Тема: Несколько плагинов с общими библиотеками  (Прочитано 24596 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн MikhailTAPАвтор темы

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Добрый день!
В нашей компании есть следующая проблема: имеется несколько плагинов использующих общие библиотеки. При этом, если на машине установлен один из плагинов, и рядом ставится второй плагин с обновлённой общей библиотекой, то возникает конфликт. Любой из установленных плагинов может не находить нужных методов (если сигнатура метода была изменена), или же использовать методы из старой библиотеки.
Каким образом можно решить эту проблему?

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Что-то я не понял - если рядом ставится второй плагин с обновленной общей библиотекой, то как тогда могут быть использованы методы из старой библиотеки? Разве они не заменены на новые?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Если вы изменяете логику работы метода - то меняйте и имя. В конце-концов, можно просто добавлять циферки на конце (SuperPuperMethod, SuperPuperMethod1...). А если добавляете новый метод с другой сигнатурой, то конфликтов по идее быть не должно (в NET).

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Каким образом можно решить эту проблему?
Взаимодействовать посредством интерфейсов. Принцип аналогичен тому, который в COM.

.NET гораздо более гибок, чем COM. Например, ты можешь править уже имеющиеся старые интерфейсы, добавляя новые методы и всё при этом будет работать. Главное при этом - не трогать уже имеющиеся старые, иначе получишь то, что ты получил. Тогда конфликтов быть не должно, насколько мне известно. По факту, в твоём случае, ноги растут от плохого проектирования. Прежде чем садиться писать код, неплохо было бы для начала (помимо анализа проблемы) выполнить проектирование и лишь затем садиться за реализацию. В процессе проектирования в т.ч. заранее продумываются и программные интерфейсы с учётом дальнейших возможных изменений.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В нашей компании есть следующая проблема: имеется несколько плагинов использующих общие библиотеки. При этом, если на машине установлен один из плагинов, и рядом ставится второй плагин с обновлённой общей библиотекой, то возникает конфликт.
Решение очевидно - не делать так. Или не менять общие библиотеки или обновлять и ставить одновременно все плагины, использующие эти общие библиотеки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Решение очевидно
очевидно в текущем контексте. - так будет корректней.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Возможно будет интересно...

Если говорить о варианте, когда сохраняются разные версии DLL (то ли под разные версии CAD, то ли под разные версии .NET, то ли оба варианта вместе)... Разные версии AutoCAD используют разные версии .NET Framework. Т.о. в одном каталоге разместить одноимённые DLL, собранные под разные версии .NET не получится. Варианта два:
  • давать разные имена DLL файлам, например добавляя различного рода суффиксы, указывающие либо целевую версию CAD (.R17.2, R18.0, и т.д.) либо указывающие версию CLR, если это общая DLL, не связанная с AutoCAD .NET API
  • помещать DLL по отдельным подкаталогам (в этом случае DLL имеют одинаковые имена). В runtime вычисляется нужный подкаталог и грузится нужная DLL.
За всю свою историю работы я ни разу не столкнулся с проблемами в работе своих .NET плагинов, использующих мною же созданных  (и, по мере необходимости, обновляемых) общих DLL. Это обусловлено в первую очередь тем, что очередная версия DLL не изменяет состав и сигнатуры уже существующих методов. Я могу добавлять новые или изменять реализацию, но не меняю "старые контракты". Взаимодействие выполняю, как правило, посредством интерфейсов.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
За всю свою историю работы я ни разу не столкнулся с проблемами в работе своих .NET плагинов, использующих мною же созданных общих DLL.
Тут существенно местоимение "Я". Замени его на "Мы" и вполне возможно что возникнет проблема.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
и вполне возможно что возникнет проблема.
И на чём же она должна возникнуть, если контракт не нарушен? Пример, если не сложно.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
И на чём же она должна возникнуть, если контракт не нарушен? Пример, если не сложно.
Главная проблема именно в том, что если созданием/развитием общих библиотек занимается не один, а несколько человек, то контракты часто нарушаются ("правила игры меняются по ходу игры"). Результаты мы видим у MikhailTAP.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн MikhailTAPАвтор темы

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
В качестве эксперимента сделал следующие: загружаю плагин1 (использует более раннюю версию общей библиотеки), затем загружаю плагин2(использует обновлённую версию общей библиотеки). Потом в VS посмотрел загруженные модули, и получается, что в такой ситуации, общая библиотека подгружаемая плагином2 - игнорируется (в памяти висит только библиотека плагина1).
Вариантом был бы StrongName, но сделать это невозможно, т.к. библиотеки Акада которые используются - не подписаны.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Вариантом был бы StrongName, но сделать это невозможно, т.к. библиотеки Акада которые используются - не подписаны.
давно известный факт, причём автодеск утверждает, что это безобразие создано специально.
« Последнее редактирование: 01-07-2015, 10:50:33 от Андрей Бушман »

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Только сейчас заметил, что на мой вопрос в комментах по обозначенной выше ссылке ответили. Что же, на первый взгляд аргументация выглядит достаточно разумной.
« Последнее редактирование: 01-07-2015, 10:51:45 от Андрей Бушман »

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Эх, поднимем такую хорошую тему :)
Тоже столкнулся с проблемой общих сборок.
Ситуация такая: есть несколько приложений, которые используют несколько общих вспомогательных DLL. Одна библиотека расширяет функционал AutoCAD API, вторая - Civil 3D API, третья - вспомогательная библиотека с механизмом реализации ссылок между объектами чертежа, ну и т.д. Каждое приложение имеет свой собственный инсталлятор и устанавливается отдельно в свою папку Bundle. Соответственно, каждое из приложений тянет в свою папку эти вспомогательные DLL. Упрощенная схема на рисунке Current. Так вот, если я внес какие-то изменения во вспомогательные DLL, пересобрал приложения, создал новые инсталляторы и отправил пользователям, но они по какой-то причине не обновили все приложения, то возникают вполне логичные различные неполадки несовместимости при их загрузке в AutoCAD. Со стороны пользователя, это, конечно же, значительное неудобство. Получается, я облегчаю себе жизнь, как разработчику, вынося повторяющийся функционал в общие библиотеки, но этим усложняю жизнь пользователям. Думаю, что это не очень хорошо.
Как выход из этой ситуации, мне видится создание отдельной инсталляции для вспомогательных библиотек. Можно это сделать в виде отдельного компонента и внедрять как необходимый компонент в инсталлятор каждого приложения. При установке, будет проверяться версия установленного пакета библиотек и, при необходимости, обновляться. Схема не нова, нечто похожее используют многие инсталляторы приложений Windows. Взять, хотя бы, для примера, установку нужной версии .NET Framework при установке AutoCAD.
Разумеется, помещать пакет библиотек логично в таком варианте в отдельном Bundle. Упрощенная схема на рисунке Project. На первый взгляд, вроде работоспособно. Каких-то проблем с технической реализацией этой схемы я пока не вижу. Но нужно как-то обеспечить загрузку вспомогательных библиотек раньше загрузки всех приложений, которые их используют. Иначе AutoCAD их сам не найдет и не загрузит, когда DLL приложения запросит какой-нибудь объект из вспомогательной DLL, и загрузка приложения прервется ошибкой. Как я понимаю, загрузка Bundle выполняется в AutoCAD по алфавитному порядку названий папок Bundle в каталоге ApplicationPlugins. Получается, что нужно обеспечить папке Bundle с библиотечными DLL такое название, чтобы она была "выше всех". На мой взгляд, это довольно "топорный" способ т.к. нет гарантии, что AutoCAD и дальше будет так загружать пакеты. С его точки зрения все Bundle равнозначны и независимы. Да и хотелось бы давать свободные названия для папок Bundle, а не что-то типа "0Library.bundle", "1Application1.bundle", "2Application2.bundle". Но, пока, ничего лучше придумать не могу. Может быть, есть у кого-то интересные идеи по данному вопросу? Или критические замечания по такой схеме?
Спасибо.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Может быть, есть у кого-то интересные идеи по данному вопросу? Или критические замечания по такой схеме?
Пока на уровне интуиции я могу сказать, что так делать не следует.
Во-первых не следует полагаться на порядок загрузки. Я не проверял, но мне кажется, что он читает каталоги внутри ApplicationPlugins и обрабатывает их не в алфавитном порядке, а в том порядке в котором они находятся в каталоге (а это совершенно необязательно отсортированные по алфавиту).
Во-вторых, я бы предпочел в методе Initialize своих приложений загружать необходимые сборки если они еще не загружены, а если их загрузить не удаётся, то сообщал бы пользователю.
В-третьих, я бы вообще не включал их ни в какие BUNDLE'ы - если это библиотечные файлы, то зачем отдавать их загрузку на волю AutoCAD?
IMHO.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение