Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close info bars when associated project(s) unload #9608

Merged
merged 13 commits into from
Dec 3, 2024

Conversation

drewnoakes
Copy link
Member

@drewnoakes drewnoakes commented Dec 2, 2024

Previously, info bars would remain in VS after solution close, or after project unload. This can lead to confusion when opening a new solution and seeing an error message from the previously open solution.

This change keeps track of which project(s) are associated with each info bar, and monitors the unload event of those projects. Now, when a project unloads, it will remove the info bar if no other remaining projects are also associated with that info bar.

The code was refactored a fair bit, reducing the number of source files. Quite a few refactorings are in their own commits to make review easier. The main change is in 66270de.

clear-info-bar-on-solution-change

Microsoft Reviewers: Open in CodeFlow

These internal types don't need runtime null checks. We have annotations to validate that non-null values are passed where needed.
Previously, info bars would remain in VS after solution close, or after project unload. This can lead to confusion when opening a new solution and seeing an error message from the previously open solution.

This change keeps track of which project(s) are associated with each info bar, and monitors the unload event of those projects. Now, when a project unloads, it will remove the info bar if no other remaining projects are also associated with that info bar.
@drewnoakes drewnoakes requested a review from a team as a code owner December 2, 2024 11:22
@@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.Notifications;
/// <summary>
/// Provides methods for displaying non-blocking notifications to the user.
/// </summary>
[ProjectSystemContract(ProjectSystemContractScope.ProjectService, ProjectSystemContractProvider.Private, Cardinality = ImportCardinality.ExactlyOne)]
[ProjectSystemContract(ProjectSystemContractScope.UnconfiguredProject, ProjectSystemContractProvider.Private, Cardinality = ImportCardinality.ExactlyOne)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between these two scope, and why we need to use UnconfiguredProject here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several MEF scopes. Global, ProjectServices (similar to global), UnconfiguredProject and ConfiguredProject. There's only one instance of Global and ProjectServices, and there are potentially many instances of UnconfiguredProject and ConfiguredProject.

A component that lives inside UnconfiguredProject is created for each project.

So this change means that the component is now created for every project. Note that this attribute doesn't control the scopes, it just documents it. What actually changes the scope is the ImportingConstructor argument list. This PR adds an import of UnconfiguredProject, which forces the component to move from an outer scope to the inner scope.

Now that the component has access to a project, we can register the infobars against those projects.

That's a brief discussion of scopes. There's more to say on the topic. We have some docs for scopes in https://github.com/microsoft/VSProjectSystem/blob/master/doc/overview/scopes.md but I don't think they are as helpful as they could be. I hope to improve them some time.


public async Task ShowInfoBarAsync(string message, ImageMoniker image, CancellationToken cancellationToken, params ImmutableArray<InfoBarAction> actions)
{
if (await _vsShellServices.IsCommandLineModeAsync(cancellationToken))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's command line mode in VS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you run devenv /build MySolution.sln then VS runs without any UI and builds the solution. We call this "command line mode" and there's no UI. We track this in several places to both:

  • Improve performance (avoiding work when there's no UI)
  • Prevent hangs (due to waiting for things that will never be available in this mode)

@@ -1,6 +1,7 @@
appsettings
args
async
asynch
Copy link
Contributor

@LittleLittleCloud LittleLittleCloud Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change necessary? Looks like asynch is not used anywhere in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not in this PR but it is in a class I was looking at. I generally add words when I find them, to avoiding having warnings in the editor in VS.

Comment on lines +30 to +31
public VsInfoBarService(
UnconfiguredProject project,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LittleLittleCloud this is the actual change that moves the scope of the MEF component into UnconfiguredProject scope. The previous service only imported from the Glboal and ProjectServices scopes. Now we import UnconfiguredProject, so we're moved into that scope.

@drewnoakes drewnoakes merged commit 079fefc into dotnet:main Dec 3, 2024
5 checks passed
@drewnoakes drewnoakes deleted the close-info-bars-on-project-close branch December 3, 2024 06:35
@dotnet-policy-service dotnet-policy-service bot added this to the 17.12 milestone Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants