Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab3.docx
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
3.22 Mб
Скачать

Реализация класса третьего плагина

Этот класс будет многим похож на аналогичный в первом плагине, разве что мы не будем создавать копии серверных классов PluginConnectionInfo и PluginAction.

Первое, о чём мы вспомним, это то, что наше приложение-хост ищет класс ZigzagPlugin с методом GetComClassName. Сейчас наш класс находится в неймспейсе Plugin3, так что конечное имя класса будет Plugin3.ZigzagPlugin. Можно так же убить неймспейс, как мы это делали в прошлый раз, но давайте тут поступим иначе. Создадим вне пространства имён ещё один класс, в самом низу файла:

public class ZigzagPlugin

{

/// <summary>

/// Возвращает имя COM-класса плагина.

/// </summary>

/// <returns>Строка с именем COM-класса плагина.</returns>

public static string GetCOMClassName()

{

string result = typeof(Plugin3.ZigzagPlugin).FullName;

return result;

}

}

Теперь непосредственно о реализации класса плагина. Так как это будет COM-класс, единственный экспонируемый нашей библиотекой, зададим ему свойство COM-видимости и Guid. Кроме того, пропишем, что он реализует интерфейс IPlugin.

/// <summary>

/// COM-класс плагина для ZigzagServer.

/// </summary>

[ComVisible(true), Guid("9665CD7C-2CF6-4D73-B6C9-1EC865BE0930")]

public class ZigzagPlugin : ZigzagServer.IPlugin

Добавим в класс переменную с ZigzagControl и экземпляр главной формы. Кроме того, напишем пустой конструктор, дабы класс легко было создавать через COM.

object zigzagControl;

MainForm form;

public ZigzagPlugin()

{

}

Добавим пару вспомогательных методов, которые представляют собой вызываемые из плагина действия. Тут у нас их, для разнообразия, два, что гораздо больше, чем одно:).

/// <summary>

/// Отображает форму.

/// </summary>

private void ShowForm()

{

form = new MainForm(zigzagControl);

form.Show();

}

/// <summary>

/// Обновляет данные на форме, загружая их с сервера.

/// </summary>

private void RefreshFormData()

{

if (form != null)

form.RefreshData(zigzagControl);

}

С этим развязались, теперь можно переходить к основной нагрузке класса, реализации интерфейса IPlugin. Заведём регион:

#region IPlugin Members

#endregion

А потом добавим методы, которые будут практически идентичны методам предыдущего плагина. Вот метод подключения:

/// <summary>

/// Осуществляет подключение плагина.

/// </summary>

/// <param name="iZigzagControl">Интерфейс IZigzagControl объекта ZigzagControl.</param>

/// <param name="iPluginConnectionInfo">Интерфейс IPluginConnectionInfo. Передавайте сюда object, плагин должен его инициализировать на своей стороне.</param>

/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>

public int Connect(object iZigzagControl, ref object iPluginConnectionInfo)

{

try

{

this.zigzagControl = iZigzagControl; // Сохраним переменную, дающую контроль над сервером. "Переменная всевластия", ага.

// Получим типы "действие плагина" и "информация подключения плагина".

Type pluginActionType = Type.GetTypeFromProgID("ZigzagServer.PluginAction");

Type pluginConnectionInfo = Type.GetTypeFromProgID("ZigzagServer.PluginConnectionInfo");

List<object> actionsList = new List<object>(); // Создадим список доступных из плагина действий.

//С помощью класса Activator создадим COM-объекты типов по их ProgID, имени.

actionsList.Add(Activator.CreateInstance(pluginActionType, new object[3] { 0, "Показать форму диаграмы", "Отображает форму динамической диаграмы на экране" })); // Добавим туда действия.

actionsList.Add(Activator.CreateInstance(pluginActionType, new object[3] { 1, "Отправить текущие данные на форму", "Актуализирует данные формы" }));

//Аналогичным образом создадим информацию подключения плагина.

iPluginConnectionInfo = Activator.CreateInstance(pluginConnectionInfo, new object[3] { "Zigzag dynamic diagram", "Динамическая диаграма", actionsList.ToArray() });

return 0;

}

catch (Exception exc)

{

System.Windows.Forms.MessageBox.Show(exc.Message + "\r\n" + exc.StackTrace, "Exception occured");

return -1;

}

}

Похоже на предыдущий, не правда ли? Только, разве что, на этот раз мы используем классы с сервера, а не пишем их сами, реализовывая серверные интерфейсы. Мы получаем тип по его имени, так называемому в COM «ProgID», и просим среду создать для нас экземпляр этого типа через статический класс Activator. Активатору мы передаём параметры для конструктора, а он ищет имя в реестре, находит бинарники, где содержится данный класс; опционально загружает их в память, вызывает конструктор нужного класса и возвращает нам инициализированный экземпляр с сервера.

Теперь реализуем метод отключения.

/// <summary>

/// Метод отключения плагина от приложения-хоста.

/// </summary>

/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>

public int Disconnect()

{

try

{

((IDisposable)zigzagControl).Dispose(); // Освободим переменную ZigzagControl, чтобы сервер мог уменьшить счётчик выданных COM-экземпляров.

zigzagControl = null;

form.Close(); // Уничтожим главную форму.

form.Dispose();

form = null;

}

catch

{ }

return 0;

}

Тут всё совсем точь-в-точь, как в первом плагине, даже пояснять не интересно. Переходим к запросу выполнения действия:

/// <summary>

/// Метод выполнения действия плагина. Вызывается приложением-хостом.

/// </summary>

/// <param name="actionId">Числовой уникальный идентификатор действия.</param>

/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>

public int PerformAction(int actionId)

{

switch (actionId)

{

case 0:

ShowForm(); // Отобразить форму.

return 0;

case 1:

RefreshFormData(); // Заставить форму запросить новые данные с сервера.

return 0;

default:

return -1; // Действия с запрошенным actionId не существует. Такие дела.

}

}

Тут тоже всё прозрачно.

Казалось бы, плагин реализован, ан нет. Для него теперь нужно сделать инсталлятор, который будет его регистрировать в COM.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]