Visual Studio е създадено с мисълта да бъде настройвано, разширявано и подобрявано от своите потребители. Модулярността е залегнала толкова дълбоко в концепцията на Visual Studio, че Visual Studio поддържа паралелно няколко модела за добавяне на функционалност:

Macros: Автоматизират съществуващи функционалности на Visual Studio (през DTE Automation Model) в една команда. Не са част от Visual Studio от версия 2012, но могат да бъдат добаване като extension (създаден от Microsoft и след това отворен като код в GiHub). В студията до 2010 macro-та се пишеха на Visual Basic, а тези, които могат да се изпълняват от специализараният extension са на JavaScript.

Add-Ins: Добавят нова функционалност имплементирайки интерфейсите на DTE Automation Object Model. Deprecated във версия 2013 и не се поддържат от версия 2015. След версия 2010 се заменят от:

Visual Studio extensions (VSIX): Добавят нова функционалност имплементирайки интерфейсите на DTE Automation Object Model и/или Managed Package Framework (MPF) интерфейсите и/или Managed Extensibility Framework (MEF) интерфейсите.

Таблица: Поддръжка на различните модели за разширяване при различните издания на Visual Studio.

За да станат нещата по-сложни, Visual Studio предлага паралелно и 2 различни инфраструктурни модела, които могат да бъдат имплементирани и разширявани (и комбинирани, за да е по-весело и объркващо):

Non-managed (COM Aggregation):

Регистрират се през IProfferService и се достъпват през IServiceProvider.

EnvDTE Automation Object Model: Имплементирани като COM обвивки върху native елементите на Visual Studio, Automation Object Model предоставя достъп до повечетo функционалности:

  • Проектна система
  • Всички стъпки по Build->Deploy->Debug->Publish пътеката
  • Команди
  • Tool windows
  • Стандартни диалози (MessageBox, Open file/folder dialog, etc.)
  • Стария модел на Language service
  • Няма достъп до Adornment слоя на прозореца на редактора (от VS 2010 пренаписан на WPF и MEF) и функционалности като подчертавки (squiggles), подсказки (smart tags) и други визуални елементи.

Удобен за използване, EnvDTE е изключително труден за custom имплементация, поради факта, че не е модулярен и добавянето на нова проектна система изисква имплементацията на най-основни принципи като: проектът съдържа файлове. Създаването на Language service, който да има по-богат IntelliSense и Code completion, изисква да се почне от най-ниско ниво (Tokenizer, Scanner).

Managed Package Framework (MPF): Друг модел на абстракция върху COM. По-лесен за имплементация, но често е по-труден за използване отвън от EnvDTE.

Managed (MEF):

Регистрират се и се консумират през Composition атрибути ([Export]/[Import]). Основните функционалности достъпни през MEF са:

Интерфейсите на едитора и новият модел на Language service: Изцяло написани на .NET не могат да бъдат достъпвани през COM и респективно през Automation Object Model и MPF.

Common Project System (CPS):

  • Проектната система! (имплементираш само специфичните за твоята проектна система части като Project Properties)
  • Команди
  • Всички стъплки по Build->Deploy->Debug->Publish пътеката
  • Ограничена подръжка на дизайнерски property pages

Тенденцията е COM Aggregation да бъде заменяна от MEF. С всеки етап на обогатяването на MEF инфраструктурата на Visual Studio има все повече функционалности, които се достъпват само през MEF, но не през COM. Процесът обаче е изключително бавен и от VS 2010, когато беше представен новия WPF-базиран редактор и нови функционалности като smart tags и adornments (украшения) като squiggles бяха  възможни само през MEF, едва при даването на достъп на разработчиците до CPS през VS 2017 бяха добавани нови функционалности достъпни само през MEF (https://github.com/Microsoft/VSProjectSystem/blob/ae18f6db87f4d10be2c4dc311f0371fc71d9d3b9/doc/overview/interfaces_NOT_defined_on_IVsProject_object.md).

Ако искате да създадете extension, който да пише в output window или да показва диалози, ще се наложи да комбинирате използването на MEF с MPF или EnvDTE.

За следващите примери, са нужни:

  • Visual Studio 2017 с инсталиран Visual Studio extension development workload
  • Macros for Visual Studio extension

Macro

Macros имат своето място, защото са бързи за писане, познати са от други продукти на Microsoft като Office и не изискват друга инфраструктура за създаване и използване освен Macros for Visual Studio. От друга страна, IntelliSense е ограничен до минимум и намирането на грешки в тях е трудно, тъй като Marcos for Visual Studio не предоставя дебъгер.

Примерът показва macro за премахване на подчертавка в началото на private полета във всички отворени файлове. Други macros могат да бъдат намерени в Macro Explorer (Tools->Macros->Macros Explorer).

VSIX

Имплементирането на extension, който върши същата работа като macro-то изисква значително повече допълнителна инфраструктура: всяка една команда се регистрира на 2 места:

  • Във VSCT файла, където се дефинира позицията на командата във Tool менюто на Visual Studio:

  • Във Package-а, където handler-а на командата се добавя в OleMenuCommandService, който прави връзката между позицията на командата в Tools менюто и handler-а (през CommandId).

Команда за премахване на долната черта в началото на private полета във всички файлове от активния проект (EnvDTE).

Команда за премахване на долната черта в началото на private полета във всички файлове от активния проект (MPF).

Двата примера са показателни за това как консумирането на базови функционалности е по-лесно през Automation Object Model. Също така стават видими разликите на функционално ниво: FindTarget(MPF) от редактора по подразбиране не поддържа  търсене и подменяне на текст в повече от един отворен файл. Това може да бъде имплементирано допълнително в custom редактор.

Следващият пример показва елегантността на MEF. SquiggleTagger подчертава в червено долната черта в началато на името на private полета.  Единствената регистрация е на ITaggerProvider:


Автор:
Александър Хитров

>>> Алекс работи като разработчик на софтуер в Прогрес от юли 2015-а.
>>> От 2008-а предимно се занимава с разработката на екстеншъни за Visual Studio и плъгини за Eclipse.
>>> Програмира професионално от 2005-а година.
>>> Голяма част от свободното си време прекарва в спорт и пътешествия.
>>> С години се опитвал да свири на китара, после на саксофон, а от ранна детска възраст и до сега през няколко години се опитва да рисува.

 


Стани част от потребителските групи на DEV.BG. Абонирай се и ще ти изпращаме информация за всичко, което предстои в групата.

Визия: Личен архив

Прочети още:
Обучение с Утвърждение (Част 1)
Обучение с Утвърждение (Част 2)

Share This