Partage via


Composants d’une extension VisualStudio.Extensibility

Une extension utilisant VisualStudio.Extensibility a généralement plusieurs composants qui interagissent ensemble et avec Visual Studio.

Instance d’extension

Les extensions doivent avoir une classe qui dérive de Extension. Pour obtenir un exemple d’implémentation, consultez MarkdownLinter.

Une instance de la classe Extension est le point de départ de l’exécution de l’extension. Cette instance contient les méthodes nécessaires pour que Visual Studio interroge les services fournis par l’extension. Il fournit également des méthodes virtuelles pour l’extension afin de fournir des ressources localisées et des services locaux appartenant à l’extension à partager entre les composants de l’extension.

La configuration de la classe Extension contient également les métadonnées pour l’extension qui est affichée dans la fenêtre Gérer les extensions de Visual Studio et, pour les extensions publiées, sur la 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"),
    };
    ...

Pour les développeurs d’extensions qui connaissent les API VSSDK existantes, le Metadata contenu dans ExtensionConfiguration est utilisé pour générer le fichier .vsixmanifest. En outre, la classe Extension est similaire à la classe AsyncPackage utilisée dans le modèle d’extensibilité VSSDK.

Objet VisualStudioExtensibility

L’objet VisualStudioExtensibility agit comme point d’entrée pour les fonctionnalités d’extensibilité exposées par Visual Studio. Cette classe a différentes méthodes d’extension, propriétés permettant d’énumérer rapidement les fonctionnalités disponibles dans le Kit de développement logiciel (SDK) d’extensibilité. Consultez la documentation de l’API pour connaître les méthodes disponibles.

Pièces d'extension

Pour les fonctionnalités où une extension contribue aux composants de Visual Studio, comme les commandes, les écouteurs d’éditeur, les extensions utilisent des classes attributées. Le processus de génération génère les métadonnées appropriées pour vous assurer que ces composants peuvent être découverts par Visual Studio.

Pour les fonctionnalités où une extension contribue aux composants de Visual Studio, tels que les commandes, les écouteurs d’éditeur, les fenêtres d’outils, etc., les extensions utilisent des classes marquées avec l’attribut VisualStudioContribution. Le processus de génération génère les métadonnées appropriées pour vous assurer que ces composants peuvent être découverts par Visual Studio.

Actuellement, le Kit de développement logiciel (SDK) prend en charge un ensemble limité de composants à apporter :

Les instances de ces classes sont créées dans le cadre de l’infrastructure d’extensibilité fournie par le Kit de développement logiciel (SDK) à l’aide d’une bibliothèque d’injection de dépendances, et les constructeurs peuvent être utilisés pour récupérer des instances de services fournis par le SDK ou par l’extension elle-même pour partager l’état entre les composants.

Durée de vie des parties d’extension

La durée de vie de chaque partie est gérée par le composant respectif qui charge ces composants dans le processus IDE Visual Studio.

  • Les gestionnaires de commandes sont initialisés lorsque le jeu de commandes correspondant est activé, ce qui peut se trouver pendant la première exécution de la commande. Une fois activés, les gestionnaires de commandes ne doivent être supprimés que lorsque l’IDE est arrêté.

  • De même, les écouteurs d’événements pour les vues de texte sont initialisés lorsque la première vue de texte correspondant au type de contenu spécifié est chargée dans l'IDE. Actuellement, ces écouteurs sont actifs jusqu’à ce que l’IDE soit arrêté, mais ce comportement peut changer à l’avenir.

En général, pour les extensions complexes, nous recommandons que les extensions fournissent des services locaux que les composants peuvent importer dans leur constructeur. Ces services peuvent ensuite être utilisés pour partager l'état entre les composants et entre les instances d'un même composant. Cette pratique garantit que l’état de l’extension n’est pas affecté par les modifications de durée de vie des parties d’extension.

Services fournis par le Kit de développement logiciel (SDK) pour injection

Les services suivants sont fournis par le Kit de développement logiciel (SDK) qui peut être utilisé dans le constructeur pour n’importe quelle partie d’extension :

  • VisualStudioExtensibility: chaque composant d’extension peut injecter une instance de VisualStudioExtensibility pour interagir avec l’IDE Visual Studio.

  • Extension : les parties peuvent injecter le type Microsoft.VisualStudio.Extensibility.Extension ou le propre type de l’extension qui en hérite aux parties de l’extension.

  • TraceSource: une instance source de trace est créée à la demande pour chaque extension qui peut être utilisée pour enregistrer les informations de diagnostic. Ces instances sont inscrites auprès du fournisseur de diagnostics Visual Studio qui peut être utilisé pour fusionner des journaux à partir de plusieurs services et utiliser des outils futurs pour accéder à la journalisation en temps réel. Consultez Journalisation.

  • Services locaux : tous les services locaux fournis par l’extension elle-même seront également disponibles pour l’injection de dépendances.

  • MefInjection<TService> et AsyncServiceProviderInjection<TService, TInterface> : les extensions dans le processus peuvent injecter des services du kit de développement logiciel (SDK) Visual Studio qui seraient traditionnellement consommés via MEF ou le AsyncServiceProvider.

Services d’extension local

Dans certains scénarios, une extension peut souhaiter partager l’état entre différents composants, tels qu’un gestionnaire de commandes et un écouteur de modification d’affichage de texte, comme indiqué dans MarkdownLinter exemple. Ces services peuvent être ajoutés à la collection de services en cours de traitement en remplaçant la méthode Extension.InitializeServices et, lorsque des instances d'éléments d'extension sont créées, les services sont injectés selon les arguments du constructeur.

Il existe trois options pour ajouter un service :

  • AddTransient: une nouvelle instance du service est créée pour chaque partie qui l’ingère.
  • AddScoped: une nouvelle instance du service est créée dans une certaine étendue. Dans le contexte de l’extensibilité de Visual Studio, l’étendue fait référence à une seule partie d’extension.
  • AddSingleton: il existe une seule instance partagée de service créée lors de la première ingestion.

En raison de la durée de vie de l'objet VisualStudioExtensibility étant limitée à l'étendue d'une seule extension, tout service local qui l'ingère doit être un service avec une portée définie ou temporaire. La tentative de création d’un service singleton qui injecte VisualStudioExtensibility entraîne une défaillance.

Pour obtenir un exemple de l’utilisation des services locaux, consultez Extension MarkdownLinter.

Contexte client

Étant donné que toutes les extensions du nouveau Kit de développement logiciel (SDK) sont hors processus, nous introduisons le concept de contexte client pour différentes parties d’extension afin de représenter l’état de l’IDE au moment où l’événement ou la méthode est appelé. Ce contexte est représenté par l’instance IClientContext dans le Kit de développement logiciel (SDK) et est transmis à différentes opérations telles que les gestionnaires d'exécution de commandes. Le Kit de développement logiciel (SDK) fournit des méthodes d’extension sur IClientContext qui peuvent être utilisées pour récupérer des objets à partir du contexte. Par exemple, les extensions peuvent obtenir l’affichage de texte actif ou l’URI des éléments sélectionnés au moment de l’exécution de commande à l’aide de l’instance de IClientContext.

Certains composants tels que les commandes vous permettent également de déclarer les contextes qui les intéressent. Cela permet d’optimiser la quantité de données transférées dans chaque exécution à distance, car le contexte client peut être volumineux à l’avenir. Dans la préversion initiale, il n’existe que deux contextes disponibles, Shell et Editor, et les deux sont inclus par défaut lors de la déclaration d’une commande à l’aide de CommandAttribute.