Re: Приложение с плагинами
От: Andrew Merkulov Россия www.ibprovider.com
Дата: 21.07.06 08:05
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Нужно сделать следующее: есть приложение, где форма оформленна для MDI. Есть директория, кде находятся сборки. Приложения должно просматривать всю директорию и загружать находящиеся там сборки. Сборки должны добавлять на главную форму свои пункты меню, и кнопки на панель инструментов.И дальше уже при выборе нужных пунктов меню, должны вызывать функции и показываться формы находящиеся в сборках.


А>Как это реализовать?

А>Скажите, в какую сторону копать?

Подключаем сборки через Reflection
1. Загружаем сборку
/// <summary>
        /// Кеш загруженных сборок
        /// </summary>
        /// <param name="AssemblyFileName"></param>
        /// <returns></returns>
        private static Assembly GetAssembly(string AssemblyFileName)
        {
            if(AssemblyDictionary==null) AssemblyDictionary=new ListDictionary(); 
            
            if(AssemblyDictionary.Contains(AssemblyFileName))
                return AssemblyDictionary[AssemblyFileName] as Assembly;
            else
            {
                //проверка наличия файла
                if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + @"Plugins\" + AssemblyFileName))
                {
                    Debuger.LogDebug( "Не удалось найти плагин " + AppDomain.CurrentDomain.BaseDirectory + @"Plugins\" + AssemblyFileName,null,AM.Messaging.MessageType.Error);
                    return null;
                }
                //загружаем сборку плагина в этот домен
                Assembly ass = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + @"Plugins\" + AssemblyFileName); 
                 
                if(ass!=null)
                    AssemblyDictionary.Add(AssemblyFileName,ass);
                return ass;
            }
        }


2. Создаем экземпляр заданного класса в сборке
/// <summary>
        /// Загружает из заданной сборки заданный тип
        /// </summary>
        /// <param name="RequiredType">Имя файла сборки без указания пути</param>
        /// <param name="ConstructorArguments">Имя файла сборки без указания пути</param>
        /// <param name="AssemblyFileName">Имя файла сборки без указания пути</param>        
        public static object LoadInstanceOf(Type RequiredType, object[] ConstructorArguments, string AssemblyFileName)
        {            
            Assembly ass = GetAssembly(AssemblyFileName); if(ass==null) return null;
            
            try
            {
                //ищем входной объект плагина
                foreach (Type type in ass.GetTypes())
                {
                    if(type.BaseType == RequiredType)
                    {                        
                        //Создаем экземпляр класса
                        return Activator.CreateInstance(type,ConstructorArguments);                          
                    }
                }
                return null;
    
            }
            catch (Exception ex) //перехватываем исключения в плагинах
            {
                .......                
            }
            return null;
        }

        #endregion


Теперь по общим вопросам.
1. Я разделяю в плагине сборки конфигурацию (PluginConfiguration) и формы (PluginForm). Когда главная форма загружает необходимый плагин она загружает конфигурацию которая предоставляет информацию основной форме к примеру

PluginConfigurationInstance.GetMenuItems(MenuItemCategory.File);
PluginConfigurationInstance.GetToolBars();

и соответственно главная MDI форма выстраивает свои меню и тулбары в соответствии с данными полученными из PluginConfiguration.

2. Каждому пункту меню и кнопке тулбара в плагине соответствует некая PluginCommand (см паттерн Command). Она управляет доступностью элементов меню и кнопок в определенный момент а так же выполняет действие внутри плагина при нажатии пункта меню(кнопки тулбара)

В итоге как мне кажеться получается достаточно слабое связывание.

При добавлении дочерних форм PluginForm, PluginConfiguration посылает событие основной форме и та уже устанавливает себя в качестве родительской PluginForm

Это если вкратце


А>Зарание большое спасибо!


Немного обо мне, и моем круге
Мои профиль в LiveLib &mdash; книги
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.