Freigeben über


Grundlagen vermittelter Dienstleistungen

Ein vermittelter Dienst ist ein Dienst, der über einen IServiceBroker erworben wird und als RPC-kompatible Schnittstelle verfügbar gemacht wird, damit der Dienst und sein Client in unterschiedlichen AppDomains, Prozessen oder sogar über mehrere Computer hinweg existieren können (im Fall von Live Share). Der vermittelte Dienst kann entweder vom Hauptprozess von Visual Studio oder von einigen seiner Hilfsprozesse angeboten werden und kann von einem dieser Prozesse durch eine Visual Studio-Erweiterung genutzt werden.

Weitere (nicht vermittelte) Visual Studio-Dienste sind über die IServiceProvider Schnittstelle verfügbar, wie unter Verwendung und Bereitstellung von Diensten beschrieben. Solche Dienste sind in der Regel nur im Hauptprozess von Visual Studio verfügbar, stellen aber einen größeren Satz von Funktionen zur Verfügung als brokerierte Dienste.

Eine Visual Studio-Erweiterung, die auf einem Live Share-Gast ausgeführt wird, kann zusätzliche Funktionen bereitstellen, indem auf eine Teilmenge dieser Dienste zugegriffen wird, die vom Live Share-Host bereitgestellt werden. Autorisierungsprüfungen gelten für Live-Freigabeverbindungen, um das Risiko zu verringern, dass ein Gast der Live-Freigabe die Sicherheit des Hosts der Live-Freigabe beeinträchtigt. Autoren von brokerierten Diensten, die sich dafür entscheiden, ihre Dienste über Live Share verfügbar zu machen, sollten sich um die Implementierung von Autorisierungsprüfungen kümmern, wie in how to provide a brokered service beschrieben.

Service Broker

Visual Studio verfügt über einen globalen IServiceBroker, der ähnlich wie GlobalProvider ist und aus dem abgerufen werden kann, während er andere Dienste bereitstellt. Es kann auch über MEF abgerufen werden.

Möglicherweise gibt es andere kontextspezifische Dienstbroker, die von bestimmten Visual Studio-Features unterstützt werden, die das globale Feature mit einem eigenen aggregieren möchten, das zusätzliche Dienste anbietet (oder vielleicht einige unterdrückt).

Ein IServiceBroker ist (absichtlich) eine Black Box, mit der ein Client Dienste abrufen kann, die entweder lokal, in einem anderen Prozess oder auf einem anderen Computer verfügbar sind. Dienstanbieter können Aggregate eines oder mehrerer anderer sein, mit angewandten Richtlinien.

Basierend auf dem Kontext, in dem sich der Visual Studio-Prozess befindet, ist dieser globale Dienstbroker ein Aggregat eines sich ändernden Satzes anderer Dienstbroker. Kontextänderungen innerhalb des Prozesses können den Satz von brokerierten Diensten ändern, die aktiviert werden können. Wenn z. B. eine Lösung geladen wird, kann ein Dienst speziell im Zusammenhang mit der aktiven Lösung verfügbar werden. Dieser Dienst kann auch in einer Ansicht "Ordner öffnen" verfügbar sein, wenn auch mit einer anderen Sicherungsimplementierung. Die Änderung der Dienstimplementierung wäre für einen Client dieses Diensts transparent, da beide Implementierungen denselben Vertrag erfüllen müssen, aber der Client muss den Dienst in dieser Kontextänderung erneut abfragen (von denen sie über AvailabilityChangedbenachrichtigt werden würden), um die neue Instanz abzurufen.

Der Dienstbroker wird in der Regel verwendet, um einen Proxy für den Dienst abzurufen. Statt einen Verweis auf das Dienstobjekt direkt zu empfangen, empfängt der Client einen Stub, der alle Methodenaufrufe an den Dienst weiterleitet und Ergebnisse oder Ausnahmen an den Client zurückgibt. Es kann auch Ereignisse weiterleiten, die vom Dienst an den Client ausgelöst werden. In einigen Fällen unterstützt oder erfordert ein Dienst, dass der Client ein "Zielobjekt" bietet, für das der Dienst Methoden aufrufen kann, um den Client zurückzurufen.

Vermittelte Dienstinfrastruktur

Dienste müssen in das IBrokeredServiceContainer System gestellt werden, um von der globalen IServiceBroker verfügbar zu sein. Dieser Dienstcontainer ist nicht nur für die Bereitstellung der Dienst-Factory für den Servicebroker verantwortlich, sondern auch für die Kontrolle darüber, welche Clients Zugriff auf den Dienst haben, und dafür, dass diese Clients benachrichtigt werden, wenn sich der Zugriff auf diesen Dienst ändert.

Zusammensetzung eines brokerierten Diensts

Ein vermittelter Dienst besteht aus den folgenden Elementen:

  • Eine Schnittstelle, die die Funktionalität des Diensts deklariert und als Vertrag zwischen dem Dienst und seinen Clients dient.
  • Eine Implementierung dieser Schnittstelle.
  • A ServiceMoniker , um dem Dienst einen Namen und eine Version zuzuweisen.
  • Eine ServiceRpcDescriptor, die das ServiceMoniker mit einem Verhalten kombiniert, um RPC bei Bedarf zu behandeln.
  • Code zur Bereitstellung der Servicefabrik
  • Dienstregistrierung

Dienstschnittstelle

Dies kann eine .NET-Standardschnittstelle sein (häufig in C#geschrieben). Damit brokerierte Dienstclients und -dienste in unterschiedlichen Prozessen vorhanden sind und über RPC kommunizieren können, muss diese Schnittstelle die durch ServiceRpcDescriptor spezifizierten Einschränkungen Ihres Dienstes einhalten. Diese Einschränkungen umfassen in der Regel, dass Eigenschaften und Indexer nicht zulässig sind, und die meisten oder alle Methoden geben Task oder einen anderen asynchron kompatiblen Rückgabetyp zurück.

Vermittelte Dienstbezeichnungen und Beschreibungen

Für die Aktivierung eines Dienstes ist es erforderlich, seinen Moniker zu kennen. Da der Moniker in der Beschreibung des Dienstes enthalten ist, kann ein Client in der Regel einfach mit dem ServiceRpcDescriptor umgehen. Ein Deskriptor fügt das Verhalten hinzu, das erforderlich ist, um eine RPC-Verbindung zwischen dem brokerierten Dienst und seinem Client einzurichten, oder wenn dies erforderlich ist, um RPC-Aufrufe in/aus Streamzu serialisieren.

Visual Studio empfiehlt die Verwendung des ServiceJsonRpcDescriptor abgeleiteten Typs für brokerierte Dienste, die die StreamJsonRpc-Bibliothek verwendet, wenn der Client und der Dienst RPC für die Kommunikation benötigen. StreamJsonRpc wendet bestimmte Einschränkungen für die Dienstschnittstelle an, wie hier beschrieben.

Ein Deskriptor muss selten direkt verwendet werden. Stattdessen wird es typischerweise von VisualStudioServices oder einer Bibliothek erworben, die den Dienst anbietet, und dann als Argument für GetProxyAsync verwendet.

Sowohl die ServiceMoniker als auch die ServiceJsonRpcDescriptor Klassen sind unveränderlich und daher sicher, als static readonly Felder oder Eigenschaften verwendet zu werden. Jeder andere ServiceRpcDescriptorabgeleitete Typ sollte unveränderlich sein.

A ServiceMoniker ist serialisierbar. A ServiceJsonRpcDescriptor ist nicht serialisierbar.

Dienstzielgruppe

Jeder vermittelte Dienst wird mit einer Auswahl an Flags bei ServiceAudience registriert. Diese Flags steuern, welche Clients und über welche Verbindungen der brokerierte Dienst verfügbar gemacht wird.

Eine typische Auswahl ist ServiceAudience.Local, die den Dienst für jeden lokalen Prozess innerhalb einer Visual Studio-Sitzung verfügbar macht. Bei dieser Einstellung wird der Dienst immer lokal aktiviert, auch wenn eine Live Shared-Sitzung aktiv ist.

Wenn das ServiceAudience.LiveShareGuest-Flag hinzugefügt wird, erhält ein Live Share-Gast, der diesen brokerierten Dienst anfordert, einen Proxy für diesen Dienst über die Remoteverbindung mit dem Live Share-Host.

Jede Kombination von Flags, die auf ServiceAudience definiert wurden, ist legal. Die LiveShareGuest Flagge kann festgelegt werden, ohne auch die Local Flagge festzulegen, z. B. um einen vermittelten Dienst nur für Live Share-Gäste (von einem Live Share-Host) verfügbar zu machen und niemals lokal verfügbar zu machen (wo sich Client und Dienst im selben Prozess befinden).

Die RemoteExclusiveClient- und RemoteExclusiveServer-Flaggen sind veraltet.

Wenn ein Client einen brokergesteuerten Dienst anfordert, muss er nicht wissen, wofür der ServiceAudience Dienst ist oder wo der Dienst aktiviert wird. Es kann jedoch hilfreich sein, dass ein Dienst diesen Wert dokumentiert, und für einen Entwickler, der den Dienst verwendet, um zu wissen, wo ein Dienst aktiviert werden kann, damit sie die Art von Daten antizipieren können, die in verschiedenen Kontexten von diesem Dienst stammen können und wann ein Dienst verfügbar ist.

Zusammensetzung eines vermittelten Clients

Wenn ein Client einen vermittelten Dienst anfordert, erhält er entweder null zurück, wenn der Dienst nicht verfügbar ist, es wird ein ServiceActivationFailedException ausgelöst, wenn der Dienst bei der Aktivierung fehlschlägt, oder er erhält einen Proxy für den Dienst. Ein Proxy wird verwendet, ob der vermittelte Dienst im selben Prozess wie der Client oder in einem anderen Prozess aktiviert ist. Dieser Proxy hilft dabei, Nutzungsmuster in den lokalen und Remotedienstfällen zu harmonisieren, sodass der Client nicht wissen muss, wo sich der Dienst befindet.