diff --git a/src/Compilers/Core/Portable/CorLightup.cs b/src/Compilers/Core/Portable/CorLightup.cs
index 020a6c423160c8f7df042d10328fee543ee2b070..3ee67635fbca06aefadb98225851dc90cc4b1e8e 100644
--- a/src/Compilers/Core/Portable/CorLightup.cs
+++ b/src/Compilers/Core/Portable/CorLightup.cs
@@ -76,7 +76,7 @@ private static class _Assembly
private static class _ResolveEventArgs
{
- internal static readonly Type Type = Type.GetType("System.ResolveEventArgs", throwOnError: false);
+ internal static readonly Type Type = ReflectionUtilities.TryGetType("System.ResolveEventArgs");
internal static readonly MethodInfo get_Name = Type
.GetTypeInfo()
@@ -89,8 +89,8 @@ private static class _ResolveEventArgs
private static class _AppDomain
{
- internal static readonly Type Type = Type.GetType("System.AppDomain", throwOnError: false);
- internal static readonly Type ResolveEventHandlerType = Type.GetType("System.ResolveEventHandler", throwOnError: false);
+ internal static readonly Type Type = ReflectionUtilities.TryGetType("System.AppDomain");
+ internal static readonly Type ResolveEventHandlerType = ReflectionUtilities.TryGetType("System.ResolveEventHandler");
internal static readonly MethodInfo get_CurrentDomain = Type
.GetTypeInfo()
diff --git a/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs b/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs
index d02f73be2575da2a5124259cf9691acc1ef0ee4f..a631c962a27fb83c85fd31c1bd677b430a46a9da 100644
--- a/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs
+++ b/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs
@@ -10,17 +10,30 @@ namespace Roslyn.Utilities
{
internal static class ReflectionUtilities
{
+ public static Type TryGetType(string assemblyQualifiedName)
+ {
+ try
+ {
+ // Note that throwOnError=false only suppresses some exceptions, not all.
+ return Type.GetType(assemblyQualifiedName, throwOnError: false);
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
///
/// Find a instance by first probing the contract name and then the name as it
/// would exist in mscorlib. This helps satisfy both the CoreCLR and Desktop scenarios.
///
public static Type GetTypeFromEither(string contractName, string desktopName)
{
- var type = Type.GetType(contractName, throwOnError: false);
+ var type = TryGetType(contractName);
if (type == null)
{
- type = Type.GetType(desktopName, throwOnError: false);
+ type = TryGetType(desktopName);
}
return type;
diff --git a/src/Compilers/Helpers/CoreClrShim.cs b/src/Compilers/Helpers/CoreClrShim.cs
index a933bd3be0757246027030f2c5f37c368432400f..8cacb35aa95bf632f75dd016f2185255006be12e 100644
--- a/src/Compilers/Helpers/CoreClrShim.cs
+++ b/src/Compilers/Helpers/CoreClrShim.cs
@@ -6,7 +6,6 @@
namespace Roslyn.Utilities
{
-
///
/// This is a bridge for APIs that are only available on CoreCLR or .NET 4.6
/// and NOT on .NET 4.5. The compiler currently targets .NET 4.5 and CoreCLR
@@ -14,13 +13,20 @@ namespace Roslyn.Utilities
///
internal static class CoreClrShim
{
+
+ internal static class AssemblyLoadContext
+ {
+ internal static readonly Type Type = ReflectionUtilities.TryGetType(
+ "System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+ }
+
internal static class CodePagesEncodingProvider
{
- internal static readonly Type Type =
- Type.GetType("System.Text.CodePagesEncodingProvider, " +
- "System.Text.Encoding.CodePages, " +
- "Version=4.0.0.0, Culture=neutral, " +
- "PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
+ internal static readonly Type Type = ReflectionUtilities.TryGetType(
+ "System.Text.CodePagesEncodingProvider, " +
+ "System.Text.Encoding.CodePages, " +
+ "Version=4.0.0.0, Culture=neutral, " +
+ "PublicKeyToken=b03f5f7f11d50a3a");
private static PropertyInfo s_instance = Type
?.GetTypeInfo()
diff --git a/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GacFileResolver.cs b/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GacFileResolver.cs
index 4b67edef9c6b69955c42bf30589f1bd2064bedb6..33eac41a07c05abc0d5d042deb8b0a42e36bf34c 100644
--- a/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GacFileResolver.cs
+++ b/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GacFileResolver.cs
@@ -11,37 +11,46 @@
namespace Microsoft.CodeAnalysis.Scripting.Hosting
{
///
- /// Extends MetadataFileReferenceResolver to enable resolution of assembly
- /// simple names in the GAC.
+ /// Resolves assembly identities in Global Assembly Cache.
///
internal sealed class GacFileResolver : IEquatable
{
///
- /// Architecture filter used when resolving assembly references.
+ /// Returns true if GAC is available on the platform.
///
- public ImmutableArray Architectures { get; }
+ public static bool IsAvailable => CoreClrShim.AssemblyLoadContext.Type == null;
///
- /// CultureInfo used when resolving assembly references.
+ /// Architecture filter used when resolving assembly references.
///
- public CultureInfo PreferredCulture { get; }
+ public ImmutableArray Architectures { get; }
///
- /// A resolver that is configured to resolve against the GAC associated
- /// with the bitness of the currently executing process.
+ /// used when resolving assembly references, or null to prefer no culture.
///
- internal static GacFileResolver Default = new GacFileResolver(
- architectures: GlobalAssemblyCache.CurrentArchitectures,
- preferredCulture: null);
+ public CultureInfo PreferredCulture { get; }
///
- /// Constructs an instance of a
+ /// Creates an instance of a , if available on the platform (check ).
///
/// Supported architectures used to filter GAC assemblies.
/// A culture to use when choosing the best assembly from
/// among the set filtered by
- public GacFileResolver(ImmutableArray architectures, CultureInfo preferredCulture)
+ /// The platform doesn't support GAC.
+ public GacFileResolver(
+ ImmutableArray architectures = default(ImmutableArray),
+ CultureInfo preferredCulture = null)
{
+ if (!IsAvailable)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ if (architectures.IsDefault)
+ {
+ architectures = GlobalAssemblyCache.CurrentArchitectures;
+ }
+
Architectures = architectures;
PreferredCulture = preferredCulture;
}
diff --git a/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GlobalAssemblyCache.cs b/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GlobalAssemblyCache.cs
index fa011b769af85e1b669a3f24bb1e68650bd76dd7..8ce0fd252d663408822c1027b4bd62421feb0864 100644
--- a/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GlobalAssemblyCache.cs
+++ b/src/Compilers/Helpers/GlobalAssemblyCacheHelpers/GlobalAssemblyCache.cs
@@ -87,13 +87,19 @@ private enum ASM_CACHE
private const int ERROR_INSUFFICIENT_BUFFER = unchecked((int)0x8007007A);
- public static readonly ImmutableArray RootLocations;
+ public static ImmutableArray s_rootLocations;
- static GlobalAssemblyCache()
+ public static ImmutableArray RootLocations
{
- RootLocations = ImmutableArray.Create(
- GetLocation(ASM_CACHE.ROOT),
- GetLocation(ASM_CACHE.ROOT_EX));
+ get
+ {
+ if (s_rootLocations.IsDefault)
+ {
+ s_rootLocations = ImmutableArray.Create(GetLocation(ASM_CACHE.ROOT), GetLocation(ASM_CACHE.ROOT_EX));
+ }
+
+ return s_rootLocations;
+ }
}
private static unsafe string GetLocation(ASM_CACHE gacId)
@@ -105,7 +111,7 @@ private static unsafe string GetLocation(ASM_CACHE gacId)
throw Marshal.GetExceptionForHR(hr);
}
- byte[] data = new byte[((int)characterCount + 1) * 2];
+ byte[] data = new byte[(characterCount + 1) * 2];
fixed (byte* p = data)
{
hr = GetCachePath(gacId, p, ref characterCount);
diff --git a/src/Interactive/EditorFeatures/Core/Extensibility/Interactive/InteractiveEvaluator.cs b/src/Interactive/EditorFeatures/Core/Extensibility/Interactive/InteractiveEvaluator.cs
index 3cb76a586a50ee23f18b7d7dc7442d0381acf4ce..2f1012938c827bea52b50f62678e6931bebb5f0d 100644
--- a/src/Interactive/EditorFeatures/Core/Extensibility/Interactive/InteractiveEvaluator.cs
+++ b/src/Interactive/EditorFeatures/Core/Extensibility/Interactive/InteractiveEvaluator.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
@@ -257,9 +258,7 @@ private static MetadataReferenceResolver CreateMetadataReferenceResolver(IMetada
return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(searchPaths, baseDirectory),
string.IsNullOrEmpty(packagesDirectory) ? null : new NuGetPackageResolverImpl(packagesDirectory),
- new GacFileResolver(
- architectures: GacFileResolver.Default.Architectures, // TODO (tomat)
- preferredCulture: System.Globalization.CultureInfo.CurrentCulture), // TODO (tomat)
+ GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => metadataService.GetReference(path, properties));
}
diff --git a/src/Interactive/Features/Interactive/Core/InteractiveHost.Service.cs b/src/Interactive/Features/Interactive/Core/InteractiveHost.Service.cs
index dc6879f0746fba1e77d12b2674b0f805e930bf3d..23429f13f1367662981afbed99d7362861bffee3 100644
--- a/src/Interactive/Features/Interactive/Core/InteractiveHost.Service.cs
+++ b/src/Interactive/Features/Interactive/Core/InteractiveHost.Service.cs
@@ -169,13 +169,12 @@ private MetadataReferenceResolver CreateMetadataReferenceResolver(ImmutableArray
var packagesDirectory = string.IsNullOrEmpty(userProfilePath) ?
null :
Path.Combine(userProfilePath, Path.Combine(".nuget", "packages"));
+
return new RuntimeMetadataReferenceResolver(
- new RelativePathResolver(searchPaths, baseDirectory),
+ new RelativePathResolver(searchPaths, baseDirectory),
string.IsNullOrEmpty(packagesDirectory) ? null : new NuGetPackageResolverImpl(packagesDirectory),
- new GacFileResolver(
- architectures: GacFileResolver.Default.Architectures, // TODO (tomat)
- preferredCulture: CultureInfo.CurrentCulture), // TODO (tomat)
- (path, properties) => _metadataFileProvider.GetReference(path, properties));
+ GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
+ (path, properties) => _metadataFileProvider.GetReference(path, properties));
}
private SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray searchPaths, string baseDirectory)
diff --git a/src/Scripting/CSharp/CommandLine/Csi.cs b/src/Scripting/CSharp/CommandLine/Csi.cs
index 7f294babcede17bbf4aae49d9023aa7e26f97a30..3062598a59eb7a687bc289a647a37a8a6cab964e 100644
--- a/src/Scripting/CSharp/CommandLine/Csi.cs
+++ b/src/Scripting/CSharp/CommandLine/Csi.cs
@@ -23,7 +23,7 @@ internal override MetadataReferenceResolver GetCommandLineMetadataReferenceResol
return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(Arguments.ReferencePaths, Arguments.BaseDirectory),
null,
- new GacFileResolver(GacFileResolver.Default.Architectures, CultureInfo.CurrentCulture),
+ GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) =>
{
loggerOpt?.AddRead(path);
diff --git a/src/Scripting/Core/Resolvers/RuntimeMetadataReferenceResolver.cs b/src/Scripting/Core/Resolvers/RuntimeMetadataReferenceResolver.cs
index 4edd31612e5d7b9c0a5e4f395c3426cb9a20a64b..2707340bd26d1e8d3961e63fc1e88d0767452602 100644
--- a/src/Scripting/Core/Resolvers/RuntimeMetadataReferenceResolver.cs
+++ b/src/Scripting/Core/Resolvers/RuntimeMetadataReferenceResolver.cs
@@ -25,7 +25,7 @@ internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolv
internal RuntimeMetadataReferenceResolver(
ImmutableArray searchPaths,
string baseDirectory)
- : this(new RelativePathResolver(searchPaths, baseDirectory), null, GacFileResolver.Default)
+ : this(new RelativePathResolver(searchPaths, baseDirectory), null, GacFileResolver.IsAvailable ? new GacFileResolver() : null)
{
}
diff --git a/src/Scripting/VisualBasic/CommandLine/Vbi.vb b/src/Scripting/VisualBasic/CommandLine/Vbi.vb
index 279f59f693df6a72c3e3dccda213e9b9f4f12a2d..23796a7edc10e3942bba10fb88d72053e91f2abd 100644
--- a/src/Scripting/VisualBasic/CommandLine/Vbi.vb
+++ b/src/Scripting/VisualBasic/CommandLine/Vbi.vb
@@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.Scripting.Hosting.VisualBasic
Return New RuntimeMetadataReferenceResolver(
New RelativePathResolver(Arguments.ReferencePaths, Arguments.BaseDirectory),
Nothing,
- New GacFileResolver(GacFileResolver.Default.Architectures, CultureInfo.CurrentCulture),
+ If(GacFileResolver.IsAvailable, New GacFileResolver(preferredCulture:=CultureInfo.CurrentCulture), Nothing),
Function(path, properties)
loggerOpt?.AddRead(path)
Return MetadataReference.CreateFromFile(path)