Componenti di un'estensione VisualStudio.Extensibility
Un'estensione che usa VisualStudio.Extensibility include in genere diversi componenti che interagiscono tra loro e anche con Visual Studio.
Istanza dell'estensione
Le estensioni devono avere una classe che deriva da Extension
. Per un'implementazione di esempio, vedere MarkdownLinter.
Un'istanza della Extension
classe è il punto di partenza per l'esecuzione dell'estensione. Questa istanza contiene i metodi necessari per Visual Studio per eseguire query sui servizi forniti dall'estensione. Fornisce inoltre metodi virtuali per l'estensione per fornire risorse localizzate e servizi locali di proprietà dell'estensione da condividere tra i componenti dell'estensione.
La configurazione per la Extension
classe contiene anche i metadati per l'estensione visualizzata nella finestra Gestione estensioni di Visual Studio e, per le estensioni pubblicate, in Visual Studio Marketplace.
[VisualStudioContribution]
public class MarkdownLinterExtension : Extension
{
/// <inheritdoc/>
public override ExtensionConfiguration ExtensionConfiguration => new()
{
Metadata = new(
id: "MarkdownLinter.0cf26ba2-edd5-4419-8646-a55d0a83f7d8",
version: this.ExtensionAssemblyVersion,
publisherName: "Microsoft",
displayName: "Markdown Linter Sample Extension",
description: "Sample markdown linter extension"),
};
...
Per gli sviluppatori di estensioni che hanno familiarità con le API VSSDK esistenti, viene usato per Metadata
ExtensionConfiguration
generare il .vsixmanifest
file. Inoltre, la Extension
classe è simile alla AsyncPackage
classe usata nel modello di estendibilità VSSDK.
Oggetto VisualStudioExtensibility
L'oggetto VisualStudioExtensibility
funge da punto di ingresso per le funzionalità di estendibilità esposte da Visual Studio. Questa classe include vari metodi di estensione, proprietà per enumerare rapidamente le funzionalità disponibili in extensibility SDK. Vedere la documentazione dell'API per i metodi disponibili.
Parti di estensione
Per le funzionalità in cui un'estensione contribuisce ai componenti di Visual Studio, ad esempio comandi, listener dell'editor, le estensioni utilizzeranno classi con attributi. Il processo di compilazione genererà i metadati corretti per assicurarsi che questi componenti possano essere individuati da Visual Studio.
Per le funzionalità in cui un'estensione contribuisce ai componenti di Visual Studio, ad esempio comandi, listener dell'editor, finestre degli strumenti e così via, le estensioni usano classi contrassegnate con l'attributo VisualStudioContribution
. Il processo di compilazione genera i metadati corretti per assicurarsi che questi componenti possano essere individuati da Visual Studio.
Attualmente l'SDK supporta un set limitato di componenti da fornire:
- Gestori dei comandi
- Finestre degli strumenti
- Listener chiusi aperti dalla visualizzazione testo per tenere traccia degli eventi chiusi creati e chiusi.
- Listener di modifiche della visualizzazione testo per tenere traccia delle modifiche apportate a una visualizzazione testo aperta.
- Provider di margini
- Visualizzatori del debugger
Le istanze di queste classi vengono create come parte del framework di estendibilità fornito dall'SDK usando una libreria di inserimento delle dipendenze e i costruttori possono essere usati per recuperare istanze di servizi forniti dall'SDK o dall'estensione stessa per condividere lo stato tra i componenti.
Durata delle parti di estensione
La durata di ogni parte viene gestita dal rispettivo componente che carica tali parti all'interno del processo dell'IDE di Visual Studio.
I gestori comandi vengono inizializzati quando viene attivato il set di comandi corrispondente, che può essere durante la prima esecuzione del comando. Dopo l'attivazione, i gestori comandi devono essere eliminati solo quando l'IDE viene arrestato.
Analogamente, i listener di eventi di visualizzazione testo vengono inizializzati quando la prima visualizzazione testo corrispondente al tipo di contenuto specificato viene caricata nell'IDE. Attualmente, tali listener sono attivi fino a quando l'IDE non viene arrestato, ma questo comportamento potrebbe cambiare in futuro.
In generale, per le estensioni complesse è consigliabile che le estensioni forniscano servizi locali che le parti possono importare nel costruttore e che usano tali servizi per condividere lo stato tra parti e tra istanze della stessa parte. Questa procedura garantisce che lo stato dell'estensione non sia influenzato dalle modifiche di durata delle parti di estensione.
Servizi forniti dall'SDK per l'inserimento
I servizi seguenti vengono forniti dall'SDK che possono essere usati nel costruttore per qualsiasi parte di estensione:
VisualStudioExtensibility
: ogni parte di estensione può inserire un'istanza di per interagire con l'IDE diVisualStudioExtensibility
Visual Studio.Extension
: le parti possono inserireMicrosoft.VisualStudio.Extensibility.Extension
il tipo o le estensioni di un tipo che ereditano da esso alle parti di estensione.TraceSource
: viene creata un'istanza dell'origine di traccia su richiesta per ogni estensione che può essere usata per registrare le informazioni di diagnostica. Queste istanze vengono registrate con il provider di diagnostica di Visual Studio che può essere usato per unire i log da più servizi e usare strumenti futuri per accedere alla registrazione in tempo reale. Vedere Registrazione.Servizi locali: tutti i servizi locali forniti dall'estensione stessa saranno disponibili anche per l'inserimento delle dipendenze.
MefInjection<TService>
eAsyncServiceProviderInjection<TService, TInterface>
: le estensioni in-proc possono inserire servizi di Visual Studio SDK che vengono tradizionalmente utilizzati tramite MEF o AsyncServiceProvider.
Servizi di estensione locali
In alcuni scenari, un'estensione potrebbe voler condividere lo stato tra diversi componenti, ad esempio un gestore dei comandi e un listener di modifica della visualizzazione testo, come illustrato nell'esempio MarkdownLinter
. Questi servizi possono essere aggiunti alla raccolta di servizi in-process eseguendo l'override del metodo e man mano Extension.InitializeServices
che vengono create istanze di parti di estensione, i servizi vengono inseriti in base agli argomenti del costruttore.
Sono disponibili tre opzioni per l'aggiunta di un servizio:
AddTransient
: viene creata una nuova istanza del servizio per ogni parte che lo inserisce.AddScoped
: una nuova istanza del servizio viene creata all'interno di un determinato ambito. Nel contesto dell'estendibilità di Visual Studio, l'ambito fa riferimento a una singola parte di estensione.AddSingleton
: è presente una singola istanza condivisa del servizio creata al primo inserimento.
A causa della durata dell'oggetto VisualStudioExtensibility
associato all'ambito di una singola parte di estensione, qualsiasi servizio locale che lo inserisce deve essere un servizio temporaneo o con ambito. Il tentativo di creare un servizio singleton che inserisce VisualStudioExtensibility
genererà un errore.
Per un esempio di utilizzo dei servizi locali, vedere Estensione MarkdownLinter.
Contesto client
Poiché tutte le estensioni nel nuovo SDK eseguono il processo, viene introdotto il concetto di contesto client per varie parti di estensione per rappresentare lo stato dell'IDE al momento in cui viene richiamato l'evento o il metodo. Questo contesto è rappresentato dall'istanza dell'SDK IClientContext
e viene passato a varie operazioni, ad esempio i gestori di esecuzione dei comandi. L'SDK fornisce metodi di estensione su IClientContext
che possono essere utilizzati per recuperare oggetti dal contesto. Ad esempio, le estensioni possono ottenere la visualizzazione testo attiva o l'URI per gli elementi selezionati al momento dell'esecuzione del comando usando l'istanza IClientContext
.
Alcuni componenti, ad esempio i comandi, consentono anche di dichiarare quali contesti sono interessati. Questa operazione viene eseguita per ottimizzare la quantità di dati trasferiti in ogni esecuzione remota, perché il contesto client può ottenere grandi dimensioni in futuro. Nell'anteprima iniziale sono disponibili solo due contesti Shell
e Editor
, e entrambi sono inclusi per impostazione predefinita quando si dichiara un comando usando CommandAttribute
.