src/Microsoft.VisualStudio.ProjectSystem.Managed/Tree/Dependencies/Subscriptions/RuleHandlers/ProjectRuleHandler.cs
/// <summary>
/// When some other project's snapshot changed we need to check if our snapshot has a top level
/// dependency on changed project. If it does we need to refresh those top level dependencies to 
/// reflect changes.
/// </summary>
/// <param name="thisProjectSnapshot"></param>
/// <param name="otherProjectSnapshot"></param>
/// <param name="shouldBeResolved">
/// Specifies if top-level project dependencies resolved status. When other project just had its dependencies
/// changed, it is resolved=true (we check target's support when we add project dependencies). However when 
/// other project is unloaded, we should mark top-level dependencies as unresolved.
/// </param>
/// <param name="token"></param>
When some other project's snapshot changed we need to check if our snapshot has a top level
dependency on changed project. If it does we need to refresh those top level dependencies to
reflect changes.
When some other project ' s snapshot changed we need to check if our snapshot has a top level dependency on changed project . If it does we need to refresh those top level dependencies to reflect changes .
private void OnOtherProjectDependenciesChanged(
            DependenciesSnapshot thisProjectSnapshot,
            DependenciesSnapshot otherProjectSnapshot,
            bool shouldBeResolved,
            CancellationToken token)
        {
            if (token.IsCancellationRequested ||
                StringComparers.Paths.Equals(thisProjectSnapshot.ProjectPath, otherProjectSnapshot.ProjectPath))
            {
                return;
            }
            string otherProjectPath = otherProjectSnapshot.ProjectPath;
            foreach ((ITargetFramework _, TargetedDependenciesSnapshot targetedDependencies) in thisProjectSnapshot.DependenciesByTargetFramework)
            {
                foreach (IDependency dependency in targetedDependencies.TopLevelDependencies)
                {
                    if (token.IsCancellationRequested)
                        return;
                    if (!StringComparers.DependencyProviderTypes.Equals(dependency.ProviderType, ProviderTypeString))
                        continue;
                    if (!StringComparers.Paths.Equals(otherProjectPath, dependency.FullPath))
                        continue;
                    RaiseChangeEvent(dependency);
                    break;
                }
            }
            return;
            void RaiseChangeEvent(IDependency dependency)
            {
                IDependencyModel model = CreateDependencyModel(
                    dependency.Path,
                    dependency.OriginalItemSpec,
                    shouldBeResolved,
                    dependency.Implicit,
                    dependency.BrowseObjectProperties);
                var changes = new DependenciesChangesBuilder();
                if (!shouldBeResolved)
                {
                    changes.Removed(ProviderTypeString, model.Id);
                }
                changes.Added(model);
                FireDependenciesChanged(
                    new DependenciesChangedEventArgs(
                        this,
                        dependency.TargetFramework.FullName,
                        changes.TryBuildChanges()!,
                        token));
            }
        }
private void OnOtherProjectDependenciesChanged ( DependenciesSnapshot thisProjectSnapshot , DependenciesSnapshot otherProjectSnapshot , bool shouldBeResolved , CancellationToken token ) { if ( token . IsCancellationRequested || StringComparers . Paths . Equals ( thisProjectSnapshot . ProjectPath , otherProjectSnapshot . ProjectPath ) ) { return ; } string otherProjectPath = otherProjectSnapshot . ProjectPath ; foreach ( ( ITargetFramework _ , TargetedDependenciesSnapshot targetedDependencies ) in thisProjectSnapshot . DependenciesByTargetFramework ) { foreach ( IDependency dependency in targetedDependencies . TopLevelDependencies ) { if ( token . IsCancellationRequested ) return ; if ( ! StringComparers . DependencyProviderTypes . Equals ( dependency . ProviderType , ProviderTypeString ) ) continue ; if ( ! StringComparers . Paths . Equals ( otherProjectPath , dependency . FullPath ) ) continue ; RaiseChangeEvent ( dependency ) ; break ; } } return ; void RaiseChangeEvent ( IDependency dependency ) { IDependencyModel model = CreateDependencyModel ( dependency . Path , dependency . OriginalItemSpec , shouldBeResolved , dependency . Implicit , dependency . BrowseObjectProperties ) ; var changes = new DependenciesChangesBuilder ( ) ; if ( ! shouldBeResolved ) { changes . Removed ( ProviderTypeString , model . Id ) ; } changes . Added ( model ) ; FireDependenciesChanged ( new DependenciesChangedEventArgs ( this , dependency . TargetFramework . FullName , changes . TryBuildChanges ( ) ! , token ) ) ; } }
When some other project's snapshot changed we need to check if our snapshot has a top level
dependency on changed project.
When some other project ' s snapshot changed we need to check if our snapshot has a top level dependency on changed project .
// if any of the snapshots is not provided or this is the same project - skip // We're only interested in project dependencies // avoid unnecessary removing since, add would upgrade dependency in snapshot anyway, // but remove would require removing item from the tree instead of in-place upgrade.
thisProjectSnapshot
DependenciesSnapshot
None
otherProjectSnapshot
DependenciesSnapshot
None
shouldBeResolved
bool
Specifies if top-level project dependencies resolved status. When other project just had its dependencies
changed, it is resolved=true (we check target's support when we add project dependencies). However when
other project is unloaded, we should mark top-level dependencies as unresolved.
Specifies if top - level project dependencies resolved status . When other project just had its dependencies changed it is resolved = true ( we check target ' s support when we add project dependencies ) . However when other project is unloaded we should mark top - level dependencies as unresolved .
token
CancellationToken
None