File: ServiceDescriptor.cs
Web Access
Project: src\src\Workspaces\Remote\Core\Microsoft.CodeAnalysis.Remote.Workspaces.csproj (Microsoft.CodeAnalysis.Remote.Workspaces)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Diagnostics;
using Microsoft.ServiceHub.Framework;
using Roslyn.Utilities;
using StreamJsonRpc;
 
namespace Microsoft.CodeAnalysis.Remote
{
    /// <summary>
    /// Describes Roslyn remote brokered service. 
    /// Adds Roslyn specific JSON converters and RPC settings to the default implementation.
    /// </summary>
    internal sealed class ServiceDescriptor : ServiceJsonRpcDescriptor
    {
        /// <summary>
        /// Brokered services must be defined in Microsoft.VisualStudio service namespace in order to be considered first party.
        /// </summary>
        internal const string ServiceNameTopLevelPrefix = "Microsoft.VisualStudio.";
 
        private static readonly JsonRpcTargetOptions s_jsonRpcTargetOptions = new()
        {
            // Do not allow JSON-RPC to automatically subscribe to events and remote their calls.
            NotifyClientOfEvents = false,
 
            // Only allow public methods (may be on internal types) to be invoked remotely.
            AllowNonPublicInvocation = false
        };
 
        internal readonly string ComponentName;
        internal readonly string SimpleName;
 
        private readonly Func<string, string> _featureDisplayNameProvider;
        private readonly RemoteSerializationOptions _serializationOptions;
 
        private ServiceDescriptor(
            ServiceMoniker serviceMoniker,
            string componentName,
            string simpleName,
            RemoteSerializationOptions serializationOptions,
            Func<string, string> displayNameProvider,
            Type? clientInterface)
            : base(serviceMoniker, clientInterface, serializationOptions.Formatter, serializationOptions.MessageDelimiters, serializationOptions.MultiplexingStreamOptions)
        {
            ComponentName = componentName;
            SimpleName = simpleName;
            _featureDisplayNameProvider = displayNameProvider;
            _serializationOptions = serializationOptions;
        }
 
        private ServiceDescriptor(ServiceDescriptor copyFrom)
          : base(copyFrom)
        {
            ComponentName = copyFrom.ComponentName;
            SimpleName = copyFrom.SimpleName;
            _featureDisplayNameProvider = copyFrom._featureDisplayNameProvider;
            _serializationOptions = copyFrom._serializationOptions;
        }
 
        public static ServiceDescriptor CreateRemoteServiceDescriptor(string componentName, string simpleName, string suffix, RemoteSerializationOptions options, Func<string, string> featureDisplayNameProvider, Type? clientInterface)
            => new(CreateMoniker(componentName, simpleName, suffix), componentName, simpleName, options, featureDisplayNameProvider, clientInterface);
 
        public static ServiceDescriptor CreateInProcServiceDescriptor(string componentName, string simpleName, string suffix, Func<string, string> featureDisplayNameProvider)
            => new(CreateMoniker(componentName, simpleName, suffix), componentName, simpleName, RemoteSerializationOptions.Default, featureDisplayNameProvider, clientInterface: null);
 
        private static ServiceMoniker CreateMoniker(string componentName, string simpleName, string suffix)
            => new(ServiceNameTopLevelPrefix + componentName + "." + simpleName + suffix);
 
        protected override ServiceRpcDescriptor Clone()
            => new ServiceDescriptor(this);
 
        protected override IJsonRpcMessageFormatter CreateFormatter()
            => _serializationOptions.ConfigureFormatter(base.CreateFormatter());
 
        protected override JsonRpcConnection CreateConnection(JsonRpc jsonRpc)
        {
            jsonRpc.CancelLocallyInvokedMethodsWhenConnectionIsClosed = true;
            var connection = base.CreateConnection(jsonRpc);
            connection.LocalRpcTargetOptions = s_jsonRpcTargetOptions;
            return connection;
        }
 
        internal string GetFeatureDisplayName()
            => _featureDisplayNameProvider(SimpleName);
    }
}