private void ProcessSharedProjectsUpdates( IProjectSharedFoldersSnapshot sharedFolders, ITargetedProjectContext targetContext, DependenciesRuleChangeContext dependencyChangeContext) { Requires.NotNull(sharedFolders, nameof(sharedFolders)); Requires.NotNull(targetContext, nameof(targetContext)); Requires.NotNull(dependencyChangeContext, nameof(dependencyChangeContext)); IDependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot; if (!snapshot.Targets.TryGetValue(targetContext.TargetFramework, out ITargetedDependenciesSnapshot targetedSnapshot)) { return; } IEnumerable <string> sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath); var currentSharedImportNodes = targetedSnapshot.TopLevelDependencies .Where(x => x.Flags.Contains(DependencyTreeFlags.SharedProjectFlags)) .ToList(); IEnumerable <string> currentSharedImportNodePaths = currentSharedImportNodes.Select(x => x.Path); // process added nodes IEnumerable <string> addedSharedImportPaths = sharedFolderProjectPaths.Except(currentSharedImportNodePaths); foreach (string addedSharedImportPath in addedSharedImportPaths) { IDependencyModel added = new SharedProjectDependencyModel( addedSharedImportPath, addedSharedImportPath, isResolved: true, isImplicit: false, properties: ImmutableStringDictionary <string> .EmptyOrdinal); dependencyChangeContext.IncludeAddedChange(targetContext.TargetFramework, added); } // process removed nodes IEnumerable <string> removedSharedImportPaths = currentSharedImportNodePaths.Except(sharedFolderProjectPaths); foreach (string removedSharedImportPath in removedSharedImportPaths) { bool exists = currentSharedImportNodes.Any(node => PathHelper.IsSamePath(node.Path, removedSharedImportPath)); if (exists) { dependencyChangeContext.IncludeRemovedChange( targetContext.TargetFramework, ProjectRuleHandler.ProviderTypeString, dependencyId: removedSharedImportPath); } } }
private void ProcessSharedProjectsUpdates( IProjectSharedFoldersSnapshot sharedFolders, ITargetedProjectContext targetContext, DependenciesRuleChangeContext dependencyChangeContext) { Requires.NotNull(sharedFolders, nameof(sharedFolders)); Requires.NotNull(targetContext, nameof(targetContext)); Requires.NotNull(dependencyChangeContext, nameof(dependencyChangeContext)); IDependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot; if (!snapshot.Targets.TryGetValue(targetContext.TargetFramework, out ITargetedDependenciesSnapshot targetedSnapshot)) { return; } IEnumerable <string> sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath); var currentSharedImportNodes = targetedSnapshot.TopLevelDependencies .Where(x => x.Flags.Contains(DependencyTreeFlags.SharedProjectFlags)) .ToList(); IEnumerable <string> currentSharedImportNodePaths = currentSharedImportNodes.Select(x => x.Path); // process added nodes IEnumerable <string> addedSharedImportPaths = sharedFolderProjectPaths.Except(currentSharedImportNodePaths); foreach (string addedSharedImportPath in addedSharedImportPaths) { IDependencyModel added = CreateDependencyModel(addedSharedImportPath, targetContext.TargetFramework, resolved: true); dependencyChangeContext.IncludeAddedChange(targetContext.TargetFramework, added); } // process removed nodes IEnumerable <string> removedSharedImportPaths = currentSharedImportNodePaths.Except(sharedFolderProjectPaths); foreach (string removedSharedImportPath in removedSharedImportPaths) { IDependency existingImportNode = currentSharedImportNodes .Where(node => PathHelper.IsSamePath(node.Path, removedSharedImportPath)) .FirstOrDefault(); if (existingImportNode != null) { IDependencyModel removed = CreateDependencyModel(removedSharedImportPath, targetContext.TargetFramework, resolved: true); dependencyChangeContext.IncludeRemovedChange(targetContext.TargetFramework, removed); } } }
private async Task HandleAsync(Tuple <IProjectSubscriptionUpdate, IProjectSharedFoldersSnapshot, IProjectCatalogSnapshot> e) { AggregateCrossTargetProjectContext currentAggregateContext = await _host.GetCurrentAggregateProjectContext(); if (currentAggregateContext == null) { return; } IProjectSubscriptionUpdate projectUpdate = e.Item1; IProjectSharedFoldersSnapshot sharedProjectsUpdate = e.Item2; IProjectCatalogSnapshot catalogs = e.Item3; // We need to process the update within a lock to ensure that we do not release this context during processing. // TODO: Enable concurrent execution of updates themselves, i.e. two separate invocations of HandleAsync // should be able to run concurrently. using (await _gate.DisposableWaitAsync()) { // Get the inner workspace project context to update for this change. ITargetedProjectContext projectContextToUpdate = currentAggregateContext .GetInnerProjectContext(projectUpdate.ProjectConfiguration, out bool isActiveContext); if (projectContextToUpdate == null) { return; } var dependencyChangeContext = new DependenciesRuleChangeContext( currentAggregateContext.ActiveProjectContext.TargetFramework, catalogs); ProcessSharedProjectsUpdates(sharedProjectsUpdate, projectContextToUpdate, dependencyChangeContext); if (dependencyChangeContext.AnyChanges) { DependenciesChanged?.Invoke(this, new DependencySubscriptionChangedEventArgs(dependencyChangeContext)); } } }