Лучший подход к расширяемости типов узлов и контекстных действий в древовидном представлении форм

Я работаю над надстройкой Visual Studio для Visual Studio 2008, которая отображает древовидную структуру, обеспечивающую представление содержимого в серверном продукте. Серверный продукт содержит различные типы узлов, и каждый узел имеет собственный тип контекстного меню (меню, вызываемое правой кнопкой мыши).

Для новых типов узлов и действий, связанных с узлом, я сейчас просто добавляю код во второй проект. Я хотел бы отключить свои типы узлов и действия, доступные на узле, в таком количестве, чтобы я мог добавлять узлы и записи в контекстное меню с моделью плагина. MEF, вероятно, был бы хорошим кандидатом. Есть ли у кого-нибудь хорошая идея о том, как реализовать это простым и понятным способом, чтобы разработчику плагинов не приходилось много заниматься сантехникой?


person Serge van den Oever    schedule 31.05.2009    source источник


Ответы (1)


Я бы предоставил общую библиотеку, на которую ссылаются как ваш код, так и библиотеки плагинов (назовем это зависимостью контракта). Там определите интерфейс для типа узла, например INodeType. Кроме того, рассмотрите возможность реализации здесь AbstractNodeType, который реализует INodeType и предоставляет некоторые полезные свойства, которые автор плагина может установить в своем конструкторе.

Одним из свойств INodeType является свойство ContextMenu, которое возвращает контекстное меню форм Windows.

В вашем коде сделайте свойство:

[Import("NodeTypes", typeof(INodeType))]
public IEnumerable<INodeType> extensionNodeTypes { get; set; }

Вы можете просто перечислить это после того, как сочинили.

В коде плагина они будут объявлять новые типы узлов примерно так (может не компилироваться):

[Export("NodeTypes", typeof(INodeType))]
public class SomeNodeType : AbstractNodeType
{
    public SomeNodeType()
    {
        this.ContextMenu = base.BuildContextMenu(/* ... */);
        /* etc. */
    }
    /* ... other custom logic ... */
}

Надеюсь, я не перепутал синтаксис, но это общая идея.

person Scott Whitlock    schedule 01.06.2009
comment
Боюсь, я еще этого не понимаю. Поддерживает ли этот подход добавление плагинов путем добавления (и регистрации?) просто сборки, или для этого нужна перекомпиляция основного приложения? Что делают [Импорт...] и [Экспорт...]? - person Serge van den Oever; 01.06.2009
comment
Все, что вам нужно сделать, чтобы добавить плагины, это поместить больше DLL в каталог, где ваш код ищет плагины, и он найдет все, что экспортирует это имя контракта (NodeTypes) этого типа (INodeType). Мой ответ предполагает, что у вас есть базовое представление о MEF: codeplex.com/MEF - person Scott Whitlock; 01.06.2009
comment
В этом случае вам придется перезапустить свой код, чтобы он увидел новый плагин, но на этом сайте есть примеры, показывающие, как перекомпоновать, который сможет найти новые плагины без перезапуска. - person Scott Whitlock; 01.06.2009
comment
Привет, Скотт, это была моя проблема :-) Я слышал о MEF, но ничего о нем не знал, поэтому я не понял, что вы говорите в терминах MEF! Я собираюсь погрузиться в это. Большое спасибо! - person Serge van den Oever; 02.06.2009