VisualStudio.Extensibility 拡張機能のコンポーネント

VisualStudio.Extensibility を利用する拡張機能には、通常、Visual Studio とやり取りするいくつかのコンポーネントがあります。

拡張機能インスタンス

拡張機能には、派生 Extension元のクラスが必要です。 実装例については、MarkdownLinter を参照してください

クラスの Extension インスタンスは、拡張機能の実行の開始点です。 このインスタンスには、拡張機能によって提供されるサービスのクエリを実行するために Visual Studio に必要なメソッドが含まれています。 また、拡張機能のコンポーネント間で共有されるローカライズされたリソースと拡張機能所有のローカル サービスを提供するための仮想メソッドも提供します。

クラスのExtension構成には、Visual Studio の [拡張機能の管理] ウィンドウに表示される拡張機能のメタデータと、発行された拡張機能の 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"),
    };
    ...

既存の VS SDK API に慣れている拡張機能開発者の場合は、ファイルの Metadata 生成に含まれている ExtensionConfiguration ものが .vsixmanifest 使用されます。 また、この Extension クラスは VS SDK 拡張機能モデルで使用されるクラスに似ています AsyncPackage

VisualStudioExtensibility オブジェクト

オブジェクト VisualStudioExtensibility は、Visual Studio によって公開される機能拡張機能のエントリ ポイントとして機能します。 このクラスには、拡張 SDK で使用可能な機能をすばやく列挙するためのさまざまな拡張メソッド、プロパティがあります。 使用可能なメソッドについては、API のドキュメントを参照してください。

拡張パーツ

拡張機能がコマンド、エディター リスナーなどのコンポーネントを Visual Studio に提供する機能の場合、拡張機能は属性付きクラスを利用します。 ビルド プロセスでは、Visual Studio でこれらのコンポーネントを確実に検出できるように、適切なメタデータが生成されます。

拡張機能がコマンド、エディター リスナー、ツール ウィンドウなどのコンポーネントを Visual Studio に提供する機能の場合、拡張機能は属性でマークされたクラスを VisualStudioContribution 利用します。 ビルド プロセスによって正しいメタデータが生成され、Visual Studio でこれらのコンポーネントを確実に検出できるようになります。

現在、SDK では、提供されるコンポーネントの限られたセットがサポートされています。

これらのクラスのインスタンスは、依存関係挿入ライブラリを使用して SDK によって提供される拡張フレームワークの一部として作成され、コンストラクターを使用して、SDK または拡張機能自体によって提供されるサービスのインスタンスを取得して、コンポーネント間で状態を共有できます。

延長部品の有効期間

各パーツの有効期間は、Visual Studio IDE プロセス内でそれらのパーツを読み込む各コンポーネントによって管理されます。

  • コマンド ハンドラーは、対応するコマンド セットがアクティブ化されるときに初期化されます。これは、コマンドの最初の実行中に発生する可能性があります。 アクティブ化されたコマンド ハンドラーは、IDE がシャットダウンされたときにのみ破棄する必要があります。

  • 同様に、テキスト ビュー イベント リスナーは、指定されたコンテンツ タイプに一致する最初のテキスト ビューが IDE に読み込まれるときに初期化されます。 現在、このようなリスナーは IDE がシャットダウンされるまでアクティブですが、この動作は将来変更される可能性があります。

一般に、複雑な拡張機能の場合、拡張機能では、パーツがコンストラクターにインポートできるローカル サービスを提供し、それらのサービスを使用して、同じパーツの複数のパーツ間およびインスタンス間で状態を共有することをお勧めします。 この方法により、拡張パーツの有効期間の変更によって拡張機能の状態が影響を受けないようにします。

SDK によって提供されるインジェクション用のサービス

次のサービスは、任意の拡張パーツのコンストラクターで使用できる SDK によって提供されます。

  • VisualStudioExtensibility: すべての拡張機能パーツは、Visual Studio IDE と対話するためのインスタンス VisualStudioExtensibility を挿入できます。

  • Extension: パーツは、型を挿入するか、拡張機能から拡張パーツに継承する拡張機能独自の型を挿入 Microsoft.VisualStudio.Extensibility.Extension できます。

  • TraceSource: 診断情報の記録に使用できる拡張機能ごとに、トレース ソース インスタンスが必要に応じて作成されます。 これらのインスタンスは Visual Studio 診断 プロバイダーに登録されます。このプロバイダーを使用すると、複数のサービスのログをマージし、将来のツールを使用してリアルタイム ログにアクセスできます。 ログ記録を参照してください

  • ローカル サービス: 拡張機能自体によって提供されるローカル サービスも、依存関係の挿入に使用できます。

  • MefInjection<TService>および AsyncServiceProviderInjection<TService, TInterface>: インプロセス拡張機能は、MEF または AsyncServiceProvider通じて従来使用される Visual Studio SDK サービスを挿入できます。

ローカル拡張機能サービス

特定のシナリオでは、拡張機能では、コマンド ハンドラーやテキスト ビュー変更リスナーなど、さまざまなコンポーネント間で状態を共有することが必要になる場合があります(例を MarkdownLinter 参照)。 これらのサービスは、メソッドをオーバーライド Extension.InitializeServices することでインプロセス サービス コレクションに追加でき、拡張パーツのインスタンスが作成されると、コンストラクターの引数に基づいてサービスが挿入されます。

サービスを追加するには、次の 3 つのオプションがあります。

  • AddTransient: サービスを取り込む各パーツに対して、サービスの新しいインスタンスが作成されます。
  • AddScoped: サービスの新しいインスタンスが特定のスコープ内に作成されます。 Visual Studio の拡張機能のコンテキストでは、スコープは 1 つの拡張パーツを参照します。
  • AddSingleton: 最初のインジェストで作成されるサービスの 1 つの共有インスタンスがあります。

オブジェクトの VisualStudioExtensibility 有効期間が 1 つの拡張パーツのスコープにバインドされているため、それを取り込むローカル サービスは、スコープ付きまたは一時的なサービスである必要があります。 挿入 VisualStudioExtensibility するシングルトン サービスを作成しようとすると、エラーが発生します。

ローカル サービスの使用方法の例については、MarkdownLinter 拡張機能を参照してください

クライアント コンテキスト

新しい SDK のすべての拡張機能ではプロセスが不足するため、イベントまたはメソッドが呼び出されたときの IDE の状態を表すさまざまな拡張パーツのクライアント コンテキストの概念を紹介します。 このコンテキストは SDK の IClientContext インスタンスによって表され、コマンド実行ハンドラーなどのさまざまな操作に渡されます。 SDK には、コンテキストからオブジェクトを IClientContext 取得するために使用できる拡張メソッドが用意されています。 たとえば、拡張機能は、インスタンスを利用するコマンドの実行時に、選択した項目のアクティブなテキスト ビューまたは URI を IClientContext 取得できます。

コマンドなどの一部のコンポーネントでは、関心のあるコンテキストを宣言することもできます。 これは、クライアント コンテキストが将来大きくなる可能性があるため、各リモート実行で転送されるデータの量を最適化するために行われます。 初期プレビューでは、使用可能なコンテキストは 2 つだけで、 ShellEditor使用して CommandAttributeコマンドを宣言するときに、両方が既定で含まれます。