Éléments essentiels du service réparti
Un service réparti est un service acquis via un IServiceBrokerservice, et est exposé en tant qu’interface compatible RPC pour permettre au service et à son client d’exister dans des AppDomains, des processus ou même sur des ordinateurs (dans le cas de Live Share). Le service réparti peut être profferé à partir du processus Visual Studio principal ou de certains de ses processus auxiliaires, et peut être consommé par l’un de ces processus par une extension Visual Studio.
D’autres services Visual Studio (non réparti) sont disponibles via l’interface IServiceProvider , comme décrit dans Utilisation et fourniture de services. Ces services sont généralement disponibles uniquement dans le processus principal de Visual Studio, mais exposent un plus grand ensemble de fonctionnalités que les services réparti.
Une extension Visual Studio s’exécutant sur un invité Live Share peut fournir des fonctionnalités supplémentaires en accédant à un sous-ensemble de ces services comme proffered par l’hôte Live Share. Les case activée d’autorisation s’appliquent aux connexions Live Share pour atténuer le risque d’un invité Live Share mal comportementant qui compromet la sécurité de l’hôte Live Share. Les auteurs de services réparti qui choisissent d’exposer leurs services sur Live Share doivent prendre soin d’implémenter des case activée d’autorisation, comme décrit dans Comment fournir un service réparti.
Service Broker
Visual Studio a un élément global IServiceBroker, analogue à (et récupérable à partir de) qui GlobalProvider expose d’autres services. Il peut également être récupéré via MEF.
Il peut y avoir d’autres répartiteurs de services spécifiques au contexte proposés par des fonctionnalités Visual Studio spécifiques qui souhaitent agréger l’ensemble avec l’un de leurs propres services qui propose des services supplémentaires (ou peut-être supprimer certains).
Il IServiceBroker s’agit (intentionnellement) d’une boîte noire qui permet à un client d’obtenir des services qui peuvent être locaux, dans un autre processus ou sur un autre ordinateur. Les répartiteurs de services peuvent être des agrégats d’un ou de plusieurs autres, avec des stratégies appliquées.
En fonction du contexte dans lequel se trouve le processus Visual Studio, ce service broker global est un agrégat d’un ensemble changeant d’autres répartiteurs de services. Les modifications de contexte au sein du processus peuvent modifier l’ensemble de services réparti qui peuvent être activés. Par exemple, lorsqu’une solution est chargée, un service spécifiquement lié à la solution active peut devenir disponible. Ce même service peut également être disponible dans une vue Ouvrir un dossier, bien qu’avec une implémentation de stockage différente. La modification de l’implémentation du service serait transparente pour un client de ce service, car les deux implémentations doivent remplir le même contrat, mais le client doit interroger à nouveau le service dans ce changement de contexte (dont ils seraient avertis via AvailabilityChanged) pour obtenir la nouvelle instance.
Le service Broker est généralement utilisé pour obtenir un proxy vers le service. Autrement dit, au lieu de recevoir directement une référence à l’objet de service, le client reçoit un stub qui transfère tous les appels de méthode au service et les résultats ou exceptions au client. Il peut également transférer des événements déclenchés par le service au client. Dans certains cas, un service peut prendre en charge ou exiger que le client offre un « objet cible » sur lequel le service peut appeler des méthodes pour rappeler le client.
Conteneur de service réparti
Les services doivent être mis en avant dans l’ordre IBrokeredServiceContainer pour être disponibles à partir du global IServiceBroker. Ce conteneur de service est responsable non seulement de l’exposition de la fabrique de services au service Broker, mais également du contrôle des clients qui ont accès au service et de notifier ces clients lors de l’accès à ce service.
Composition d’un service réparti
Un service réparti se compose des éléments suivants :
- Interface qui déclare la fonctionnalité du service et sert de contrat entre le service et ses clients.
- Implémentation de cette interface.
- A ServiceMoniker pour attribuer un nom et une version au service.
- Qui ServiceRpcDescriptor combine le ServiceMoniker comportement pour gérer RPC si nécessaire.
- Code pour proffer la fabrique de service
- Inscription du service
Interface de service
Il peut s’agir d’une interface .NET standard (souvent écrite en C#). Pour permettre aux clients et services de service réparti d’exister dans des processus distincts et de communiquer via RPC, cette interface doit respecter les restrictions spécifiées par le ServiceRpcDescriptor service que votre service utilisera. Ces restrictions incluent généralement que les propriétés et les indexeurs ne sont pas autorisés, et la plupart ou toutes les méthodes retournent Task ou un autre type de retour compatible asynchrone.
Monikers et descripteurs de service réparti
L’activation d’un service nécessite de connaître son moniker. Étant donné que le moniker est inclus dans le descripteur du service, un client peut généralement simplement traiter le ServiceRpcDescriptor. Un descripteur ajoute le comportement nécessaire pour configurer une connexion RPC entre le service réparti et son client ou lorsque nécessaire pour sérialiser les appels RPC vers/à partir d’un Stream.
Visual Studio recommande d’utiliser le ServiceJsonRpcDescriptor type dérivé pour les services répartits qui utilisent la bibliothèque StreamJsonRpc lorsque le client et le service nécessitent une communication RPC. StreamJsonRpc applique certaines restrictions sur l’interface de service, comme décrit ici.
Un descripteur doit rarement être utilisé directement. Au lieu de cela, il est généralement acquis à partir VisualStudioServices d’une bibliothèque qui offre le service, puis utilisé comme argument à GetProxyAsync.
Les classes et ServiceJsonRpcDescriptor les ServiceMoniker classes sont immuables et donc sécurisées à partager en tant que static readonly
champs ou propriétés.
Tout autre ServiceRpcDescriptortype dérivé doit être immuable.
A ServiceMoniker est sérialisable. Un ServiceJsonRpcDescriptor n’est pas sérialisable.
Public de service
Chaque service réparti est inscrit avec une sélection d’indicateurs de ServiceAudience. Ces indicateurs contrôlent les clients et les connexions auxquelles le service réparti sera exposé.
Une sélection classique est ServiceAudience.Local, qui expose le service à n’importe quel processus local au sein d’une session Visual Studio. Avec ce paramètre, le service est toujours activé localement, même si une session Live Shared est active.
Lorsque l’indicateur ServiceAudience.LiveShareGuest est ajouté, un invité Live Share qui demande que le service réparti obtient un proxy vers ce service réparti via la connexion à distance avec l’hôte Live Share.
Toute combinaison d’indicateurs définis est ServiceAudience légale. L’indicateur LiveShareGuest peut être défini sans également définir l’indicateur Local , par exemple pour exposer un service réparti uniquement aux invités Live Share (à partir d’un hôte Live Share) et ne jamais être disponible localement (où le client et le service se trouvent dans le même processus).
Les RemoteExclusiveClient indicateurs et RemoteExclusiveServer les indicateurs sont déconseillés.
Lorsqu’un client demande un service réparti, il n’a pas besoin de savoir ce qui ServiceAudience est pour ce service ou où le service sera activé. Toutefois, il peut être utile pour un service de documenter cette valeur et pour un développeur qui consomme le service pour savoir où un service peut être activé afin qu’il puisse anticiper le type de données provenant de ce service dans différents contextes et lorsqu’un service peut être disponible.
Composition d’un client réparti
Lorsqu’un client demande un service réparti, il revient null
lorsque le service n’est pas disponible, une ServiceActivationFailedException levée si le service échoue dans l’activation ou qu’il obtient un proxy vers le service.
Un proxy est utilisé si le service réparti est activé dans le même processus que le client ou un autre.
Ce proxy permet d’harmoniser les modèles d’utilisation dans les cas de service local et distant afin que le client ne sache pas où se trouve le service.