Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use no-op global assembly cache helper when running under .net core #69936

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ namespace Microsoft.CodeAnalysis

/// <summary>
/// Provides APIs to enumerate and look up assemblies stored in the Global Assembly Cache.
///
/// This resolver only works when running under the .net framework runtime.
/// </summary>
internal sealed class ClrGlobalAssemblyCache : GlobalAssemblyCache
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Reflection;

namespace Microsoft.CodeAnalysis;

/// <summary>
/// Implements a no-op wrapper to search the global assembly cache when running under a .net core runtime.
/// At some point we may wish to get information about assemblies in the GAC under a .net core runtime - for example
/// if we're loading a .net framework project in vscode and want to find the actual assembly to decompile.
///
/// However it isn't extremely straightforward to implement and we don't need it at this time so leaving it as a no-op.
/// More info on how this might be possible under a .net core runtime can be found https://github.com/dotnet/core/issues/3048#issuecomment-725781811
/// </summary>
internal sealed class DotNetCoreGlobalAssemblyCache : GlobalAssemblyCache
Copy link
Member

Choose a reason for hiding this comment

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

Should we just make this type a singleton vs. creating a new one every time?

Copy link
Member Author

Choose a reason for hiding this comment

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

Going to leave this as-is - this is already created as a singleton instance, as instantiated by the GlobalAssemblyCache.CreateInstance in the parent.

{
public override IEnumerable<AssemblyIdentity> GetAssemblyIdentities(AssemblyName partialName, ImmutableArray<ProcessorArchitecture> architectureFilter = default)
{
return ImmutableArray<AssemblyIdentity>.Empty;
}

public override IEnumerable<AssemblyIdentity> GetAssemblyIdentities(string? partialName = null, ImmutableArray<ProcessorArchitecture> architectureFilter = default)
{
return ImmutableArray<AssemblyIdentity>.Empty;
}

public override IEnumerable<string> GetAssemblySimpleNames(ImmutableArray<ProcessorArchitecture> architectureFilter = default)
{
return ImmutableArray<string>.Empty;
}

public override AssemblyIdentity? ResolvePartialName(string displayName, out string? location, ImmutableArray<ProcessorArchitecture> architectureFilter = default, CultureInfo? preferredCulture = null)
{
location = null;
return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand All @@ -27,7 +25,9 @@ private static GlobalAssemblyCache CreateInstance()
}
else
{
return new ClrGlobalAssemblyCache();
return System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.Contains(".NET Framework")
Copy link
Member Author

Choose a reason for hiding this comment

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

if there is a preferred way to do this let me know.

Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine

Copy link
Member

Choose a reason for hiding this comment

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

Believe this is the preferred way. Pattern occurs several places in our code base.

? new ClrGlobalAssemblyCache()
: new DotNetCoreGlobalAssemblyCache();
}
}

Expand All @@ -44,22 +44,22 @@ private static GlobalAssemblyCache CreateInstance()
/// </summary>
/// <param name="partialName">Optional partial name.</param>
/// <param name="architectureFilter">Optional architecture filter.</param>
public abstract IEnumerable<AssemblyIdentity> GetAssemblyIdentities(AssemblyName partialName, ImmutableArray<ProcessorArchitecture> architectureFilter = default(ImmutableArray<ProcessorArchitecture>));
public abstract IEnumerable<AssemblyIdentity> GetAssemblyIdentities(AssemblyName partialName, ImmutableArray<ProcessorArchitecture> architectureFilter = default);

/// <summary>
/// Enumerates assemblies in the GAC returning those that match given partial name and
/// architecture.
/// </summary>
/// <param name="partialName">The optional partial name.</param>
/// <param name="architectureFilter">The optional architecture filter.</param>
public abstract IEnumerable<AssemblyIdentity> GetAssemblyIdentities(string partialName = null, ImmutableArray<ProcessorArchitecture> architectureFilter = default(ImmutableArray<ProcessorArchitecture>));
public abstract IEnumerable<AssemblyIdentity> GetAssemblyIdentities(string? partialName = null, ImmutableArray<ProcessorArchitecture> architectureFilter = default);

/// <summary>
/// Enumerates assemblies in the GAC returning their simple names.
/// </summary>
/// <param name="architectureFilter">Optional architecture filter.</param>
/// <returns>Unique simple names of GAC assemblies.</returns>
public abstract IEnumerable<string> GetAssemblySimpleNames(ImmutableArray<ProcessorArchitecture> architectureFilter = default(ImmutableArray<ProcessorArchitecture>));
public abstract IEnumerable<string> GetAssemblySimpleNames(ImmutableArray<ProcessorArchitecture> architectureFilter = default);

/// <summary>
/// Looks up specified partial assembly name in the GAC and returns the best matching <see cref="AssemblyIdentity"/>.
Expand All @@ -69,13 +69,12 @@ private static GlobalAssemblyCache CreateInstance()
/// <param name="preferredCulture">The optional preferred culture information</param>
/// <returns>An assembly identity or null, if <paramref name="displayName"/> can't be resolved.</returns>
/// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception>
public AssemblyIdentity ResolvePartialName(
public AssemblyIdentity? ResolvePartialName(
string displayName,
ImmutableArray<ProcessorArchitecture> architectureFilter = default(ImmutableArray<ProcessorArchitecture>),
CultureInfo preferredCulture = null)
ImmutableArray<ProcessorArchitecture> architectureFilter = default,
CultureInfo? preferredCulture = null)
{
string location;
return ResolvePartialName(displayName, out location, architectureFilter, preferredCulture);
return ResolvePartialName(displayName, out _, architectureFilter, preferredCulture);
}

/// <summary>
Expand All @@ -87,10 +86,10 @@ public AssemblyIdentity ResolvePartialName(
/// <param name="preferredCulture">The optional preferred culture information</param>
/// <returns>An assembly identity or null, if <paramref name="displayName"/> can't be resolved.</returns>
/// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception>
public abstract AssemblyIdentity ResolvePartialName(
public abstract AssemblyIdentity? ResolvePartialName(
string displayName,
out string location,
ImmutableArray<ProcessorArchitecture> architectureFilter = default(ImmutableArray<ProcessorArchitecture>),
CultureInfo preferredCulture = null);
out string? location,
ImmutableArray<ProcessorArchitecture> architectureFilter = default,
CultureInfo? preferredCulture = null);
}
}
3 changes: 3 additions & 0 deletions src/Scripting/Core/Microsoft.CodeAnalysis.Scripting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\MonoGlobalAssemblyCache.cs">
<Link>Hosting\Resolvers\MonoGlobalAssemblyCache.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\DotNetCoreGlobalAssemblyCache.cs">
<Link>Hosting\Resolvers\DotNetCoreGlobalAssemblyCache.cs</Link>
</Compile>
<Compile Update="ScriptingResources.Designer.cs" GenerateSource="true" />
</ItemGroup>
<ItemGroup>
Expand Down