次の方法で共有


仲介型サービスの基本情報

仲介型サービスは、IServiceBroker を介して取得されるサービスであり、サービスとそのクライアントが異なる AppDomain、プロセス、または複数のマシン (Live Share の場合) に存在できるようにする RPC 互換インターフェイスとして公開されます。 仲介型サービスは、メインの Visual Studio プロセスまたはその補助プロセスの一部から提供され、Visual Studio 拡張機能によってこれらのプロセスのいずれかで使用される場合があります。

サービスの使用と提供」で説明しているように、IServiceProvider インターフェイス経由でより多くの (仲介されていない) Visual Studio サービスを利用できます。 このようなサービスは、通常、メインの Visual Studio プロセスでのみ使用できますが、仲介型サービスよりも大きな機能セットが公開されます。

Live Share ゲストで実行されている Visual Studio 拡張機能は、Live Share ホストによって提供されるこれらのサービスのサブセットにアクセスすることで、追加の機能を提供する場合があります。 Live Share ホストのセキュリティを侵害する不適切な動作の Live Share ゲストのリスクを軽減するために、Live Share 接続を介した認証チェックが適用されます。 Live Share 経由でサービスを公開することを選択する仲介型サービスの作成者は、「仲介型サービスを提供する方法」の説明に従って、認証チェックを実装するよう注意する必要があります。

Service Broker

Visual Studio には、1 つのグローバルな IServiceBroker があります。これは、他のサービスを公開する GlobalProvider に似ています (また、そこからの取得も可能です)。 MEF を介して取得することもできます。

グローバルな機能を、追加のサービスを提供する (または一部を抑制する) 自身の機能と集約する、特定の Visual Studio 機能によって提供される他の、よりコンテキスト固有のサービス ブローカーが存在する場合があります。

IServiceBroker は、ローカル、別のプロセス、または別のコンピューター上にある可能性のあるサービスをクライアントが取得できるようにする (意図的な) ブラック ボックスです。 サービス ブローカーは、ポリシーが適用された 1 つ以上の他のブローカーの集約である場合があります。

Visual Studio プロセスが存在しているコンテキストに基づいて、このグローバル サービス ブローカーは、他のサービス ブローカーの変化するセットの集約です。 プロセス内のコンテキストが変わると、アクティブ化できる仲介型サービスのセットが変わる可能性があります。 たとえば、ソリューションが読み込まれると、アクティブなソリューションに特に関連するサービスが使用可能になることがあります。 同じサービスが [フォルダーを開く] ビューでも使用できることがありますが、その場合は異なるバッキング実装を伴います。 両方の実装が同じコントラクトを満たす必要があるため、サービス実装の変更は、そのサービスのクライアントに対して透過的になりますが、クライアントは新しいインスタンスを取得するために、このコンテキストの変更 (AvailabilityChanged を介して通知される) 全体でサービスのクエリを再実行する必要があります。

通常、サービス ブローカーは、サービスへのプロキシを取得するために使用されます。 つまり、クライアントは、サービス オブジェクトへの参照を直接受け取るのではなく、すべてのメソッド呼び出しをサービスに転送し、結果または例外をクライアントに返すスタブを受け取ります。 また、サービスによって発生したイベントもクライアントに転送されることがあります。 場合によっては、サービスがクライアントにコールバックするためにメソッドを呼び出すことができる "ターゲット オブジェクト" をクライアントが提供することをサポートまたは要求することがあります。

ブローカー サービス コンテナー

グローバル IServiceBroker から利用できるようにするには、サービスを IBrokeredServiceContainer に提供する必要があります。 このサービス コンテナーは、サービス ファクトリをサービス ブローカーに公開するだけでなく、サービスにアクセスできるクライアントを制御し、そのサービスへのアクセスが変更されたときにそれらのクライアントに通知する役割も担います。

仲介型サービスの構成

仲介型サービスは次の要素で構成されます。

  • サービスの機能を宣言し、サービスとそのクライアント間のコントラクトとして機能するインターフェイス。
  • そのインターフェイスの実装。
  • 名前とバージョンをサービスに割り当てる ServiceMoniker
  • ServiceMoniker を RPC を処理するための動作と組み合わせる ServiceRpcDescriptor (必要な場合に)。
  • サービス ファクトリを提供するコード
  • サービス登録

サービス インターフェイス

これは標準の .NET インターフェイスである場合があります (多くの場合、C# で記述されています)。 ブローカー サービス クライアントとサービスを個別のプロセスに存在させ、RPC 経由で通信できるようにするには、このインターフェイスは、サービスが使用する ServiceRpcDescriptor によって指定されているとおりに制約に従う必要があります。 通常、これらの制限にはそのプロパティが含まれており、インデクサーは許可されません。ほとんどまたはすべてのメソッドによって、Task または非同期互換の別の戻り値の型が返されます。

仲介型サービス モニカーと記述子

サービスをアクティブ化するには、そのモニカーを知っている必要があります。 モニカーはサービスの記述子に含まれているため、通常、クライアントは ServiceRpcDescriptor とやり取りすることができるだけです。 記述子は、仲介型サービスとそのクライアントとの間の RPC 接続を設定するために必要な場合、または Stream との間の RPC 呼び出しをシリアル化するために必要な場合にその動作を追加します。

Visual Studio では、クライアントとサービスが通信するために RPC を必要とする場合に StreamJsonRpc ライブラリを利用するブローカー サービスに ServiceJsonRpcDescriptor 派生型を使用することをお勧めします。 ここで説明しているように、StreamJsonRpc によって、サービス インターフェイスに対して特定の制約が適用されます。

記述子を直接使用する必要はほとんどありません。 代わりに、通常は VisualStudioServices から、またはサービスを提供するライブラリから取得され、GetProxyAsync への引数として使用されます。

ServiceMoniker クラスと ServiceJsonRpcDescriptor クラスはどちらも不変であるため、static readonly フィールドまたはプロパティとして共有しても安全です。 その他の ServiceRpcDescriptor 派生型は変更不可である必要があります。

ServiceMoniker はシリアル化できます。 ServiceJsonRpcDescriptor はシリアル化できません。

サービス対象ユーザー

すべての仲介型サービスは、ServiceAudience から選択したフラグと共に登録されます。 これらのフラグは、仲介型サービスが公開されるクライアントと接続を制御します。

一般的な選択は ServiceAudience.Local であり、これは、サービスを Visual Studio セッション内の任意のローカル プロセスに公開することです。 この設定では、Live Share セッションがアクティブな場合でも、サービスは常にローカルでアクティブになります。

ServiceAudience.LiveShareGuest フラグが追加されると、ブローカー サービスを必要とする Live Share ゲストは、Live Share ホストとのリモート接続を介してそのブローカー サービスへのプロキシを取得します。

ServiceAudience で定義されているフラグの組み合わせはすべて有効です。 LiveShareGuest フラグは、Local フラグを設定 "することなく" 設定できます。たとえば、ブローカー サービスを (Live Share ホストから) Live Share ゲスト "のみ" に公開し、ローカルで (クライアントとサービスが同じプロセスにある場合) 使用できないようにします。

RemoteExclusiveClient フラグと RemoteExclusiveServer フラグは非推奨です。

クライアントがブローカー サービスを要求する場合に、その ServiceAudience の目的やそのサービスがアクティブ化される場所を知る必要はありません。 ただし、サービスでこの値を文書化することは有用です。また、サービスを使用している開発者が、サービスがアクティブ化される可能性がある場所を認識し、さまざまな文脈でサービスから送信される可能性のあるデータの種類と、サービスがいつ利用可能になるかを予測できることは有用です。

仲介型クライアントの構成

クライアントが仲介型サービスを要求すると、サービスが利用できないときに null が返されるか、アクティブ化でサービスが失敗した場合に ServiceActivationFailedException がスローされるか、サービスへの "プロキシ" を取得するかのいずれかとなります。 仲介型サービスがクライアントと同じプロセスでアクティブ化されるか、別のプロセスでアクティブ化されるかに関係なく、プロキシが使用されます。 このプロキシは、クライアントがサービスの場所を認識する必要がないように、ローカル サービスの場合とリモート サービスの場合にわたって使用パターンを調和するのに役立ちます。