public DependenciesProjectTreeProvider(
            IProjectThreadingService threadingService,
            UnconfiguredProject project,
            IProjectAccessor projectAccessor,
            UnconfiguredProject unconfiguredProject,
            DependenciesSnapshotProvider dependenciesSnapshotProvider,
            [Import(ExportContractNames.Scopes.UnconfiguredProject)] IProjectAsynchronousTasksService tasksService,
            IDependencyTreeTelemetryService treeTelemetryService)
            : base(threadingService, unconfiguredProject)
        {
            _projectTreePropertiesProviders = new OrderPrecedenceImportCollection <IProjectTreePropertiesProvider>(
                ImportOrderPrecedenceComparer.PreferenceOrder.PreferredComesLast,
                projectCapabilityCheckProvider: unconfiguredProject);

            _viewProviders = new OrderPrecedenceImportCollection <IDependenciesTreeViewProvider>(
                ImportOrderPrecedenceComparer.PreferenceOrder.PreferredComesFirst,
                projectCapabilityCheckProvider: unconfiguredProject);

            _dependenciesSnapshotProvider = dependenciesSnapshotProvider;
            _tasksService         = tasksService;
            _project              = project;
            _projectAccessor      = projectAccessor;
            _treeTelemetryService = treeTelemetryService;

            // Hook this so we can unregister the snapshot change event when the project unloads
            unconfiguredProject.ProjectUnloading += OnUnconfiguredProjectUnloading;

            Task OnUnconfiguredProjectUnloading(object?sender, EventArgs args)
            {
                UnconfiguredProject.ProjectUnloading -= OnUnconfiguredProjectUnloading;
                _snapshotEventListener?.Dispose();

                return(Task.CompletedTask);
            }
        }
        public ProjectRuleHandler(
            IAggregateDependenciesSnapshotProvider aggregateSnapshotProvider,
            DependenciesSnapshotProvider snapshotProvider,
            IUnconfiguredProjectCommonServices commonServices)
            : base(ProjectReference.SchemaName, ResolvedProjectReference.SchemaName)
        {
            aggregateSnapshotProvider.SnapshotChanged           += OnAggregateSnapshotChanged;
            aggregateSnapshotProvider.SnapshotProviderUnloading += OnAggregateSnapshotProviderUnloading;

            // Unregister event handlers when the project unloads
            commonServices.Project.ProjectUnloading += OnUnconfiguredProjectUnloading;

            return;

            Task OnUnconfiguredProjectUnloading(object sender, EventArgs e)
            {
                commonServices.Project.ProjectUnloading             -= OnUnconfiguredProjectUnloading;
                aggregateSnapshotProvider.SnapshotChanged           -= OnAggregateSnapshotChanged;
                aggregateSnapshotProvider.SnapshotProviderUnloading -= OnAggregateSnapshotProviderUnloading;

                return(Task.CompletedTask);
            }

            void OnAggregateSnapshotChanged(object sender, SnapshotChangedEventArgs e)
            {
                OnOtherProjectDependenciesChanged(snapshotProvider.CurrentSnapshot, e.Snapshot, shouldBeResolved: true, e.Token);
            }

            void OnAggregateSnapshotProviderUnloading(object sender, SnapshotProviderUnloadingEventArgs e)
            {
                OnOtherProjectDependenciesChanged(snapshotProvider.CurrentSnapshot, e.SnapshotProvider.CurrentSnapshot, shouldBeResolved: false, e.Token);
            }
        }
Beispiel #3
0
 public DependencySharedProjectsSubscriber(
     IProjectThreadingService threadingService,
     IUnconfiguredProjectTasksService tasksService,
     DependenciesSnapshotProvider dependenciesSnapshotProvider)
     : base(threadingService, tasksService)
 {
     _dependenciesSnapshotProvider = dependenciesSnapshotProvider;
 }
        public ProjectRuleHandler(
            IAggregateDependenciesSnapshotProvider aggregateSnapshotProvider,
            DependenciesSnapshotProvider snapshotProvider,
            IUnconfiguredProjectCommonServices commonServices,
            [Import(AllowDefault = true)] ISolutionService?solutionService)
            : base(ProjectReference.SchemaName, ResolvedProjectReference.SchemaName)
        {
            aggregateSnapshotProvider.SnapshotChanged           += OnAggregateSnapshotChanged;
            aggregateSnapshotProvider.SnapshotProviderUnloading += OnAggregateSnapshotProviderUnloading;

            // Unregister event handlers when the project unloads
            commonServices.Project.ProjectUnloading += OnUnconfiguredProjectUnloading;

            return;

            Task OnUnconfiguredProjectUnloading(object sender, EventArgs e)
            {
                commonServices.Project.ProjectUnloading             -= OnUnconfiguredProjectUnloading;
                aggregateSnapshotProvider.SnapshotChanged           -= OnAggregateSnapshotChanged;
                aggregateSnapshotProvider.SnapshotProviderUnloading -= OnAggregateSnapshotProviderUnloading;

                return(Task.CompletedTask);
            }

            void OnAggregateSnapshotChanged(object sender, SnapshotChangedEventArgs e)
            {
                OnOtherProjectDependenciesChanged(snapshotProvider.CurrentSnapshot, e.Snapshot, shouldBeResolved: true, e.Token);
            }

            void OnAggregateSnapshotProviderUnloading(object sender, SnapshotProviderUnloadingEventArgs e)
            {
                // Only notify if the solution is not closing.
                // If it is closing, notifying would result in pointless updates.
                // If the solution service is unavailable, always update.
                if (solutionService?.IsSolutionClosing != true)
                {
                    OnOtherProjectDependenciesChanged(snapshotProvider.CurrentSnapshot, e.SnapshotProvider.CurrentSnapshot, shouldBeResolved: false, e.Token);
                }
            }
        }
Beispiel #5
0
        public IDisposable RegisterSnapshotProvider(DependenciesSnapshotProvider snapshotProvider)
        {
            Requires.NotNull(snapshotProvider, nameof(snapshotProvider));

            var unregister = new DisposableBag();

            lock (_lock)
            {
                snapshotProvider.SnapshotRenamed           += OnSnapshotRenamed;
                snapshotProvider.SnapshotProviderUnloading += OnSnapshotProviderUnloading;

                ITargetBlock <SnapshotChangedEventArgs> actionBlock = DataflowBlockSlim.CreateActionBlock <SnapshotChangedEventArgs>(
                    e => SnapshotChanged?.Invoke(this, e),
                    "AggregateDependenciesSnapshotProviderSource {1}",
                    skipIntermediateInputData: true);

                unregister.Add(
                    snapshotProvider.SnapshotChangedSource.LinkTo(
                        actionBlock,
                        DataflowOption.PropagateCompletion));

                _snapshotProviderByPath = _snapshotProviderByPath.SetItem(snapshotProvider.CurrentSnapshot.ProjectPath, snapshotProvider);
            }

            unregister.Add(new DisposableDelegate(
                               () =>
            {
                lock (_lock)
                {
                    string projectPath                          = snapshotProvider.CurrentSnapshot.ProjectPath;
                    _snapshotProviderByPath                     = _snapshotProviderByPath.Remove(projectPath);
                    snapshotProvider.SnapshotRenamed           -= OnSnapshotRenamed;
                    snapshotProvider.SnapshotProviderUnloading -= OnSnapshotProviderUnloading;
                }
            }));

            return(unregister);

            void OnSnapshotProviderUnloading(object sender, SnapshotProviderUnloadingEventArgs e)
            {
                // Project has unloaded, so remove it from the cache and unregister event handlers
                SnapshotProviderUnloading?.Invoke(this, e);

                unregister.Dispose();
            }

            void OnSnapshotRenamed(object sender, ProjectRenamedEventArgs e)
            {
                if (string.IsNullOrEmpty(e.OldFullPath))
                {
                    return;
                }

                lock (_lock)
                {
                    // Remove and re-add provider with new project path
                    if (_snapshotProviderByPath.TryGetValue(e.OldFullPath, out DependenciesSnapshotProvider provider))
                    {
                        _snapshotProviderByPath = _snapshotProviderByPath.Remove(e.OldFullPath);

                        if (!string.IsNullOrEmpty(e.NewFullPath))
                        {
                            _snapshotProviderByPath = _snapshotProviderByPath.SetItem(e.NewFullPath, provider);
                        }
                    }
                }
            }
        }