private void ProcessSharedProjectsUpdates( IProjectSharedFoldersSnapshot sharedFolders, TargetFramework targetFramework, DependenciesChangesBuilder changesBuilder) { Requires.NotNull(sharedFolders, nameof(sharedFolders)); Requires.NotNull(targetFramework, nameof(targetFramework)); Requires.NotNull(changesBuilder, nameof(changesBuilder)); DependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot; if (!snapshot.DependenciesByTargetFramework.TryGetValue(targetFramework, out TargetedDependenciesSnapshot? targetedSnapshot)) { return; } IEnumerable <string> sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath); var currentSharedImportNodePaths = targetedSnapshot.Dependencies .Where(pair => pair.Flags.Contains(DependencyTreeFlags.SharedProjectDependency)) .Select(pair => pair.FilePath !) .ToList(); var diff = new SetDiff <string>(currentSharedImportNodePaths, sharedFolderProjectPaths); // process added nodes foreach (string addedSharedImportPath in diff.Added) { IDependencyModel added = new SharedProjectDependencyModel( addedSharedImportPath, addedSharedImportPath, isResolved: true, isImplicit: false, properties: ImmutableStringDictionary <string> .EmptyOrdinal); changesBuilder.Added(targetFramework, added); } // process removed nodes foreach (string removedSharedImportPath in diff.Removed) { bool exists = currentSharedImportNodePaths.Any(nodePath => PathHelper.IsSamePath(nodePath, removedSharedImportPath)); if (exists) { changesBuilder.Removed( targetFramework, ProjectRuleHandler.ProviderTypeString, dependencyId: removedSharedImportPath); } } }
protected override void Handle( AggregateCrossTargetProjectContext currentAggregateContext, TargetFramework targetFrameworkToUpdate, EventData e) { IProjectSharedFoldersSnapshot sharedProjectsUpdate = e.Item2; IProjectCatalogSnapshot catalogs = e.Item3; var changesBuilder = new DependenciesChangesBuilder(); ProcessSharedProjectsUpdates(sharedProjectsUpdate, targetFrameworkToUpdate, changesBuilder); IDependenciesChanges?changes = changesBuilder.TryBuildChanges(); if (changes != null) { RaiseDependenciesChanged(targetFrameworkToUpdate, changes, currentAggregateContext, catalogs); } }
protected override void Handle( AggregateCrossTargetProjectContext currentAggregateContext, TargetFramework targetFrameworkToUpdate, EventData e) { IProjectSubscriptionUpdate projectUpdate = e.Item1; IProjectCatalogSnapshot catalogSnapshot = e.Item2; // Broken design time builds sometimes cause updates with no project changes and sometimes // cause updates with a project change that has no difference. // We handle the former case here, and the latter case is handled in the CommandLineItemHandler. if (projectUpdate.ProjectChanges.Count == 0) { return; } if (!projectUpdate.ProjectChanges.Any(x => x.Value.Difference.AnyChanges)) { return; } // Create an object to track dependency changes. var changesBuilder = new DependenciesChangesBuilder(); // Give each handler a chance to register dependency changes. foreach (Lazy <IDependenciesRuleHandler, IOrderPrecedenceMetadataView> handler in _handlers) { handler.Value.Handle(projectUpdate.ProjectChanges, targetFrameworkToUpdate, changesBuilder); } IDependenciesChanges?changes = changesBuilder.TryBuildChanges(); // Notify subscribers of a change in dependency data. // NOTE even if changes is null, it's possible the catalog has changed. If we don't take the newer // catalog we end up retaining a reference to an old catalog, which in turn retains an old project // instance which can be very large. RaiseDependenciesChanged(targetFrameworkToUpdate, changes, currentAggregateContext, catalogSnapshot); // Record all the rules that have occurred _treeTelemetryService.ObserveTargetFrameworkRules(targetFrameworkToUpdate, projectUpdate.ProjectChanges.Keys); }
protected override void Handle( string projectFullPath, AggregateCrossTargetProjectContext currentAggregateContext, TargetFramework targetFrameworkToUpdate, EventData e) { IProjectSubscriptionUpdate projectUpdate = e.Item1; IProjectCatalogSnapshot catalogSnapshot = e.Item2; // Broken design-time builds can produce updates containing no rule data. // Later code assumes that the requested rules are available. // If we see no rule data, return now. if (projectUpdate.ProjectChanges.Count == 0) { return; } // Create an object to track dependency changes. var changesBuilder = new DependenciesChangesBuilder(); // Give each handler a chance to register dependency changes. foreach (Lazy <IDependenciesRuleHandler, IOrderPrecedenceMetadataView> handler in _handlers) { IProjectChangeDescription evaluation = projectUpdate.ProjectChanges[handler.Value.EvaluatedRuleName]; IProjectChangeDescription?build = projectUpdate.ProjectChanges.GetValueOrDefault(handler.Value.ResolvedRuleName); handler.Value.Handle(projectFullPath, evaluation, build, targetFrameworkToUpdate, changesBuilder); } IDependenciesChanges?changes = changesBuilder.TryBuildChanges(); // Notify subscribers of a change in dependency data. // NOTE even if changes is null, it's possible the catalog has changed. If we don't take the newer // catalog we end up retaining a reference to an old catalog, which in turn retains an old project // instance which can be very large. RaiseDependenciesChanged(targetFrameworkToUpdate, changes, currentAggregateContext, catalogSnapshot); // Record all the rules that have occurred _treeTelemetryService.ObserveTargetFrameworkRules(targetFrameworkToUpdate, projectUpdate.ProjectChanges.Keys); }
public override string ToString() => DependenciesChangesBuilder.ToString(AddedNodes, RemovedNodes);