Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions src/GitHub.Exports/Extensions/VSExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ namespace GitHub.Extensions
{
public static class VSExtensions
{
static IUIProvider cachedUIProvider = null;

public static T TryGetService<T>(this IServiceProvider serviceProvider) where T : class
{
return serviceProvider.TryGetService(typeof(T)) as T;
}

public static object TryGetService(this IServiceProvider serviceProvider, Type type)
{
if (cachedUIProvider != null && type == typeof(IUIProvider))
return cachedUIProvider;

var ui = serviceProvider as IUIProvider;
if (ui != null)
return ui.TryGetService(type);
else
{
try
{
return serviceProvider.GetService(type);
return GetServiceAndCache(serviceProvider, type, ref cachedUIProvider);
}
catch (Exception ex)
{
Expand All @@ -33,20 +38,42 @@ public static object TryGetService(this IServiceProvider serviceProvider, Type t

public static T GetService<T>(this IServiceProvider serviceProvider)
{
return (T)serviceProvider.GetService(typeof(T));
if (cachedUIProvider != null && typeof(T) == typeof(IUIProvider))
return (T)cachedUIProvider;

return (T)GetServiceAndCache(serviceProvider, typeof(T), ref cachedUIProvider);
}

public static T GetExportedValue<T>(this IServiceProvider serviceProvider)
{
if (cachedUIProvider != null && typeof(T) == typeof(IUIProvider))
return (T)cachedUIProvider;

var ui = serviceProvider as IUIProvider;
return ui != null
? ui.GetService<T>()
: VisualStudio.Services.ComponentModel.DefaultExportProvider.GetExportedValue<T>();
: GetExportedValueAndCache<T, IUIProvider>(ref cachedUIProvider);
}

public static ITeamExplorerSection GetSection(this IServiceProvider serviceProvider, Guid section)
{
return serviceProvider?.GetService<ITeamExplorerPage>()?.GetSection(section);
}

static object GetServiceAndCache<CacheType>(IServiceProvider provider, Type type, ref CacheType cache)
{
var ret = provider.GetService(type);
if (type == typeof(CacheType))
cache = (CacheType)ret;
return ret;
}

static T GetExportedValueAndCache<T, CacheType>(ref CacheType cache)
{
var ret = VisualStudio.Services.ComponentModel.DefaultExportProvider.GetExportedValue<T>();
if (typeof(T) == typeof(CacheType))
cache = (CacheType)(object)ret;
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 with the double cast?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The type system doesn't know that it's the same type at compile time inside this condition 😉

return ret;
}
}
}