Repository: dotnet/roslyn
File: src/LanguageServer/Protocol/RoslynLanguageServer.cs (C#)

Code before:
        var provider = GetLspServices().GetRequiredService<IRequestExecutionQueueProvider<RequestContext>>();
        return provider.CreateRequestExecutionQueue(this, Logger, HandlerProvider);
    }

    private FrozenDictionary<string, ImmutableArray<BaseService>> GetBaseServices(
        JsonRpc jsonRpc,
        AbstractLspLogger logger,
        HostServices hostServices,
        WellKnownLspServerKinds serverKind,
        ImmutableArray<string> supportedLanguages)
    {
        // This map will hold either a single BaseService instance, or an ImmutableArray<BaseService>.Builder.
        var baseServiceMap = new Dictionary<string, object>();

        var clientLanguageServerManager = new ClientLanguageServerManager(jsonRpc);

        AddService<IClientLanguageServerManager>(clientLanguageServerManager);
        AddService<ILspLogger>(logger);
        AddService<AbstractLspLogger>(logger);
        AddLazyService<ILifeCycleManager>(lspServices => lspServices.GetRequiredService<LspServiceLifeCycleManager>());
        AddService(new ServerInfoProvider(serverKind, supportedLanguages));
        AddLazyService<AbstractRequestContextFactory<RequestContext>>(lspServices => new RequestContextFactory(lspServices));
        AddLazyService<AbstractTelemetryService>(lspServices => new TelemetryService(lspServices));
        AddLazyService<AbstractHandlerProvider>(_ => HandlerProvider);
        AddService<IInitializeManager>(new InitializeManager());
        AddService<IMethodHandler>(new InitializeHandler());
        AddService<IMethodHandler>(new InitializedHandler());
        AddService<IOnInitialized>(this);
        AddService<ILanguageInfoProvider>(new LanguageInfoProvider());

        // In all VS cases, we already have a misc workspace.  Specifically
        // Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.MiscellaneousFilesWorkspace.  In
        // those cases, we do not need to add an additional workspace to manage new files we hear about.  So only
        // add the LspMiscellaneousFilesWorkspace for hosts that have not already brought their own.
        if (serverKind == WellKnownLspServerKinds.CSharpVisualBasicLspServer)
            AddLazyService<ILspMiscellaneousFilesWorkspaceProvider>(lspServices => lspServices.GetRequiredService<ILspMiscellaneousFilesWorkspaceProviderFactory>().CreateLspMiscellaneousFilesWorkspaceProvider(lspServices, hostServices));

        return baseServiceMap.ToFrozenDictionary(
            keySelector: kvp => kvp.Key,
            elementSelector: kvp => kvp.Value switch
            {
                BaseService service => [service],
                ImmutableArray<BaseService>.Builder builder => builder.ToImmutable(),
                _ => throw ExceptionUtilities.Unreachable()
            });

        void AddService<T>(T instance)
            where T : class
        {
            AddBaseService(BaseService.Create(instance));
        }

Review comment (bug):
Want to do Environment.Exit() and we can return some error code, so if we ever were to see that failure we can better understand why our process exited?

Code after:
            return false;

        _ = WaitForClientProcessExitAsync(s_clientProcessId);
        return true;

        static async Task WaitForClientProcessExitAsync(int clientProcessId)
        {
            try
            {
                var clientProcessExitTask = new TaskCompletionSource<bool>();

                using var clientProcess = Process.GetProcessById(clientProcessId);
                clientProcess.EnableRaisingEvents = true;
                clientProcess.Exited += (sender, args) => clientProcessExitTask.SetResult(true);

                if (!clientProcess.HasExited)
                {
                    // Wait for the client process to exit.
                    await clientProcessExitTask.Task.ConfigureAwait(false);
                }
            }
            finally
            {
                // The process didn't exist, exited, or we ran into
                // issues checking whether the process had exited.
                Process.GetCurrentProcess().Kill();
            }
        }
    }

    public static SystemTextJsonFormatter CreateJsonMessageFormatter()
    {
        var messageFormatter = new SystemTextJsonFormatter();
        messageFormatter.JsonSerializerOptions.AddLspSerializerOptions();
        return messageFormatter;
    }

    protected override ILspServices ConstructLspServices()
    {
        return _lspServiceProvider.CreateServices(_serverKind, _baseServices);
    }

    protected override IRequestExecutionQueue<RequestContext> ConstructRequestExecutionQueue()
    {
        var provider = GetLspServices().GetRequiredService<IRequestExecutionQueueProvider<RequestContext>>();
        return provider.CreateRequestExecutionQueue(this, Logger, HandlerProvider);
    }

    private FrozenDictionary<string, ImmutableArray<BaseService>> GetBaseServices(
        JsonRpc jsonRpc,
        AbstractLspLogger logger,