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

Commit c7af72c

Browse files
committed
Add TestApp for displaying UI outside of VS
1 parent a4e60a1 commit c7af72c

18 files changed

+946
-235
lines changed

src/GitHub.VisualStudio.16.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.28721.148
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio.16", "GitHub.VisualStudio.16\GitHub.VisualStudio.16.csproj", "{4D63EA3B-6896-42B5-B182-AA54D9F5CFD6}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio.TestApp", "GitHub.VisualStudio.TestApp\GitHub.VisualStudio.TestApp.csproj", "{8BA418B2-DCB2-4E89-82A0-93B36F2B8FFE}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
1517
{4D63EA3B-6896-42B5-B182-AA54D9F5CFD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{4D63EA3B-6896-42B5-B182-AA54D9F5CFD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{4D63EA3B-6896-42B5-B182-AA54D9F5CFD6}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{8BA418B2-DCB2-4E89-82A0-93B36F2B8FFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{8BA418B2-DCB2-4E89-82A0-93B36F2B8FFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{8BA418B2-DCB2-4E89-82A0-93B36F2B8FFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{8BA418B2-DCB2-4E89-82A0-93B36F2B8FFE}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.Composition;
4+
using System.ComponentModel.Composition.Hosting;
5+
using System.ComponentModel.Composition.Primitives;
6+
using System.Diagnostics;
7+
using System.Linq;
8+
using System.Linq.Expressions;
9+
using System.Reflection;
10+
using GitHub.Api;
11+
using GitHub.Factories;
12+
using GitHub.Models;
13+
using GitHub.Services;
14+
using GitHub.VisualStudio;
15+
using GitHub.VisualStudio.Views;
16+
using GitHub.VisualStudio.Views.Dialog.Clone;
17+
using Microsoft.VisualStudio.Shell;
18+
using Rothko;
19+
using Task = System.Threading.Tasks.Task;
20+
21+
namespace GitHubCore
22+
{
23+
public class CompositionServices
24+
{
25+
public CompositionContainer CreateCompositionContainer(ExportProvider defaultExportProvider)
26+
{
27+
var catalog = new LoggingCatalog(
28+
GetCatalog(typeof(DialogService).Assembly), // GitHub.App
29+
GetCatalog(typeof(GraphQLClientFactory).Assembly), // GitHub.Api
30+
GetCatalog(typeof(RepositoryCloneView).Assembly), // GitHub.VisualStudio.UI
31+
GetCatalog(typeof(GitHubPackage).Assembly), // GitHub.VisualStudio
32+
GetCatalog(typeof(VSGitServices).Assembly), // GitHub.TeamFoundation.16
33+
GetCatalog(typeof(GitService).Assembly), // GitHub.Exports
34+
GetCatalog(typeof(NotificationDispatcher).Assembly), // GitHub.Exports.Reactive
35+
GetCatalog(typeof(IOperatingSystem).Assembly) // Rothko
36+
);
37+
38+
var compositionContainer = new CompositionContainer(catalog, defaultExportProvider);
39+
40+
var gitHubServiceProvider = new MyGitHubServiceProvider(compositionContainer);
41+
compositionContainer.ComposeExportedValue<IGitHubServiceProvider>(gitHubServiceProvider);
42+
43+
var usageTracker = new MyUsageTracker();
44+
compositionContainer.ComposeExportedValue<IUsageTracker>(usageTracker);
45+
46+
var loginManager = CreateLoginManager(compositionContainer);
47+
compositionContainer.ComposeExportedValue<ILoginManager>(loginManager);
48+
49+
return compositionContainer;
50+
}
51+
52+
private static LoginManager CreateLoginManager(CompositionContainer compositionContainer)
53+
{
54+
var keychain = compositionContainer.GetExportedValue<IKeychain>();
55+
var lazy2Fa = new Lazy<ITwoFactorChallengeHandler>(() => compositionContainer.GetExportedValue<ITwoFactorChallengeHandler>());
56+
var oauthListener = compositionContainer.GetExportedValue<IOAuthCallbackListener>();
57+
var loginManager = new LoginManager(
58+
keychain,
59+
lazy2Fa,
60+
oauthListener,
61+
ApiClientConfiguration.ClientId,
62+
ApiClientConfiguration.ClientSecret,
63+
ApiClientConfiguration.MinimumScopes,
64+
ApiClientConfiguration.RequestedScopes,
65+
ApiClientConfiguration.AuthorizationNote,
66+
ApiClientConfiguration.MachineFingerprint);
67+
return loginManager;
68+
}
69+
70+
static TypeCatalog GetCatalog(Assembly assembly)
71+
{
72+
Type[] types;
73+
try
74+
{
75+
types = assembly.GetTypes();
76+
}
77+
catch (ReflectionTypeLoadException e)
78+
{
79+
Trace.WriteLine(e);
80+
foreach (var ex in e.LoaderExceptions)
81+
{
82+
Trace.WriteLine(ex);
83+
}
84+
85+
types = e.Types.Where(t => t != null).ToArray();
86+
}
87+
88+
var catalog = new TypeCatalog(types);
89+
return catalog;
90+
}
91+
}
92+
93+
public class ViewLocatorInitializer : IDisposable
94+
{
95+
object value;
96+
97+
public ViewLocatorInitializer(IViewViewModelFactory viewViewModelFactory)
98+
{
99+
value = FactoryProviderFiled().GetValue(null);
100+
FactoryProviderFiled().SetValue(null, viewViewModelFactory);
101+
}
102+
103+
public void Dispose()
104+
{
105+
FactoryProviderFiled().SetValue(null, value);
106+
}
107+
108+
private static FieldInfo FactoryProviderFiled()
109+
{
110+
return typeof(ViewLocator).GetField("factoryProvider", BindingFlags.Static | BindingFlags.NonPublic);
111+
}
112+
}
113+
114+
public class MyGitHubServiceProvider : IGitHubServiceProvider
115+
{
116+
readonly IServiceProvider serviceProvider;
117+
118+
public MyGitHubServiceProvider(ExportProvider exportProvider)
119+
{
120+
ExportProvider = exportProvider;
121+
serviceProvider = exportProvider.GetExportedValue<SVsServiceProvider>();
122+
}
123+
124+
public T TryGetService<T>() where T : class
125+
{
126+
try
127+
{
128+
return GetService<T>();
129+
}
130+
catch
131+
{
132+
return default;
133+
}
134+
}
135+
136+
public T GetService<T>() where T : class
137+
{
138+
return GetService<T, T>();
139+
}
140+
141+
public TRet GetService<T, TRet>()
142+
where T : class
143+
where TRet : class
144+
{
145+
var value = ExportProvider.GetExportedValueOrDefault<T>();
146+
if (value != null)
147+
{
148+
return value as TRet;
149+
}
150+
151+
value = GetService(typeof(T)) as T;
152+
if (value != null)
153+
{
154+
return value as TRet;
155+
}
156+
157+
Trace.WriteLine($"Couldn't find service of type {typeof(T)}");
158+
return null;
159+
}
160+
161+
public object GetService(Type serviceType)
162+
{
163+
return serviceProvider.GetService(serviceType);
164+
}
165+
166+
#region obsolete
167+
168+
public IServiceProvider GitServiceProvider { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
169+
170+
public void AddService(Type t, object owner, object instance)
171+
{
172+
throw new NotImplementedException();
173+
}
174+
175+
public void AddService<T>(object owner, T instance) where T : class
176+
{
177+
throw new NotImplementedException();
178+
}
179+
180+
public void RemoveService(Type t, object owner)
181+
{
182+
throw new NotImplementedException();
183+
}
184+
185+
public object TryGetService(Type t)
186+
{
187+
throw new NotImplementedException();
188+
}
189+
190+
public object TryGetService(string typeName)
191+
{
192+
throw new NotImplementedException();
193+
}
194+
195+
#endregion
196+
197+
public ExportProvider ExportProvider { get; }
198+
}
199+
200+
public class MyUsageTracker : IUsageTracker
201+
{
202+
public Task IncrementCounter(Expression<Func<UsageModel.MeasuresModel, int>> counter)
203+
{
204+
Trace.WriteLine($"IncrementCounter {counter}");
205+
return Task.CompletedTask;
206+
}
207+
}
208+
209+
public class LoggingCatalog : AggregateCatalog
210+
{
211+
public LoggingCatalog(params ComposablePartCatalog[] catalogs) : base(catalogs) { }
212+
213+
public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
214+
{
215+
var exports = base.GetExports(definition);
216+
if (exports.Count() == 0)
217+
{
218+
Trace.WriteLine($"No exports for {definition}");
219+
}
220+
221+
return exports;
222+
}
223+
}
224+
}

src/GitHub.VisualStudio.16/GitHub.VisualStudio.16.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<WarningLevel>4</WarningLevel>
4747
</PropertyGroup>
4848
<ItemGroup>
49+
<Compile Include="CompositionServices.cs" />
4950
<Compile Include="OpenFromGitHubCommand.cs" />
5051
<Compile Include="Properties\AssemblyInfo.cs" />
5152
<Compile Include="GitHubCorePackage.cs" />
@@ -139,6 +140,8 @@
139140
<SpecificVersion>False</SpecificVersion>
140141
<HintPath>..\..\build\Content\Octokit.GraphQL.Core.dll</HintPath>
141142
</Reference>
143+
<Reference Include="PresentationCore" />
144+
<Reference Include="PresentationFramework" />
142145
<Reference Include="ReactiveUI, Version=8.7.0.0, Culture=neutral, PublicKeyToken=31f8874b2ce7ed44, processorArchitecture=MSIL">
143146
<SpecificVersion>False</SpecificVersion>
144147
<HintPath>..\..\build\Content\ReactiveUI.dll</HintPath>
@@ -183,7 +186,9 @@
183186
<HintPath>..\..\build\Content\System.Reactive.dll</HintPath>
184187
</Reference>
185188
<Reference Include="System.Windows.Forms" />
189+
<Reference Include="System.Xaml" />
186190
<Reference Include="System.Xml" />
191+
<Reference Include="WindowsBase" />
187192
</ItemGroup>
188193
<ItemGroup>
189194
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="15.9.3" ExcludeAssets="runtime" />

0 commit comments

Comments
 (0)