Как использовать номера версий для интерфейса в приложении с плагинами? - PullRequest
1 голос
/ 05 января 2012

Я хочу написать программу, которая позволит писать плагины для него.
Программа будет содержать SDK с некоторыми библиотеками DLL, которые облегчат разработку плагинов.

Однако я почти уверен, что со временем SDK изменится, поэтому нужен какой-то номер версии для SDK и плагинов. SDK состоит из множества DLL.

Кроме того, я не хочу, чтобы разработчик плагинов мог забыть сделать что-то необходимое для механизма.

Я могу придумать два пути:

  • Использование постоянного времени компиляции int VERSION = 1 . Каждый плагин как-то (я не знаю как именно), принимает эту константу, и она добавляется в DLL как постоянная времени компиляции. Когда плагин загружен

  • Использование одной и той же AssemblyVersion для всех модулей SDK. Когда плагин загружен, убедитесь, что версия сборки плагина ниже текущей версии сборки SDK. В этом случае мне нужно как-то синхронизировать версию программы и версию SDK.

Итак, я не уверен, как сделать то и другое.

У вас есть идеи?

Ответы [ 3 ]

3 голосов
/ 05 января 2012

Я бы вообще не вводил концепцию управления версиями. Если вы думаете, что нужно Host:

  • возможность найти и загрузить плагины
  • возможность взаимодействовать с ними, предоставляя функции плагинам или восстанавливаясь после них.

Как управлять изменениями в dev SDK?

Прежде всего: все изменения должны быть максимально 1014 * обратно совместимыми.

Что делать, если это невозможно?

Что ж, Host ищет обнаруженную функциональность в загруженном плагине, если его не удается найти, это приводит к 3 возможным выводам.

  1. Плагин написан для более новой версии Host, но используется старой

  2. Плагин написан для более старой версии Host, но используется более новой.

  3. это не плагин valud.

Конечно, вы можете включить требуемую Host версию как атрибут в MainClass вашего плагина и Host может найти его, это может помочь в легкой идентификации возможной версии конфликт. Почему возможно , потому что версия может отличаться, но архитектура может быть довольно надежной и не нужно подключать поставщика, чтобы что-то изменить внутри нее.

Надеюсь, это поможет.

2 голосов
/ 05 января 2012

По просьбе @Andrey, это разработка моего комментария к OQ:

Плагины (как в сборках плагинов) чаще всего содержат класс, который реализует интерфейс, такой как IMyPlugin

В большинстве случаев этот интерфейс должен иметь метод, подобный InitPlugin(), который позволяет плагину настраивать его структуры и т. Д., Т.е. инициализировать.

Этот InitPlugin () сам по себе хочет больше всегочасто вызывайте что-то вроде RegisterPlugin () в основной программе, чтобы зарегистрировать его функциональность в приложении.Обычно это также достигается с помощью интерфейса, такого как IMyPluginHost.

Теперь, пока вы сохраняете эти интерфейсы настолько общими, что их сами по себе менять не нужно, вы можете легко добавить подтверждение версии с помощью этой последовательности:

public interface IMyPluginHost
{
  public int RegisterPlugin(int FunctionalityGroup, object WorkerBee, int MinSDKVersion, int MaxSDKVersion);
  ... //Whatever you need to allow the plugin to call into the app
}

public interface IMyPlugin
{
  public int InitPlugin(IMyPluginHost myhost); //Return value is hust an error code
  ... //Whatever you need to allow the app to call into the plugin
}

Теперь, когда приложение решит загрузить плагин, оно создаст свой внутренний хост-класс плагина, который реализует IMyPluginHost, затем физически загрузит плагин, получит IMyPlugin в своем классе и вызовет

((IMyPlugin)pluginClass).InitPlugin(this)

Теперь плагин может циклически изменять свои функциональные группы (какие группы существуют, зависит от вашего приложения - если это, например, приложение для работы с изображениями, могут существовать такие функциональные группы, как Filter, FileTypeImport, FileTypeExport, Brush, ... каждый со своим интерфейсом) и для каждого экземпляра рабочего объекта, затем вызовите

host.RegisterPlugin(FunctionalityGroup, WorkerBee, MinSDKVersion, MaxSDKVersion);

с хостом, равным IMyPluginHost, полученным в качестве аргумента для InitPlugin().

Таким образом, если плагин построен только для SDK V5, MinSDKVersion и MaxSDKVersion будут равны 5. Но если умный плагин может обрабатывать SDK версии 2-5 мин.DKVersion будет 2, а MaxSDKVersion будет 5. Это позволяет одному плагину работать с различными версиями вашего приложения (и, следовательно, SDK)

Само приложение также имеет ряд поддерживаемых версий SDK, скажем 3-6,Так что в этом случае вызов RegisterPlugin() вернет 5, так как это самая высокая версия SDK, которую поддерживают оба партнера.Опять же, это дает вашему приложению возможность поддерживать старые плагины, так что при обновлении вашего приложения не нарушаются все сторонние плагины.

Отрицательные возвращаемые значения для InitPlugin() будут ошибками.

После того, как это сделано, плагин имеет ссылку на хост и знает, чего он может ожидать от него с точки зрения версии SDK и наоборот.

1 голос
/ 05 января 2012

Создайте абстрактный класс, который должны быть реализованы всеми плагинами, и поместите в него логику проверки версии, то есть функцию, которая возвращает старший, младший и номер сборки, с которым совместим плагин, который вы вызываете после инициализации плагина.

В зависимости от того, насколько строго вы хотите проверить свои версии, вы можете ответить в приложении.(Я также рекомендую вам использовать SemVer для версий, вы поймете, почему по мере развития вашего API)

Это также позволяет вам проверять версии, слишком старые или слишком новые для запуска в вашем приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...