Password
    
 К титульной странице  |  Форум  |  О проекте  |  Поиск товаров  |  Сделать стартовой  |  Добавить в Избранное   
Авторизация
Забыли пароль?
Регистрация 
 
Программирование
Безопасность
Демосцена
Игры
WEB-мастерская
Программное обеспечение
Аппаратное обеспечение

Webshop Search

Последние материалы
  The Chronicles of Riddick: Escape from Butcher bay

  Что такое хорошо и что такое плохо, или FAQ по LCD-мониторам

  Организация удаленного доступа

  Инсталляция программного обеспечения используя GPO

  Smarty в веб-разработке

  BioShock или кафе разбитых надежд...



Последние новости
  Конференция Разработчиков Видеоигр, 1979

  Более шустрый и динамичный Mail.lv

  Интернет магазин даром

  Price-Less.eu совсем скоро будет искать на латышском

  Запущена первая публичная бета версия поисковой системы товаров Price-Less.eu

  В Google создали инструмент для борьбы с детской порнографией



Charitable advertising
Њл ­г¦¤ Ґ¬бп ў ў иҐ© Ї®¬®йЁ!



Ziedot.lv

Penn State Child Life Program



Программирование --> C/C++
Пишем приложения с плагинами на платформе .NET
  
Автор: Cybersecurity.ru
Источник:www.cybersecurity.ru
Опубликовано: [2006-11-15 00:21]
Если вы снабдите своё приложение возможностью понимать плагины, то обеспечите себе возможность изменить часть функциональности такого приложения безперекомпиляции, а не путём полной перекомпиляции этого приложения, как это делается обычно. И хотя не все приложения нуждаются в этом, такая возможность все же иногда является нелишней. Это руководство будет наследником того, которое я писал для программистов приложений, написанных на VB6 с использованием COM. По-моему, на .NET это сделать немного легче, чем на COM, и результат получается гораздо более впечатляющим. Например, для отображения интерфейса COM-плагина в диалоговом окне приложения-хоста было похоже на кошмар и требовало немалой изобретательности. Однако в .NET это достаточно тривиальная задача, благодаря архитектуре Windows Forms. Скажу также, что процедуры открытия и исследования DLL в .NET очень похожи.

Код к статье : Демонстрационный проект на VB - http://www.divil.co.uk/net/articles/plugins/pluginssample.zip

Архитектура плагинов

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

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

Пишем интерфейсы

Сначала создадим проект типа Class Library и определим в нём 2 простых интерфейса. Каждый плагин будет иметь свойство с именем плагина и функцией, принимающей 2 целых числа и возвращающих число типа double . Главное приложение будет содержать такой метод, с помощью которого плагин сможет отобразить окно с сообщением в этом приложении. При создании нового проекта типа Class Library, мы по умолчанию получим в нём уже готовый класс. Его нужно удалить и определить интерфейс:

using System; 
namespace hDrummer.clInterfaces { 
/// <summary> 
/// IPlugin 
/// </summary> 
public interface IPlugin 
{ 
void Initialize(IHost host); 
string Name { get; } 
double Calculate(int i1, int i2); 
} 
/// <summary> 
/// IHost 
/// </summary> 
public interface IHost { 
void ShowFeedBack(string strFeedBack); 
} 
} 

И наконец установим выходную директорию для этой библиотеки в общий каталог, в который поместим приложение и плагины.

Пишем первый плагин

Поскольку для целей тестирования нам нужен хотя бы один плагин, то и займёмся его написанием. Снова создаем проект типа Class Library, устанавливаем директорию для вывода и создаём ссылку на нашу предыдущую библиотеку. Затем меняем предлагаемый класс следующим образом:

using System;
using hDrummer.clInterfaces;

namespace hDrummer.PluginLibrary
{
/// <summary>
/// Plugin class
/// </summary>
public class PluginSample: clInterfaces.IPlugin
{
private clInterfaces.IHost objHost;
public void Initialize(IHost host)
{
objHost = host;
}
public string Name 
{
get 
{
return "PluginSample1 - Adds two numbers";
}
}
public double Calculate (int i1, int i2)
{
return i1+i2;
}
}
} 

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

Пишем приложение-хост

Создадим новый проект типа Windows Application. Первым делом добавим ссылку на только что созданную библиотеку классов и установим выходную директорию в ту же, что и для библиотеки классов (это делается в свойствах проекта-Configuration Properties-Build-Output Path - прим. переводчика.). Существенной частью данной статьи явлется процесс исследования DLL на предмет наличия плагинов, хранение информации о том, какие плагины доступны, инициализация и дальнейшее их использование. Для этого мы создадим класс в файле PluginServices.vb, который инкапсулирует все эти вещи. Для получения списка плагинов используем функцию FindPlugins, которая принимает строку, содержащую каталог для поиска плагинов; строку, содержащую имя интерфейса, по которой мы будем искать классы, реализующие его функциональность. Эта функция перебират все файлы с расширением .dll в указанном каталоге, загружает их с помощью метода Assembly.LoadFrom() и передаёт выполнение другой функции для инспектирования сборки.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.IO;

namespace HostApplication
{
public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

public AvailablePlugins[] FindPlugins(string strPath, string strInterface)
{
ArrayList Plugins = new ArrayList();
string[] strDLLs;
Assembly objDLL;

strDLLs = Directory.GetFileSystemEntries(strPath, "*.dll");
for (int intIndex=0;(intIndex<strDLLs.Length-1);intIndex++)
{
try 
{
objDLL = Assembly.LoadFrom(strDLLs[intIndex]);
ExamineAssembly(objDLL, strInterface, Plugins);
}
catch (Exception ex) 
{
//ошибка загрузки DLL - мы тут ничего не делаем
}
}
// тут надо посмотреть объявление переменной в VB проекте
//AvailablePlugin Results[Plugins.Count-1];
if (Plugins.Count!=0) 
{
Plugins.CopyTo(Results);
return Results;
} 
else {return null;}

}
public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null) 
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
private void InitializeComponent()
{
// 
// Form1
// 
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(488, 273);
this.Name = "Form1";
this.Text = "Form1";

}
#endregion
[STAThread]
static void Main() 
{
Application.Run(new Form1());
}
} } 

Как только все файлы проверены и исследованы, функция возвращает массив типа AvailablePlugin, если что-то найдено, или null, если не найдено ничего. Как видим, функция ExamineAssembly проверяет загруженные сборки. Функция ExamineAssembly перебирает все типы, экспортируемые сборкой, и использует метод GetInterface() для каждого из них, проверяя, не реализует ли он наш интерфейс. Конечно же, в метод передаётся строка, содержащая полностью квалифицированное имя интерфейса. В нашем случае это PluginSample.Interfaces.IPlugin . Если такой тип найден, то ссылка на него добавляется к нашей переменной класса ArrayList, в ней хранится полный путь к DLL и полное имя класса.

private static ExamineAssembly(Assembly objDLL, string strInterface, ArrayList Plugins){
Type objType;
Type objInterface;
AvailablePlugin Plugin;

//Цикл по всем типам в DLL
foreach (objType in objDLL.GetTypes()){
//Смотрим только типы public
if (objType.IsPublic == true) {
//игнорируем абстрактные классы
if ((objType.Attributes And TypeAttributes.Abstract) != 
TypeAttributes.Abstract){
//Смотрим, реализует ли этот тип наш интерфейс
objInterface = objType.GetInterface(strInterface, true);
if (objInterface != null){
Plugin = new AvailablePlugin();
Plugin.AssemblyPath = objDLL.Location;
Plugin.ClassName = objType.FullName;
Plugins.Add(Plugin);
}
}}}} 

Наконец, напишем функцию, которая создаст экземпляр необходимого плагина. Она принимает структуру AvailablePlugin и возвращает оbject, который нужно привести к определённому типу в вызывающей процедуре.

public static object CreateInstance(AvailablePlugin Plugin){ 
Assembly objDLL;
object objPlugin;

try {
//Загружаем dll
objDLL = Assembly.LoadFrom(Plugin.AssemblyPath);

//создаём и возвращаем экземпляр класса
objPlugin = objDLL.CreateInstance(Plugin.ClassName);
}
catch (Exception e){return null;}
return objPlugin;
}} 

Вот и всё о файле PluginServices.vb. Всё остальное дотаточно просто. В методе Main мы вызываем метод FindPlugins и заполняем с его помощью список на форме. Пользователь может выбрать какой-то плагин из этого списка, а также имеет возможность выбора двух чисел, запуска плагина и получения результата. Однако, ещё необходимо реализовать класс в приложении-хосте. Класс, который реализует интерфейс IHost и предложит плагинам способ для вызова методов приложения-хоста. В нашем случае такой метод просто отображает диалоговое окно с сообщением.. Я не стану дальше расписывать код приложения, в надежде, что код сам всё расскажет за себя. Однако стоит заметить, что в этом приложении мы всякий раз, при необходимости вычислений, создаём экземпляр плагина, хотя обычно время жизни такого экземпляра должно быть гораздо больше.

Ещё один плагин

Попробуем создать ещё один плагин, перемножающий два числа. Этот плагин будет перемножать два числа. Он также будет использовать интерфейс для отображения результата в диалогов окне. Код находится в папке [Plugin 2]. Вот и всё. Код к данному руководству у вас есть, так что можете использовать файл PluginServices.vb в своих приложениях. В модификациях он не нуждается.
Прим. переводчика: Скачайте проект на VB, чтобы посмотреть код целиком. Ссылка на него - в заголовке статьи.

Вот и всё, удачного программирования!





Перейти к рубрике --> C & C++

Наши друзья
Juridiskie pakalpojumi  
IT Works
Проект Самоучка Codenet - всё для программиста
Скачать программы, игры Бесплатные электронные книги
• Hi-tech NEWS • InCube e-mag
ZONEHOSTER.com Программисты, Вам сюда!
КомментарииВсего:0


Только зарегистрированные пользователи могут оставлять здесь комментарии. Зарегистрироваться можно здесь. Если вы уже зарегистировались ранее, то можете войти в систему здесь.


© Mihail Chernov (MiHack) Обмен ссылками
Видеотехника
  *Видеокамеры
  *DVD проигрыватели
  *Телевизоры и аксессуары
Телефония и cвязь
  *Радиотелефоны
  *Портативные радиостанции
  *Смартфоны
  *Мобильные телефоны
Программное обеспечение
  *Компьютерные игры
  *Прикладное ПО
  *Электронные издания
Автопринадлежности
  *Автомагнитолы
  *Автозапчасти
Одежда и обувь
  *Женская
  *Мужская
Бытовая техника
  *Холодильники
  *Стиральные машины
  *Микроволновые печи
  *Посудомоечные машины
  *Пылесосы
  *Кондиционеры
  *Электрические и газовые плиты
  *Водонагреватели и бойлеры
  *Прочее
Спорт и туризм
  *Тренажёры
  *Спорт инвентарь
Компьютеры
  *Офисная техника
  *Мониторы
  *Персональные компьютеры
  *Ноутбуки
  *Серверы
  *Сетевое оборудование
  *Игровые консоли
  *Аксессуары
Фототехника
  *Фотоаппараты
  *Аксессуары
Детские товары
  *Игрушки
  *Детские коляски
  *Детские автокресла
  *Всё для детской комнаты
Аудиотехника
  *MP3 плееры
  *Музыкальные центры
  *CD-проигрыватели
  *Наушники и микрофоны
  *Радио тюнеры
  *Усилители
  *Аккустические системы
  *Запись звука
Сантехника и отопление
  *Ванна и туалет
  *Отопление
  *Котлы
  *Насосы
Для дома и сада
  *Мебель
  *Для сада и огорода
  *Для строительства и хозяйства
Красота и здоровье
  *Косметические средства
  *Маникюр
  *Массажёры
  *Эпиляторы
-->