Приложение на основе плагинов в C # - PullRequest
9 голосов
/ 25 июня 2009

Мне нужно создать приложение с графическим интерфейсом, используя выбранный язык. Приложение будет работать на Windows XP. Это будет своего рода сложное приложение для Windows. Я думаю, и в соответствии с большинством предложений, C # будет лучшим для использования. Древовидная структура слева от графического интерфейса будет заполняться после чтения из файла конфигурации, который будет двоичным файлом. (но изначально я могу работать с простым файлом ASCII, чтобы проверить мой код.). Приложение примет некоторые входные данные от пользователя через этот графический интерфейс и запишет обратно в тот же файл конфигурации и отразит изменения в древовидной структуре или метках или любом другом соответствующем поле в форме.

Для каждой вкладки будет 3 вкладки и 3 соответствующих файла конфигурации. Мне нужна помощь в разработке приложения на данный момент. Я планирую сделать хост-приложение (основное приложение) и использовать 3 вкладки в качестве плагинов. Это работоспособно? Если да, можете ли вы направить меня на это Я имею в виду, как мне сделать 3 плагина в C # и как написать интерфейс, чтобы основное приложение знало, какой плагин загрузить и когда его загрузить? Будет ли в папке моего проекта отдельная папка «Плагин»? Я надеюсь, что вы поняли мою точку зрения, хотя для вас эта информация слишком мала для начала.

Также в проекте уже есть некоторые файлы .cpp. Эти файлы вместе с некоторыми файлами .h содержат некоторые важные определения и константы. Они должны быть интегрированы с моим приложением C #. Я понятия не имею, как это сделать, но я уверен, что это возможно, скомпилировав код .cpp в .dll, а затем предоставив скомпилированный .dll моему приложению C #. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация для дизайна верхнего уровня.

Спасибо, Viren

Ответы [ 5 ]

13 голосов
/ 25 июня 2009

Чтобы реализовать интерфейс плагина вручную, вам понадобится такой метод. Я оставил некоторые TODO, где вы захотите улучшить обработку ошибок и / или сделать реализацию немного более специфичной для конкретного случая.

    public List<T> LoadPlugin<T>(string directory)
    {
        Type interfaceType = typeof(T);
        List<T> implementations = new List<T>();

        //TODO: perform checks to ensure type is valid

        foreach (var file in System.IO.Directory.GetFiles(directory))
        {
            //TODO: add proper file handling here and limit files to check
            //try/catch added in place of ensure files are not .dll
            try
            {
                foreach (var type in System.Reflection.Assembly.LoadFile(file).GetTypes())
                {
                    if (interfaceType.IsAssignableFrom(type) && interfaceType != type)
                    { 
                        //found class that implements interface
                        //TODO: perform additional checks to ensure any
                        //requirements not specified in interface
                        //ex: ensure type is a class, check for default constructor, etc
                        T instance = (T)Activator.CreateInstance(type);
                        implementations.Add(instance);
                    }
                }
            }
            catch { }
        }

        return implementations;
    }

Пример вызова:

List<IPlugin> plugins = LoadPlugin<IPlugin>(path);

Что касается c ++ части вашего вопроса. Есть несколько разных способов подойти к этому, хотя правильный выбор зависит от вашей конкретной ситуации. Вы можете создать CLR-совместимый .dll в c ++, на который ваш c # проект мог бы ссылаться и вызывать, как и любой другой .dll, на который он ссылается. Кроме того, вы можете использовать P / Invoke для вызова собственного .dll.

8 голосов
/ 25 июня 2009

Одной из самых простых концепций плагинов, которые я когда-либо использовал, была, безусловно, Managed Extensibility Framework , которая будет частью .NET 4 (afaik).К сожалению, он еще не закончен, и доступен только предварительный просмотр, который может отличаться от финальной версии.Тем не менее, мы использовали MEF Preview 3 для универсального проекта, и он работал без проблем, и это, безусловно, значительно облегчило работу всего плагина.

3 голосов
/ 25 июня 2009

Посмотрите на пространство имен System.Addin: http://msdn.microsoft.com/en-us/library/system.addin.aspx

В противном случае вы можете сделать все сами. До того, как это пространство имен стало доступно, я использовал общий интерфейс «IPlugin», который должен был использовать каждый плагин / надстройка. Затем у меня был загрузчик, который проверял все * .dll в папке, а затем использовал отражение для проверки интерфейса. Затем я мог бы создавать экземпляры классов, в которых реализован мой интерфейс плагина / надстройки

Файлы cpp, вероятно, потребуется преобразовать в c #, или вы можете создать dll для ссылки.

1 голос
/ 25 июня 2009

Взгляните на Замок .

0 голосов
/ 25 июня 2009

.NET Framework использует модель COM в своих силах. Смотрите http://blog.caljacobson.com/2007/07/26/creating-a-plug-in-framework-in-c-resources/ для списка примеров плагинов, использующих эту технику.

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