Создание приложения с поддержкой плагинов [Plugin, C#]

Premium-WordPress-Plugins

В этой статье описан пример, как создать приложение с поддержкой плагин-архитектуры.

Итак, создает новый проект (Приложение Windows Forms), назовем его «PluginDemo«. После создания проекта переименовываем форму в «FrmMain«, бросаем на форму «ListView«, обзываем его «lvPluginsList«, устанавливаем свойство «View» в «Details«, добавляем 3 колонки (столбца): «Имя плагина», «Описание», «Версия». Думаю, уже догадались, что в этом «ListView» будут выводиться подключенные плагины.

Теперь приступим к написаю интерфейса для будущих плагинов (должны же мы знать, как с ними «общаться»). В обозревателе решений клацаем правой кнопкой мыши по решению «PluginDemo«, выбираем «Добавить» => «Создать проект«.

addProject

В списке выбираем «Библиотека классов«, указываем имя — «PlugIn«. Переименовываем «Class1.cs» в «Interfaces.cs» . Открываем этот файл, убираем пустой класс, который создался автоматически и добавляем:

У всех плагинов должен быть реализован интерфейс, который мы создали выше.
При загрузке плагинов и добавлении их в список мы будет получать значения следующих полей плагина: «DisplayPluginName«, «PluginDescription» и «Version«.
Когда пользователь будет выбирать в списке плагинов нужный ему плагин, то программа будет вызывать метод «Show()» выбранного плагина, в нем плагин может показать свою форму и т.п.
Кстати, не забудьте добавить наследование интерфейса «IPluginHost» главной форме:

Также нужно реализовать метод «Register( IPlugin plug )«:

Приступим к написанию плагинов. Снова добавьте новый проект («Библиотека классов«), назовите ее «Plugin1«. После создания проекта нажмите правой клавишей на «References«, выберите «Добавить ссылку…«, в открывшемся окне справа выберите «Решение» => «Проекты«, потом поставьте галочку напротив «PlugIn«.

addRefaddRefProj

Добавили мы ссылку на нашу библиотеку, где хранится интерфейс для наших плагинов. Нужно этот интерфейс реализовать в первом плагине (и остальных, естественно 🙂 ), но немного позже. Сейчас нужно добавить форму первому плагину. Снова, в обозревателе решений, нажимаем правой клавишей на «Plugin1«, выбираем «Добавить» => «Форма Windows«, называем ее «FrmP1Main«. Бросаем на форму «TextBox«, обзываем его «tbInfo«,  свойство «Multiline» переключаем в «True«.
Далее открываем код нашей формы, добавляем:

Нашему классу «frmP1Main» добавляем поле «plug» типа «IPlugin«:

Конструктору нашей формы добавляем параметр «IPlugin plug» и в теле конструктора присваиваем параметр полю «_plug», т.е. выйдет такое:

Теперь добавляем обработчик события «Load» нашей форме (нажимаем на форму, с окне «Свойства» нажимаем на значок молнии, два раза клацаем по пункту «Load«; либо двойной щелчок на форме):

Думаю, все понятно: во время загрузки формы в «tbInfo» будет добавлена информация о плагине.

Настало время реализовать интерфейс в плагине. Переименовываем файл первого плагина «Class1.cs» в «PlugIn«. Удаляем пустой класс и добавляем следующий код:

В коде выше реализованы методы и поля интерфейса «IPlugin«, также добавлены свои поля.
Надеюсь, еще не забыли о том, что когда пользователь будет выбирать нужный ему плагин в главном приложении, то наше приложение будет вызывать метод «Show()«, в котором создается экземпляр формы плагина и показывается пользователю.

Второй плагин попробуйте реализовать сами (в конце статьи есть исходник :)).

Возвратимся к главному приложению (PluginDemo). Плагины уже есть, а вот их загрузки нет 🙂 Сейчас исправим. Добавьте главному приложению ссылку на «PlugIn» (выше есть пример; также подключите с помощью using), далее добавьте поле «_plugins«:

Создадим метод «LoadPlugins( string path )«, в качестве параметра будет передаваться путь к папке, где находятся наши плагины (у нас они будут находиться в папке с программой):

Собственно, ищем все .dll в папке с программой (проверяя на наличие нашего «PlugIn«) и добавляем в список.

Теперь добавим метод, который будет добавлять подключенные плагины в «ListView«:

Пробегаемся по списку плагинов и добавляем в «lvPlugins» имя, версию и автора плагинов.

Добавляем методы «LoadPlugins()» и «AddPluginsItems()» в обработчик события «Load» формы:

Добавляем еще один обработчик события «DoubleClick» для «lvPlugins«:

Здесь мы проверяем: есть ли выделенные элементы, если есть — получаем индекс первого выделенного и вызываем метод «Show()» выбранного плагина.

В общем, всё 🙂 Должно получится что-то типа такого:

finalИсходники на GitHub

Запись опубликована в рубрике Статьи по C# с метками , , . Добавьте в закладки постоянную ссылку.

15 комментариев на «Создание приложения с поддержкой плагинов [Plugin, C#]»

  1. Евгений говорит:

    Отличная статья. Огромное спасибо автору…. Везде искал эта самая понятная…

  2. ффф говорит:

    … какой крд
    plugins[ plugins.Count ].Host = (IPluginHost)this;
    Тут ошибка типа «out of range». Необходимо учитывать что массивы считаются от нуля.

    • admin говорит:

      Ага, и не только массивы 🙂
      П.С. В исходниках на гитхабе норм, а здесь почему так — хз 😀

  3. coexire говорит:

    Подскажите плагины должны лежать только в корне программы?
    Все зделал запустил работает, если плагины лежат в корне, если переношу в папку Корень\\Плагины\\ то они не отстраиваются.

    • admin говорит:

      Рекомендую попытаться разобраться в данном коде хотя бы чуточку, а не просто копировать/вставлять 😉

      • coexire говорит:

        Я таки немного смотрел код, переписал под себя.

        private void Update_version_Load(object sender, EventArgs e)
        {
        String adress_plugin = Application.StartupPath ;
        //String adress_plugin = Application.StartupPath + «\\Main_plugins\\»;
        loadPlugins(adress_plugin);
        addPluginsItems();
        }
        В таком варианте работает если я пишу String adress_plugin = Application.StartupPath + «\\Main_plugins\\»;

        То на куске кода
        try
        {
        Assembly ass = null;
        ass = Assembly.Load( args );
        var s = ass.FullName;
        if ( ass != null )
        {
        ObjType = ass.GetType( args + «.PlugIn» );
        }
        }
        catch
        {
        return;
        } Все время срабатывает исключение

      • admin говорит:

        Нужно юзать LoadFrom тогда, вот ей нужно передавать полный путь к либе. Позже внесу правки в пример.

  4. coexire говорит:

    ass = Assembly.LoadFrom(pluginFiles[i].ToString()); решил этот вопрос

  5. azatot говорит:

    На одном компьютере работает все четко, а на другом компьютере плагины не отображаются в listview. В чем может быть проблема?

  6. den говорит:

    Приветствую, всё хорошо, спасибо за пример, но возможно подскажете как эти плагины запускать именно в главной форме FrmMain??? например в панель как то передавать сонтролы с формы!

    • admin говорит:

      Ссылки на плагины хранятся в this._plugins главной формы. В чем проблема передать их «куда нужно» и производить с ними необходимые действия?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *