Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit d69a629

Browse files
authored
Merge pull request #1569 from github/fixes/1550-async-initialize-GitHubPane
Initialize GitHubPane and menus asynchronously
2 parents 5321090 + 39d77aa commit d69a629

File tree

9 files changed

+116
-90
lines changed

9 files changed

+116
-90
lines changed

src/GitHub.Exports/Settings/Guids.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static class Guids
1313
public const string CodeContainerProviderId = "6CE146CB-EF57-4F2C-A93F-5BA685317660";
1414
public const string InlineReviewsPackageId = "248325BE-4A2D-4111-B122-E7D59BF73A35";
1515
public const string PullRequestStatusPackageId = "5121BEC6-1088-4553-8453-0DDC7C8E2238";
16+
public const string GitHubPanePackageId = "0A40459D-6B6D-4110-B6CE-EC83C0BC6A09";
1617
public const string TeamExplorerWelcomeMessage = "C529627F-8AA6-4FDB-82EB-4BFB7DB753C3";
1718
public const string LoginManagerId = "7BA2071A-790A-4F95-BE4A-0EEAA5928AAF";
1819

src/GitHub.InlineReviews/InlineReviewsPackage.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ protected override async Task InitializeAsync(
3535

3636
async Task InitializeMenus()
3737
{
38-
var menuService = (IMenuCommandService)(await GetServiceAsync(typeof(IMenuCommandService)));
3938
var componentModel = (IComponentModel)(await GetServiceAsync(typeof(SComponentModel)));
4039
var exports = componentModel.DefaultExportProvider;
40+
var commands = new IVsCommandBase[]
41+
{
42+
exports.GetExportedValue<INextInlineCommentCommand>(),
43+
exports.GetExportedValue<IPreviousInlineCommentCommand>()
44+
};
4145

4246
await JoinableTaskFactory.SwitchToMainThreadAsync();
43-
menuService.AddCommands(
44-
exports.GetExportedValue<INextInlineCommentCommand>(),
45-
exports.GetExportedValue<IPreviousInlineCommentCommand>());
47+
var menuService = (IMenuCommandService)(await GetServiceAsync(typeof(IMenuCommandService)));
48+
menuService.AddCommands(commands);
4649
}
4750
}
4851
}

src/GitHub.InlineReviews/PullRequestStatusBarPackage.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
22
using System.Threading;
33
using System.Runtime.InteropServices;
4-
using GitHub.Services;
54
using GitHub.VisualStudio;
65
using GitHub.InlineReviews.Services;
76
using Microsoft.VisualStudio.Shell;
87
using Task = System.Threading.Tasks.Task;
98
using Microsoft.VisualStudio.Threading;
9+
using Microsoft.VisualStudio.ComponentModelHost;
1010

1111
namespace GitHub.InlineReviews
1212
{
@@ -27,9 +27,9 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
2727

2828
async Task InitializeStatusBar()
2929
{
30-
var usageTracker = (IUsageTracker)await GetServiceAsync(typeof(IUsageTracker));
31-
var serviceProvider = (IGitHubServiceProvider)await GetServiceAsync(typeof(IGitHubServiceProvider));
32-
var barManager = new PullRequestStatusBarManager(usageTracker, serviceProvider);
30+
var componentModel = (IComponentModel)(await GetServiceAsync(typeof(SComponentModel)));
31+
var exports = componentModel.DefaultExportProvider;
32+
var barManager = exports.GetExportedValue<PullRequestStatusBarManager>();
3333

3434
await JoinableTaskFactory.SwitchToMainThreadAsync();
3535
barManager.StartShowingStatus();
Lines changed: 14 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
using System;
22
using System.Windows;
3-
using System.Windows.Input;
43
using System.Windows.Controls;
54
using System.Windows.Controls.Primitives;
65
using System.ComponentModel.Composition;
6+
using GitHub.Commands;
77
using GitHub.InlineReviews.Views;
88
using GitHub.InlineReviews.ViewModels;
99
using GitHub.Services;
10-
using GitHub.VisualStudio;
1110
using GitHub.Models;
1211
using GitHub.Logging;
13-
using GitHub.Extensions;
1412
using Serilog;
1513
using ReactiveUI;
1614

@@ -19,21 +17,25 @@ namespace GitHub.InlineReviews.Services
1917
/// <summary>
2018
/// Manage the UI that shows the PR for the current branch.
2119
/// </summary>
20+
[Export(typeof(PullRequestStatusBarManager))]
2221
public class PullRequestStatusBarManager
2322
{
2423
static readonly ILogger log = LogManager.ForContext<PullRequestStatusBarManager>();
2524
const string StatusBarPartName = "PART_SccStatusBarHost";
2625

27-
readonly IUsageTracker usageTracker;
28-
readonly IGitHubServiceProvider serviceProvider;
26+
readonly IShowCurrentPullRequestCommand showCurrentPullRequestCommand;
2927

30-
IPullRequestSessionManager pullRequestSessionManager;
28+
// At the moment this must be constructed on the main thread.
29+
// TeamExplorerContext needs to retrieve DTE using GetService.
30+
readonly Lazy<IPullRequestSessionManager> pullRequestSessionManager;
3131

3232
[ImportingConstructor]
33-
public PullRequestStatusBarManager(IUsageTracker usageTracker, IGitHubServiceProvider serviceProvider)
33+
public PullRequestStatusBarManager(
34+
IShowCurrentPullRequestCommand showCurrentPullRequestCommand,
35+
Lazy<IPullRequestSessionManager> pullRequestSessionManager)
3436
{
35-
this.usageTracker = usageTracker;
36-
this.serviceProvider = serviceProvider;
37+
this.showCurrentPullRequestCommand = showCurrentPullRequestCommand;
38+
this.pullRequestSessionManager = pullRequestSessionManager;
3739
}
3840

3941
/// <summary>
@@ -46,8 +48,7 @@ public void StartShowingStatus()
4648
{
4749
try
4850
{
49-
pullRequestSessionManager = serviceProvider.GetService<IPullRequestSessionManager>();
50-
pullRequestSessionManager.WhenAnyValue(x => x.CurrentSession)
51+
pullRequestSessionManager.Value.WhenAnyValue(x => x.CurrentSession)
5152
.Subscribe(x => RefreshCurrentSession());
5253
}
5354
catch (Exception e)
@@ -58,16 +59,14 @@ public void StartShowingStatus()
5859

5960
void RefreshCurrentSession()
6061
{
61-
var pullRequest = pullRequestSessionManager.CurrentSession?.PullRequest;
62+
var pullRequest = pullRequestSessionManager.Value.CurrentSession?.PullRequest;
6263
var viewModel = pullRequest != null ? CreatePullRequestStatusViewModel(pullRequest) : null;
6364
ShowStatus(viewModel);
6465
}
6566

6667
PullRequestStatusViewModel CreatePullRequestStatusViewModel(IPullRequestModel pullRequest)
6768
{
68-
var dte = serviceProvider.TryGetService<EnvDTE.DTE>();
69-
var command = new RaisePullRequestCommand(dte, usageTracker);
70-
var pullRequestStatusViewModel = new PullRequestStatusViewModel(command);
69+
var pullRequestStatusViewModel = new PullRequestStatusViewModel(showCurrentPullRequestCommand);
7170
pullRequestStatusViewModel.Number = pullRequest.Number;
7271
pullRequestStatusViewModel.Title = pullRequest.Title;
7372
return pullRequestStatusViewModel;
@@ -111,44 +110,5 @@ StatusBar FindSccStatusBar(Window mainWindow)
111110
var contentControl = mainWindow?.Template?.FindName(StatusBarPartName, mainWindow) as ContentControl;
112111
return contentControl?.Content as StatusBar;
113112
}
114-
115-
class RaisePullRequestCommand : ICommand
116-
{
117-
readonly string guid = Guids.guidGitHubCmdSetString;
118-
readonly int id = PkgCmdIDList.showCurrentPullRequestCommand;
119-
120-
readonly EnvDTE.DTE dte;
121-
readonly IUsageTracker usageTracker;
122-
123-
internal RaisePullRequestCommand(EnvDTE.DTE dte, IUsageTracker usageTracker)
124-
{
125-
this.dte = dte;
126-
this.usageTracker = usageTracker;
127-
}
128-
129-
public bool CanExecute(object parameter) => true;
130-
131-
public void Execute(object parameter)
132-
{
133-
try
134-
{
135-
object customIn = null;
136-
object customOut = null;
137-
dte?.Commands.Raise(guid, id, ref customIn, ref customOut);
138-
}
139-
catch (Exception e)
140-
{
141-
log.Error(e, "Couldn't raise {Guid}:{ID}", guid, id);
142-
}
143-
144-
usageTracker.IncrementCounter(x => x.NumberOfShowCurrentPullRequest).Forget();
145-
}
146-
147-
public event EventHandler CanExecuteChanged
148-
{
149-
add { }
150-
remove { }
151-
}
152-
}
153113
}
154114
}

src/GitHub.VisualStudio/Commands/ShowCurrentPullRequestCommand.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using GitHub.Commands;
55
using GitHub.Logging;
66
using GitHub.Services;
7+
using GitHub.Extensions;
78
using GitHub.Services.Vssdk.Commands;
89
using Serilog;
910

@@ -20,12 +21,14 @@ public class ShowCurrentPullRequestCommand : VsCommand, IShowCurrentPullRequestC
2021
{
2122
static readonly ILogger log = LogManager.ForContext<ShowCurrentPullRequestCommand>();
2223
readonly IGitHubServiceProvider serviceProvider;
24+
readonly Lazy<IUsageTracker> usageTracker;
2325

2426
[ImportingConstructor]
25-
protected ShowCurrentPullRequestCommand(IGitHubServiceProvider serviceProvider)
27+
protected ShowCurrentPullRequestCommand(IGitHubServiceProvider serviceProvider, Lazy<IUsageTracker> usageTracker)
2628
: base(CommandSet, CommandId)
2729
{
2830
this.serviceProvider = serviceProvider;
31+
this.usageTracker = usageTracker;
2932
}
3033

3134
/// <summary>
@@ -58,6 +61,8 @@ public override async Task Execute()
5861
var manager = serviceProvider.TryGetService<IGitHubToolWindowManager>();
5962
var host = await manager.ShowGitHubPane();
6063
await host.ShowPullRequest(session.RepositoryOwner, host.LocalRepository.Name, pullRequest.Number);
64+
65+
usageTracker.Value.IncrementCounter(x => x.NumberOfShowCurrentPullRequest).Forget();
6166
}
6267
catch (Exception ex)
6368
{

src/GitHub.VisualStudio/GitHub.VisualStudio.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@
315315
<Compile Include="Commands\ShowGitHubPaneCommand.cs" />
316316
<Compile Include="Commands\OpenPullRequestsCommand.cs" />
317317
<Compile Include="GitContextPackage.cs" />
318+
<Compile Include="GitHubPanePackage.cs" />
318319
<Compile Include="IServiceProviderPackage.cs" />
319320
<Compile Include="Helpers\ActiveDocumentSnapshot.cs" />
320321
<Compile Include="Commands\AddConnectionCommand.cs" />

src/GitHub.VisualStudio/GitHubPackage.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Runtime.InteropServices;
88
using GitHub.Api;
99
using GitHub.Commands;
10-
using GitHub.Helpers;
1110
using GitHub.Info;
1211
using GitHub.Exports;
1312
using GitHub.Logging;
@@ -29,7 +28,6 @@ namespace GitHub.VisualStudio
2928
[Guid(Guids.guidGitHubPkgString)]
3029
[ProvideMenuResource("Menus.ctmenu", 1)]
3130
[ProvideAutoLoad(Guids.UIContext_Git, PackageAutoLoadFlags.BackgroundLoad)]
32-
[ProvideToolWindow(typeof(GitHubPane), Orientation = ToolWindowOrientation.Right, Style = VsDockStyle.Tabbed, Window = EnvDTE.Constants.vsWindowKindSolutionExplorer)]
3331
[ProvideOptionPage(typeof(OptionsPage), "GitHub for Visual Studio", "General", 0, 0, supportsAutomation: true)]
3432
public class GitHubPackage : AsyncPackage
3533
{
@@ -56,20 +54,23 @@ void LogVersionInformation()
5654

5755
async Task InitializeMenus()
5856
{
59-
var menuService = (IMenuCommandService)(await GetServiceAsync(typeof(IMenuCommandService)));
6057
var componentModel = (IComponentModel)(await GetServiceAsync(typeof(SComponentModel)));
6158
var exports = componentModel.DefaultExportProvider;
62-
63-
await JoinableTaskFactory.SwitchToMainThreadAsync();
64-
menuService.AddCommands(
59+
var commands = new IVsCommandBase[]
60+
{
6561
exports.GetExportedValue<IAddConnectionCommand>(),
6662
exports.GetExportedValue<IBlameLinkCommand>(),
6763
exports.GetExportedValue<ICopyLinkCommand>(),
6864
exports.GetExportedValue<ICreateGistCommand>(),
6965
exports.GetExportedValue<IOpenLinkCommand>(),
7066
exports.GetExportedValue<IOpenPullRequestsCommand>(),
7167
exports.GetExportedValue<IShowCurrentPullRequestCommand>(),
72-
exports.GetExportedValue<IShowGitHubPaneCommand>());
68+
exports.GetExportedValue<IShowGitHubPaneCommand>()
69+
};
70+
71+
await JoinableTaskFactory.SwitchToMainThreadAsync();
72+
var menuService = (IMenuCommandService)(await GetServiceAsync(typeof(IMenuCommandService)));
73+
menuService.AddCommands(commands);
7374
}
7475

7576
async Task EnsurePackageLoaded(Guid packageGuid)
@@ -147,9 +148,8 @@ public async Task<IGitHubPaneViewModel> ShowGitHubPane()
147148
ErrorHandler.Failed(frame.Show());
148149
}
149150

150-
var viewModel = (IGitHubPaneViewModel)((FrameworkElement)pane.Content).DataContext;
151-
await viewModel.InitializeAsync(pane);
152-
return viewModel;
151+
var gitHubPane = (GitHubPane)pane;
152+
return await gitHubPane.GetViewModelAsync();
153153
}
154154

155155
static ToolWindowPane ShowToolWindow(Guid windowGuid)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using GitHub.VisualStudio.UI;
4+
using Microsoft.VisualStudio.Shell;
5+
6+
namespace GitHub.VisualStudio
7+
{
8+
/// <summary>
9+
/// This is the host package for the <see cref="GitHubPane"/> tool window.
10+
/// </summary>
11+
/// <remarks>
12+
/// This package mustn't use MEF.
13+
/// See: https://github.com/github/VisualStudio/issues/1550
14+
/// </remarks>
15+
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
16+
[Guid(Guids.GitHubPanePackageId)]
17+
[ProvideToolWindow(typeof(GitHubPane), Orientation = ToolWindowOrientation.Right,
18+
Style = VsDockStyle.Tabbed, Window = EnvDTE.Constants.vsWindowKindSolutionExplorer)]
19+
public sealed class GitHubPanePackage : AsyncPackage
20+
{
21+
}
22+
}

0 commit comments

Comments
 (0)