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

Commit a2d7a2b

Browse files
committed
Make sure only one instance of a service is created
IVSServices and ITeamExplorerServices have methods that depend on types from specific versions of TeamFoundation. Unfortunately, because the class itself doesn't depend on any TeamFoundation types, it can be happily instantiated by the runtime, which means that there would be two instances of each of these MEF exports floating around, which of course silently crashes the MEF loading of any other types that depend on these services in their constructors. We need to make sure that any service exported by these TeamFoundation-specific projects have fields/properties/constructors that depend on TeamFoundation types, so that they will not be instantiated if the VS they're running on is a different version.
1 parent 4be2364 commit a2d7a2b

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

src/GitHub.TeamFoundation.14/Services/TeamExplorerServices.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ public class TeamExplorerServices : ITeamExplorerServices
1313
{
1414
readonly IServiceProvider serviceProvider;
1515

16+
/// <summary>
17+
/// This MEF export requires specific versions of TeamFoundation. ITeamExplorerNotificationManager is declared here so
18+
/// that instances of this type cannot be created if the TeamFoundation dlls are not available
19+
/// (otherwise we'll have multiple instances of ITeamExplorerServices exports, and that would be Bad(tm))
20+
/// </summary>
21+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
22+
ITeamExplorerNotificationManager manager;
23+
1624
[ImportingConstructor]
1725
public TeamExplorerServices([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider)
1826
{
@@ -21,31 +29,31 @@ public TeamExplorerServices([Import(typeof(SVsServiceProvider))] IServiceProvide
2129

2230
public void ShowMessage(string message)
2331
{
24-
var manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
32+
manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
2533
manager?.ShowNotification(message, NotificationType.Information, NotificationFlags.None, null, default(Guid));
2634
}
2735

2836
public void ShowMessage(string message, ICommand command)
2937
{
30-
var manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
38+
manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
3139
manager?.ShowNotification(message, NotificationType.Information, NotificationFlags.None, command, default(Guid));
3240
}
3341

3442
public void ShowWarning(string message)
3543
{
36-
var manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
44+
manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
3745
manager?.ShowNotification(message, NotificationType.Warning, NotificationFlags.None, null, default(Guid));
3846
}
3947

4048
public void ShowError(string message)
4149
{
42-
var manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
50+
manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
4351
manager?.ShowNotification(message, NotificationType.Error, NotificationFlags.None, null, default(Guid));
4452
}
4553

4654
public void ClearNotifications()
4755
{
48-
var manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
56+
manager = serviceProvider.TryGetService<ITeamExplorer>() as ITeamExplorerNotificationManager;
4957
manager?.ClearNotifications();
5058
}
5159
}

src/GitHub.TeamFoundation.14/Services/VSServices.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ public class VSServices : IVSServices
2323
{
2424
readonly IUIProvider serviceProvider;
2525

26+
/// <summary>
27+
/// This MEF export requires specific versions of TeamFoundation. IGitExt is declared here so
28+
/// that instances of this type cannot be created if the TeamFoundation dlls are not available
29+
/// (otherwise we'll have multiple instances of IVSServices exports, and that would be Bad(tm))
30+
/// </summary>
31+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
32+
IGitExt gitExtService;
33+
2634
[ImportingConstructor]
2735
public VSServices(IUIProvider serviceProvider)
2836
{
@@ -56,8 +64,8 @@ public void Clone(string cloneUrl, string clonePath, bool recurseSubmodules)
5664

5765
IGitRepositoryInfo GetRepoFromVS()
5866
{
59-
var gitExt = serviceProvider.GetService<IGitExt>();
60-
return gitExt.ActiveRepositories.FirstOrDefault();
67+
gitExtService = serviceProvider.GetService<IGitExt>();
68+
return gitExtService.ActiveRepositories.FirstOrDefault();
6169
}
6270

6371
public LibGit2Sharp.IRepository GetActiveRepo()

0 commit comments

Comments
 (0)