Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание plagin на С#, Создание plagin на С# 
:(
    Опции темы
greyc
Дата 26.2.2009, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 25.9.2007

Репутация: нет
Всего: нет



Ножно создать plugin на C#. Подскажите как сделать простенький плагин, или пример какого-нибудь плагина. Помогите пожалуйста!!!
PM MAIL   Вверх
Partizan
Дата 26.2.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 18
Всего: 67



greyc, плагин к чему?


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
archeg
Дата 27.2.2009, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



Рефлекшином подтягиваешь сборку, вытягиваешь нужные тебе интерфейсы - вызываешь соотв. методы. Кажись были какие-то либы для этого


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
Linus
Дата 27.2.2009, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.8.2006
Где: Украина

Репутация: 1
Всего: 4



А можно заюзать IoC контейнер, например Castle Project (MicroKernel или Windsor), или другие контейнеры.

Это сообщение отредактировал(а) Linus - 27.2.2009, 10:00
PM MAIL ICQ   Вверх
greyc
Дата 10.3.2009, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 25.9.2007

Репутация: нет
Всего: нет



Цитата(Partizan @ 26.2.2009,  08:44)
greyc, плагин к чему?

 к клиенту, написанному на с#.

Добавлено через 2 минуты и 38 секунд
Цитата(archeg @ 26.2.2009,  22:28)
Рефлекшином подтягиваешь сборку, вытягиваешь нужные тебе интерфейсы - вызываешь соотв. методы. Кажись были какие-то либы для этого

а как это сделать, можт есть ссылки на хорошую теорию по этому? нет примерчика простенького?
PM MAIL   Вверх
Partizan
Дата 10.3.2009, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 18
Всего: 67



greyc, если клиент поддерживает плагины, значит у него должен быть какой-то открытый API для написания плагинов


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
-Mikle-
Дата 10.3.2009, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 17
Всего: 59



Если клиент на С# написан тобой, то объявляй интерфейсы.
Ты не сказал что ты пишешь, поэтому я возьму, например, калькулятор. Конечно калькулятор, поддерживающий плигины, это что-то, но смысл думаю будет понятен.

Итак, в программе у тебя есть классы, которые отвечают за вычисления. Один класс - один тип вычисления. Все они имеют одинаковый интерфейс:
Код

interface ICalc
{
    double Calculate(double x, double y);

    string Title { get; }
    string Description { get; }
}

// одна из реализаций интерфейса:
public class PlusCalc : ICalc
{
    public double Calculate(double x, double y)
    {
        return x + y;
    }
    
    public string Title { get { return "+"; } }
    public string Description { get { return "сложение"; } }
}


Сразу видно, что при такой реализации калькулятора, дополнительные типы вычислений будут добавлятся путем написания наследников от ICalc.
Теперь надо выделить ICalc в отдельную сборку (PluginBase.dll), чтобы другие плагины могли иметь к ней доступ. После этого, мы можем писать сколько угодно dll'ок, которые будут содержать классы наследумые от ICalc, находящийся в PluginBase.dll

Далее. При загрузке калькулятора проводим сканирование папки на предмет поиска реализации интерфейса ICalc и загружаем:
Код

        private List<ICalc> LoadPlugins(string pluginFolder)
        {
            List<ICalc> plugins = new List<ICalc>();
            string[] assemblyNames = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);

            foreach (string fileName in assemblyNames)
            {
                Assembly assembly = Assembly.LoadFile(fileName);
                Type[] allPublicTypes = assembly.GetExportedTypes();
                foreach (Type type in allPublicTypes)
                    if (type.IsSubclassOf(typeof(ICalc)))
                        plugins.Add((ICalc)Activator.CreateInstance(type));
            }

            return plugins;
        }


Метод LoadPlugins вернет список уже созданных объектов-наследников ICalc, из всех dll  в указаной папке.
Ну а дальше уже дело техники. Можно, например, сделать так:
Код

        private void CreateCalcButtons()
        {
            List<ICalc> icalcList = LoadPlugins(Path.Combine(Application.StartupPath, "plugins"));
            foreach (ICalc icalc in icalcList)
            {
                Button btn = new Button();
                btn.Tag = icalc;
                btn.Text = icalc.Title;
                btn.Click += new EventHandler(btnCalc_Click);
                flowLayoutPanel1.Controls.Add(btn);
            }
        }


Надеюсь этот простой пример поможет вам.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
greyc
Дата 10.3.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 25.9.2007

Репутация: нет
Всего: нет



Цитата(Partizan @ 10.3.2009,  09:14)
greyc, если клиент поддерживает плагины, значит у него должен быть какой-то открытый API для написания плагинов

клиента надо мне написать. Клиента, что бы поддерживал все основные функции Subversion (svn). есть уже готовые такие клиенты http://sharpsvn.open.collab.net/ мне надо катого же, только немного модернизированного

Добавлено через 2 минуты и 6 секунд
Цитата(-Mikle- @ 10.3.2009,  09:40)
Если клиент на С# написан тобой, то объявляй интерфейсы.
Ты не сказал что ты пишешь, поэтому я возьму, например, калькулятор. Конечно калькулятор, поддерживающий плигины, это что-то, но смысл думаю будет понятен.

Итак, в программе у тебя есть классы, которые отвечают за вычисления. Один класс - один тип вычисления. Все они имеют одинаковый интерфейс:
Код

interface ICalc
{
    double Calculate(double x, double y);

    string Title { get; }
    string Description { get; }
}

// одна из реализаций интерфейса:
public class PlusCalc : ICalc
{
    public double Calculate(double x, double y)
    {
        return x + y;
    }
    
    public string Title { get { return "+"; } }
    public string Description { get { return "сложение"; } }
}


Сразу видно, что при такой реализации калькулятора, дополнительные типы вычислений будут добавлятся путем написания наследников от ICalc.
Теперь надо выделить ICalc в отдельную сборку (PluginBase.dll), чтобы другие плагины могли иметь к ней доступ. После этого, мы можем писать сколько угодно dll'ок, которые будут содержать классы наследумые от ICalc, находящийся в PluginBase.dll

Далее. При загрузке калькулятора проводим сканирование папки на предмет поиска реализации интерфейса ICalc и загружаем:
Код

        private List<ICalc> LoadPlugins(string pluginFolder)
        {
            List<ICalc> plugins = new List<ICalc>();
            string[] assemblyNames = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);

            foreach (string fileName in assemblyNames)
            {
                Assembly assembly = Assembly.LoadFile(fileName);
                Type[] allPublicTypes = assembly.GetExportedTypes();
                foreach (Type type in allPublicTypes)
                    if (type.IsSubclassOf(typeof(ICalc)))
                        plugins.Add((ICalc)Activator.CreateInstance(type));
            }

            return plugins;
        }


Метод LoadPlugins вернет список уже созданных объектов-наследников ICalc, из всех dll  в указаной папке.
Ну а дальше уже дело техники. Можно, например, сделать так:
Код

        private void CreateCalcButtons()
        {
            List<ICalc> icalcList = LoadPlugins(Path.Combine(Application.StartupPath, "plugins"));
            foreach (ICalc icalc in icalcList)
            {
                Button btn = new Button();
                btn.Tag = icalc;
                btn.Text = icalc.Title;
                btn.Click += new EventHandler(btnCalc_Click);
                flowLayoutPanel1.Controls.Add(btn);
            }
        }


Надеюсь этот простой пример поможет вам.

Большое спасобо за помощь) а то не понятно было с чего начинать!)
PM MAIL   Вверх
jonie
Дата 10.3.2009, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



в представленном примере есть большие проблемы (если переносить его будете на промышленное производство).
1) надо проверять на .net сборку хотябы (я не говорю про валидность самого файла хотябы), например так:
Код

        /// <summary>
        /// проверка на то что указанный файл .net assembly
        /// см. http://geekswithblogs.net/rupreet/archive/2005/11/02/58873.aspx
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        internal static bool IsAssembly(string filename)
        {
            bool rv = false;    //false by default
            try
            {
                if (!File.Exists(filename)) return false;

                using (Stream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryReader reader = new BinaryReader(fs))
                    {
                        fs.Position = 0x3C;
                        fs.Position = reader.ReadUInt32() + 120 + (14*8);
                        rv = (reader.ReadUInt32() != 0);
                    }
                }
            }
            catch { /* do nothing, rv already set to false */ }

            return rv;
        }
    }


2) нужно грузить предварительно сборку в другой домен, т.к. она будет висеть в примере в памяти, и выгрузить ее не удасться "законно" (подробнее гугл расскажет по словам CreateInstanceAndUnwrap, AppDomain.CreateDomain)



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
-Mikle-
Дата 11.3.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 17
Всего: 59



jonie, спасибо за коррективы. Просто я не претендовал на промышленный вариант, а только лишь показать общий принцип. Тем не менее, спасибо за код проверки IsAssembly, я никогда об этом на задумывался полагаясь на Exception.

Был бы Вам благодарен, если б вы пояснили, что находится по указанным в коде смещениям и константы 120, 14 и 8:
Цитата(jonie @  11.3.2009,  01:43 Найти цитируемый пост)
fs.Position = 0x3C;
                        fs.Position = reader.ReadUInt32() + 120 + (14*8);
                        rv = (reader.ReadUInt32() != 0);




--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.