protected IDependenciesGraphViewProvider FindViewProvider(IDependency dependency) { return(_viewProviders.FirstOrDefaultValue((x, d) => x.SupportsDependency(d), dependency)); }
/// <summary> /// ProjectContextChanged gets fired every time dependencies change for projects across solution. /// <see cref="_expandedGraphContexts"/> contains all nodes that we need to check for potential updates /// in their child dependencies. /// </summary> private void OnSnapshotChanged(object sender, SnapshotChangedEventArgs e) { DependenciesSnapshot snapshot = e.Snapshot; if (snapshot == null || e.Token.IsCancellationRequested) { return; } // _expandedGraphContexts remembers graph expanded or checked so far. // Each context represents one level in the graph, i.e. a node and its first level dependencies // Tracking changes over all expanded contexts ensures that all levels are processed // and updated when there are any changes in nodes data. lock (_lock) { foreach (IGraphContext graphContext in _expandedGraphContexts) { if (e.Token.IsCancellationRequested) { return; } bool anyChanges = false; try { if (HandleChanges(graphContext)) { anyChanges = true; } } finally { // Calling OnCompleted ensures that the changes are reflected in UI if (anyChanges) { graphContext.OnCompleted(); } } } } return; bool HandleChanges(IGraphContext graphContext) { bool anyChanges = false; foreach (GraphNode inputGraphNode in graphContext.InputNodes.ToList()) { string?existingDependencyId = inputGraphNode.GetValue <string>(DependenciesGraphSchema.DependencyIdProperty); if (string.IsNullOrEmpty(existingDependencyId)) { continue; } string?nodeProjectPath = inputGraphNode.Id.GetValue(CodeGraphNodeIdName.Assembly); if (Strings.IsNullOrEmpty(nodeProjectPath)) { continue; } DependenciesSnapshot?updatedSnapshot = _aggregateSnapshotProvider.GetSnapshot(nodeProjectPath); IDependency?updatedDependency = updatedSnapshot?.FindDependency(existingDependencyId); if (updatedDependency == null) // or updatedSnapshot == null { continue; } IDependenciesGraphViewProvider?viewProvider = _viewProviders .FirstOrDefaultValue((x, d) => x.SupportsDependency(d), updatedDependency); if (viewProvider == null) { continue; } if (!viewProvider.ShouldApplyChanges(nodeProjectPath, snapshot.ProjectPath, updatedDependency)) { continue; } using var scope = new GraphTransactionScope(); if (viewProvider.ApplyChanges( graphContext, nodeProjectPath, updatedDependency, inputGraphNode, updatedSnapshot !.DependenciesByTargetFramework[updatedDependency.TargetFramework])) { anyChanges = true; } scope.Complete(); } return(anyChanges); } }