Aspectos básicos del servicio de intermediación

Un servicio asincrónica es un servicio adquirido a través IServiceBrokerde y se expone como una interfaz compatible con RPC para permitir que el servicio y su cliente existan en distintos appDomains, procesos o incluso entre máquinas (en el caso de Live Share). El servicio asincronado se puede proferido desde el proceso principal de Visual Studio o algunos de sus procesos auxiliares, y puede ser consumido por cualquiera de estos procesos por una extensión de Visual Studio.

Hay más servicios de Visual Studio (no asincronados) disponibles a través de la IServiceProvider interfaz tal y como se describe en Uso y prestación de servicios. Estos servicios normalmente solo están disponibles en el proceso principal de Visual Studio, pero exponen un conjunto mayor de funcionalidad que los servicios asincrónicas.

Una extensión de Visual Studio que se ejecuta en un invitado de Live Share puede proporcionar funcionalidad adicional accediendo a un subconjunto de estos servicios como proporcionado por el host de Live Share. Las comprobaciones de autorización se aplican a través de las conexiones de Live Share para mitigar el riesgo de que un invitado de Live Share se comporte mal, lo que pone en peligro la seguridad del host de Live Share. Los autores de servicios asincronados que eligen exponer sus servicios a través de Live Share deben tener cuidado para implementar comprobaciones de autorización, tal como se describe en Cómo proporcionar un servicio asincronizado.

Service Broker

Visual Studio tiene un elemento global IServiceBroker, análogo a (y recuperable de) que GlobalProvider expone otro servicio. También se puede recuperar a través de MEF.

Puede haber otros agentes de servicio más específicos del contexto proferidos por características específicas de Visual Studio que quieran agregar el global con uno de sus propios que ofrece servicios adicionales (o quizá suprima algunos).

Es IServiceBroker (intencionadamente) una caja negra que permite a un cliente obtener servicios que pueden ser locales, en otro proceso o en otra máquina. Los agentes de servicio pueden ser agregados de uno o muchos otros, con directivas aplicadas.

En función del contexto en el que se encuentra el proceso de Visual Studio, este agente de servicio global es un agregado de un conjunto cambiante de otros agentes de servicio. Los cambios de contexto dentro del proceso pueden cambiar el conjunto de servicios asincrónicas que se pueden activar. Por ejemplo, cuando una solución se carga un servicio específicamente relacionado con la solución activa puede estar disponible. Ese mismo servicio también puede estar disponible en una vista Abrir carpeta, aunque con una implementación de respaldo diferente. El cambio en la implementación del servicio sería transparente para un cliente de ese servicio, ya que ambas implementaciones deben cumplir el mismo contrato, pero es necesario que el cliente vuelva a consultar el servicio en este cambio de contexto (del que se les notificará a través AvailabilityChangedde ) para obtener la nueva instancia.

El agente de servicio se usa normalmente para obtener un proxy al servicio. Es decir, en lugar de recibir una referencia al objeto de servicio directamente, el cliente recibe un código auxiliar que reenvía todas las llamadas de método al servicio y resultados o excepciones al cliente. También puede reenviar eventos generados por el servicio al cliente. En algunos casos, un servicio puede admitir o requerir que el cliente ofrezca un "objeto de destino" en el que el servicio pueda invocar métodos para volver a llamar al cliente.

Contenedor de servicios asincrónicas

Los servicios deben proferarse en para IBrokeredServiceContainer que estén disponibles desde el global IServiceBroker. Este contenedor de servicios no solo es responsable de exponer la factoría de servicios al agente de servicio, sino también para controlar qué clientes tienen acceso al servicio y notificar a esos clientes cuando cambia el acceso a ese servicio.

Composición de un servicio asincrónica

Un servicio asincrónica consta de los siguientes elementos:

  • Interfaz que declara la funcionalidad del servicio y actúa como un contrato entre el servicio y sus clientes.
  • Implementación de esa interfaz.
  • ServiceMoniker para asignar un nombre y una versión al servicio.
  • que ServiceRpcDescriptor combina el ServiceMoniker comportamiento con para controlar RPC cuando sea necesario.
  • Código para proferar la factoría de servicios
  • Registro de servicios

Interfaz de servicio

Puede ser una interfaz de .NET estándar (a menudo escrita en C#). Para permitir que los clientes y servicios de servicio asincronados existan en procesos distintos y se comuniquen a través de RPC, esta interfaz debe cumplir las restricciones especificadas por el que usará el ServiceRpcDescriptor servicio. Estas restricciones suelen incluir que no se permiten propiedades e indizadores, y la mayoría o todos los métodos devuelven Task u otro tipo de valor devuelto compatible con asincrónico.

Monikers y descriptores de servicio asincrónicas

La activación de un servicio requiere conocer su moniker. Dado que el moniker se incluye en el descriptor del servicio, un cliente normalmente solo puede tratar con .ServiceRpcDescriptor Un descriptor agrega el comportamiento necesario para configurar una conexión RPC entre el servicio asincrónico y su cliente o cuando sea necesario para serializar llamadas RPC a o desde .Stream

Visual Studio recomienda usar el ServiceJsonRpcDescriptor tipo derivado para los servicios asincronados que utiliza la biblioteca StreamJsonRpc cuando el cliente y el servicio requieren que RPC se comunique. StreamJsonRpc aplica ciertas restricciones en la interfaz de servicio como se describe aquí.

Un descriptor rara vez debe usarse directamente. En su lugar, normalmente se adquiere desde VisualStudioServices o una biblioteca que ofrece el servicio y, a continuación, se usa como argumento para GetProxyAsync.

ServiceMoniker Las clases y ServiceJsonRpcDescriptor son inmutables y, por tanto, son seguras para compartir como static readonly campos o propiedades. Cualquier otro ServiceRpcDescriptortipo derivado debe ser inmutable.

Es ServiceMoniker serializable. Un ServiceJsonRpcDescriptor no es serializable.

Audiencia del servicio

Cada servicio asincrónica se registra con una selección de marcas de ServiceAudience. Estas marcas controlan a qué clientes y a qué conexiones se expondrá el servicio asincrónica.

Una selección típica es ServiceAudience.Local, que expone el servicio a cualquier proceso local dentro de una sesión de Visual Studio. Con esta configuración, el servicio siempre se activa localmente, incluso si hay una sesión compartida activa.

Cuando se agrega la ServiceAudience.LiveShareGuest marca, un invitado de Live Share que solicita ese servicio asincrónica obtendrá un proxy a ese servicio asincrónica a través de la conexión remota con el host de Live Share.

Cualquier combinación de marcas definidas en ServiceAudience es legal. La LiveShareGuest marca se puede establecer sin establecer también la Local marca, por ejemplo, para exponer un servicio asincronizado solo a los invitados de Live Share (desde un host de Live Share) y nunca estar disponible localmente (donde el cliente y el servicio están en el mismo proceso).

Las RemoteExclusiveClient marcas y RemoteExclusiveServer están en desuso.

Cuando un cliente solicita un servicio asincrónica, no es necesario saber cuál es para ServiceAudience ese servicio o dónde se activará el servicio. Sin embargo, puede ser útil para que un servicio documente este valor y para que un desarrollador que consuma el servicio tenga en cuenta dónde se puede activar un servicio para que puedan prever el tipo de datos que pueden provenir de ese servicio en varios contextos y cuándo podría estar disponible un servicio.

Composición de un cliente asincrónica

Cuando un cliente solicita un servicio asincario, se devuelve null cuando el servicio no está disponible, se produce un ServiceActivationFailedException error si se produce un error en la activación del servicio o se obtiene un proxy al servicio. Se usa un proxy si el servicio asincrónica se activa en el mismo proceso que el cliente o uno diferente. Este proxy ayuda a armonizar los patrones de uso en los casos de servicio local y remoto para que el cliente no tenga en cuenta dónde se encuentra el servicio.