Skip to content

Commit

Permalink
Merge pull request #1223 from SteeltoeOSS/bootstrap-api-review
Browse files Browse the repository at this point in the history
Bootstrap public API review
  • Loading branch information
bart-vmware authored Dec 1, 2023
2 parents f6d2dda + 20b7ee6 commit e6012f0
Show file tree
Hide file tree
Showing 56 changed files with 2,720 additions and 2,713 deletions.
4 changes: 2 additions & 2 deletions shared-package.props
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@
</Target>

<ItemGroup
Condition="$(MSBuildProjectName.StartsWith('Steeltoe.Configuration')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Management')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Connectors')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Logging'))">
Condition="$(MSBuildProjectName.StartsWith('Steeltoe.Configuration')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Management')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Connectors')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Logging')) Or $(MSBuildProjectName.StartsWith('Steeltoe.Bootstrap'))">

<!-- Widen the condition above as we're completing more public API reviews -->
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="$(PublicApiAnalyzersVersion)" PrivateAssets="All" />
</ItemGroup>

<PropertyGroup
Condition="!$(MSBuildProjectName.StartsWith('Steeltoe.Configuration')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Management')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Connectors')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Logging'))">
Condition="!$(MSBuildProjectName.StartsWith('Steeltoe.Configuration')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Management')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Connectors')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Logging')) And !$(MSBuildProjectName.StartsWith('Steeltoe.Bootstrap'))">

<!-- Narrow the condition above as we're completing more public API reviews -->
<NoWarn>$(NoWarn);SA1401;S1168;S2360;S3900;S3956;S4004;S4023</NoWarn>
Expand Down
67 changes: 0 additions & 67 deletions src/Bootstrap/src/AutoConfiguration/AssemblyExtensions.cs

This file was deleted.

93 changes: 93 additions & 0 deletions src/Bootstrap/src/AutoConfiguration/AssemblyLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Reflection;
using Steeltoe.Common;

namespace Steeltoe.Bootstrap.AutoConfiguration;

internal sealed class AssemblyLoader
{
public IReadOnlySet<string> AssemblyNamesToExclude { get; }

static AssemblyLoader()
{
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver.LoadAnyVersion;
}

public AssemblyLoader(IReadOnlySet<string> assemblyNamesToExclude)
{
ArgumentGuard.NotNull(assemblyNamesToExclude);
ArgumentGuard.ElementsNotNullOrEmpty(assemblyNamesToExclude);

// Take a copy to ensure comparisons are case insensitive.
AssemblyNamesToExclude = assemblyNamesToExclude.ToHashSet(StringComparer.OrdinalIgnoreCase);
}

public bool IsAssemblyLoaded(string assemblyName)
{
ArgumentGuard.NotNullOrEmpty(assemblyName);

if (AssemblyNamesToExclude.Contains(assemblyName))
{
return false;
}

return TryLoadAssembly(assemblyName);
}

private static bool TryLoadAssembly(string assemblyName)
{
try
{
_ = Assembly.Load(assemblyName);
return true;
}
catch (Exception exception) when (exception is ArgumentException or IOException or BadImageFormatException)
{
return false;
}
}

private static class AssemblyResolver
{
private static readonly HashSet<string> FailedAssemblyNames = new(StringComparer.OrdinalIgnoreCase);

public static Assembly? LoadAnyVersion(object? sender, ResolveEventArgs args)
{
// Workaround for Sonar bug at https://github.com/SonarSource/sonar-dotnet/issues/8371.
_ = sender;

// Load whatever version is available (ignore Version, Culture and PublicKeyToken).
string assemblySimpleName = new AssemblyName(args.Name).Name!;

if (FailedAssemblyNames.Contains(assemblySimpleName))
{
return null;
}

// AssemblyName.Equals() returns false when path and full name are identical, so the code below
// avoids a crash caused by inserting duplicate keys in the dictionary.
Dictionary<string, Assembly> assembliesBySimpleName = AppDomain.CurrentDomain.GetAssemblies().GroupBy(nextAssembly => nextAssembly.GetName().Name!)
.ToDictionary(grouping => grouping.Key, grouping => grouping.First(), StringComparer.OrdinalIgnoreCase);

if (assembliesBySimpleName.TryGetValue(assemblySimpleName, out Assembly? assembly))
{
return assembly;
}

if (args.Name.Contains(".resources", StringComparison.Ordinal))
{
return args.RequestingAssembly;
}

// Prevent recursive attempts to resolve.
FailedAssemblyNames.Add(assemblySimpleName);
assembly = Assembly.Load(assemblySimpleName);
FailedAssemblyNames.Remove(assemblySimpleName);

return assembly;
}
}
}
Loading

0 comments on commit e6012f0

Please sign in to comment.