Как создать пользовательскую точку расширения в плагине ReSharper

Мы работаем над плагином для ReSharper и хотим сделать наш плагин расширяемым. Кажется, мы должны использовать атрибут ShellComponent, чтобы сделать это, но мы не можем найти никаких примеров. Может ли кто-нибудь понять, как определить пользовательскую точку расширения и как управлять расширением. Пример кода точки расширения и реализации расширения был бы очень полезен.

Спасибо.


person gsv    schedule 09.09.2014    source источник


Ответы (1)


Если вы хотите написать плагин, который может расширять ReSharper, вам нужно сообщить ReSharper о классах в вашем плагине, пометив их атрибутами [ShellComponent] или [SoutionComponent]. Эти атрибуты имеют разное время жизни: компонент оболочки длится столько же, сколько и сам ReSharper, а компонент решения создается при открытии решения и удаляется при закрытии решения.

Чтобы заставить ReSharper делать что-то полезное с вашими компонентами, им обычно приходится реализовывать интерфейс, такой как ICodeCompletionItemsProvider, а иногда приходится использовать другой атрибут, например [CodeCleanupModule] (который сам является производным от ShellComponentAttribute). В ReSharper есть много точек расширения, и та, которая вам подходит, зависит от того, что вы пытаетесь сделать — рефакторинг, поставщик модульных тестов, очистка кода, элементы завершения кода и т. д. devguide представляет собой хорошее введение в более распространенные точки расширения.

Но если вы хотите сделать свой собственный плагин расширяемым, тогда ваш компонент должен работать с неким шаблоном провайдера, перекладывая работу на несколько экземпляров провайдера. Например, очистка кода работает, откладывая несколько модулей очистки кода, каждый из которых отвечает за очистку различных аспектов вашего кода (пробелы, порядок и т. д.). Для этого ваш компонент должен принимать набор провайдеров в конструкторе. Компонентная модель ReSharper автоматически создаст коллекцию этих типов и передаст их. В частности, у вас должен быть конструктор, который принимает IEnumerable<T> или IViewable<T>, где T — это интерфейс провайдера, который вы собираетесь определить и вызвать. IEnumerable<T> предоставит вам простую коллекцию провайдеров, а IViewable<T> представляет наблюдаемую коллекцию и позволит вам подписаться на уведомления о новых провайдерах, доступных из модели компонентов.

person citizenmatt    schedule 10.09.2014
comment
Привет Citizenmatt Спасибо за ответ. Мы хотим сделать наш плагин расширяемым. Не могли бы вы предоставить более подробную информацию. Как мы должны определить точку расширения в нашей точке и как мы должны определить расширения для нее. Пусть мы хотим описать MyExtensionPoint. Он должен иметь конструктор, который принимает IViewable‹IMyExtension› Должен ли он быть помечен каким-либо атрибутом? Далее, когда мы определяем расширение, оно должно реализовывать IMyExtension. Должно ли расширение быть помечено атрибутом? - person gsv; 11.09.2014
comment
Ага. Именно это. ReSharper объединяет все типы, отмеченные [ShellComponent] или [SolutionComponent]. Если у вас есть параметр конструктора с IViewable<T>, он найдет все компоненты, реализующие T, и передаст их вам. Таким образом, ваш класс T должен быть помечен как компонент, а T должен быть просто общим интерфейсом, который может реализовать любой. - person citizenmatt; 11.09.2014