File: Workspace\VisualStudioDocumentTrackingServiceFactory.cs
Web Access
Project: src\src\VisualStudio\Core\Def\Microsoft.VisualStudio.LanguageServices_4volmoxl_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices)
// 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.Collections.Immutable;
using System.Composition;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation;
 
[ExportWorkspaceServiceFactory(typeof(IDocumentTrackingService), ServiceLayer.Host), Shared]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class VisualStudioDocumentTrackingServiceFactory(VisualStudioActiveDocumentTracker activeDocumentTracker) : IWorkspaceServiceFactory
{
    public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
        => new VisualStudioDocumentTrackingService(activeDocumentTracker, workspaceServices.Workspace);
 
    private class VisualStudioDocumentTrackingService(VisualStudioActiveDocumentTracker activeDocumentTracker, Workspace workspace) : IDocumentTrackingService
    {
        private readonly VisualStudioActiveDocumentTracker _activeDocumentTracker = activeDocumentTracker;
        private readonly Workspace _workspace = workspace;
        private readonly object _gate = new();
        private int _subscriptions = 0;
        private EventHandler<DocumentId?>? _activeDocumentChangedEventHandler;
 
        public event EventHandler<DocumentId?> ActiveDocumentChanged
        {
            add
            {
                lock (_gate)
                {
                    _subscriptions++;
 
                    if (_subscriptions == 1)
                    {
                        _activeDocumentTracker.DocumentsChanged += ActiveDocumentTracker_DocumentsChanged;
                    }
 
                    _activeDocumentChangedEventHandler += value;
                }
            }
 
            remove
            {
                lock (_gate)
                {
                    _activeDocumentChangedEventHandler -= value;
 
                    _subscriptions--;
 
                    if (_subscriptions == 0)
                    {
                        _activeDocumentTracker.DocumentsChanged -= ActiveDocumentTracker_DocumentsChanged;
                    }
                }
            }
        }
 
        private void ActiveDocumentTracker_DocumentsChanged(object? sender, EventArgs e)
            => _activeDocumentChangedEventHandler?.Invoke(this, TryGetActiveDocument());
 
        public DocumentId? TryGetActiveDocument()
            => _activeDocumentTracker.TryGetActiveDocument(_workspace);
 
        public ImmutableArray<DocumentId> GetVisibleDocuments()
            => _activeDocumentTracker.GetVisibleDocuments(_workspace);
    }
}