Fixes error trying to load Cosmos.CRTCompat.dll (System.BadImageForma… (#9834)

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
Sebastiaan Janssen
2021-02-18 09:27:14 +01:00
committed by GitHub
parent 88acb07873
commit f1717a17f5
9 changed files with 55 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Extensions.Logging;
namespace Umbraco.Core.Composing
{
@@ -14,6 +15,7 @@ namespace Umbraco.Core.Composing
public class DefaultUmbracoAssemblyProvider : IAssemblyProvider
{
private readonly Assembly _entryPointAssembly;
private readonly ILoggerFactory _loggerFactory;
private static readonly string[] UmbracoCoreAssemblyNames = new[]
{
"Umbraco.Core",
@@ -26,9 +28,10 @@ namespace Umbraco.Core.Composing
"Umbraco.Web.Website",
};
public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly)
public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly, ILoggerFactory loggerFactory)
{
_entryPointAssembly = entryPointAssembly ?? throw new ArgumentNullException(nameof(entryPointAssembly));
_loggerFactory = loggerFactory;
}
// TODO: It would be worth investigating a netcore3 version of this which would use
@@ -41,7 +44,7 @@ namespace Umbraco.Core.Composing
{
get
{
var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, UmbracoCoreAssemblyNames, true);
var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, UmbracoCoreAssemblyNames, true, _loggerFactory);
return finder.Find();
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Logging;
namespace Umbraco.Core.Composing
{
@@ -17,6 +18,7 @@ namespace Umbraco.Core.Composing
private readonly Assembly[] _referenceAssemblies;
private readonly string[] _targetAssemblies;
private readonly bool _includeTargets;
private readonly ILoggerFactory _loggerFactory;
/// <summary>
/// Constructor
@@ -24,11 +26,13 @@ namespace Umbraco.Core.Composing
/// <param name="referenceAssemblies">Entry point assemblies</param>
/// <param name="targetAssemblyNames">Used to check if the entry point or it's transitive assemblies reference these assembly names</param>
/// <param name="includeTargets">If true will also use the target assembly names as entry point assemblies</param>
public FindAssembliesWithReferencesTo(Assembly[] referenceAssemblies, string[] targetAssemblyNames, bool includeTargets)
/// <param name="loggerFactory">Logger factory for when scanning goes wrong</param>
public FindAssembliesWithReferencesTo(Assembly[] referenceAssemblies, string[] targetAssemblyNames, bool includeTargets, ILoggerFactory loggerFactory)
{
_referenceAssemblies = referenceAssemblies;
_targetAssemblies = targetAssemblyNames;
_includeTargets = includeTargets;
_loggerFactory = loggerFactory;
}
public IEnumerable<Assembly> Find()
@@ -54,7 +58,7 @@ namespace Umbraco.Core.Composing
}
}
var provider = new ReferenceResolver(_targetAssemblies, referenceItems);
var provider = new ReferenceResolver(_targetAssemblies, referenceItems, _loggerFactory.CreateLogger<ReferenceResolver>());
var assemblyNames = provider.ResolveAssemblies();
return assemblyNames.ToList();
}

View File

@@ -4,6 +4,8 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using Microsoft.Extensions.Logging;
namespace Umbraco.Core.Composing
{
@@ -19,11 +21,12 @@ namespace Umbraco.Core.Composing
private readonly IReadOnlyList<Assembly> _assemblies;
private readonly Dictionary<Assembly, Classification> _classifications;
private readonly List<Assembly> _lookup = new List<Assembly>();
public ReferenceResolver(IReadOnlyList<string> targetAssemblies, IReadOnlyList<Assembly> entryPointAssemblies)
private readonly ILogger _logger;
public ReferenceResolver(IReadOnlyList<string> targetAssemblies, IReadOnlyList<Assembly> entryPointAssemblies, ILogger<ReferenceResolver> logger)
{
_umbracoAssemblies = new HashSet<string>(targetAssemblies, StringComparer.Ordinal);
_assemblies = entryPointAssemblies;
_logger = logger;
_classifications = new Dictionary<Assembly, Classification>();
foreach (var item in entryPointAssemblies)
@@ -54,19 +57,39 @@ namespace Umbraco.Core.Composing
{
foreach(var dll in Directory.EnumerateFiles(dir, "*.dll"))
{
var assemblyName = AssemblyName.GetAssemblyName(dll);
AssemblyName assemblyName = null;
try
{
assemblyName = AssemblyName.GetAssemblyName(dll);
}
catch (BadImageFormatException e)
{
_logger.LogDebug(e, "Could not load {dll} for type scanning, skipping", dll);
}
catch (SecurityException e)
{
_logger.LogError(e, "Could not access {dll} for type scanning due to a security problem", dll);
}
catch (Exception e)
{
_logger.LogInformation(e, "Error: could not load {dll} for type scanning", dll);
}
// don't include if this is excluded
if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => assemblyName.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase)))
continue;
if (assemblyName != null)
{
// don't include if this is excluded
if (TypeFinder.KnownAssemblyExclusionFilter.Any(f =>
assemblyName.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase)))
continue;
// don't include this item if it's Umbraco
// TODO: We should maybe pass an explicit list of these names in?
if (assemblyName.FullName.StartsWith("Umbraco.") || assemblyName.Name.EndsWith(".Views"))
continue;
// don't include this item if it's Umbraco
// TODO: We should maybe pass an explicit list of these names in?
if (assemblyName.FullName.StartsWith("Umbraco.") || assemblyName.Name.EndsWith(".Views"))
continue;
var assembly = Assembly.Load(assemblyName);
assemblies.Add(assembly);
var assembly = Assembly.Load(assemblyName);
assemblies.Add(assembly);
}
}
}

View File

@@ -16,14 +16,14 @@ namespace Umbraco.Tests.Benchmarks
[Benchmark(Baseline = true)]
public void WithGetReferencingAssembliesCheck()
{
var typeFinder1 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash());
var typeFinder1 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
var found = typeFinder1.FindClassesOfType<IDiscoverable>().Count();
}
[Benchmark]
public void WithoutGetReferencingAssembliesCheck()
{
var typeFinder2 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash());
var typeFinder2 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
typeFinder2.QueryWithReferencingAssemblies = false;
var found = typeFinder2.FindClassesOfType<IDiscoverable>().Count();
}

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Tests.Common
protected TestHelperBase(Assembly entryAssembly)
{
MainDom = new SimpleMainDom();
_typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(entryAssembly), new VaryingRuntimeHash());
_typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(entryAssembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
}
public ITypeFinder GetTypeFinder() => _typeFinder;

View File

@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Composing;
@@ -38,7 +39,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing
[Test]
public void Find_Class_Of_Type_With_Attribute()
{
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash());
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
IEnumerable<Type> typesFound = typeFinder.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies);
Assert.AreEqual(2, typesFound.Count());
}
@@ -46,7 +47,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing
[Test]
public void Find_Classes_With_Attribute()
{
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash());
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
IEnumerable<Type> typesFound = typeFinder.FindClassesWithAttribute<TreeAttribute>(_assemblies);
Assert.AreEqual(0, typesFound.Count()); // 0 classes in _assemblies are marked with [Tree]

View File

@@ -191,7 +191,7 @@ namespace Umbraco.Tests.Testing
var proflogger = new ProfilingLogger(loggerFactory.CreateLogger<ProfilingLogger>(), profiler);
IOHelper = TestHelper.IOHelper;
TypeFinder = new TypeFinder(loggerFactory.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash());
TypeFinder = new TypeFinder(loggerFactory.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, loggerFactory), new VaryingRuntimeHash());
var appCaches = GetAppCaches();
var globalSettings = new GlobalSettings();
var settings = new WebRoutingSettings();

View File

@@ -81,7 +81,7 @@ namespace Umbraco.Extensions
var typeFinder = new TypeFinder(
loggerFactory.CreateLogger<TypeFinder>(),
new DefaultUmbracoAssemblyProvider(entryAssembly),
new DefaultUmbracoAssemblyProvider(entryAssembly, loggerFactory),
runtimeHash,
new TypeFinderConfig(Options.Create(typeFinderSettings))
);

View File

@@ -119,7 +119,7 @@ namespace Umbraco.Web
// assembly we can get and we can only get that if we put this code into the WebRuntime since the executing assembly is the 'current' one.
// For this purpose, it doesn't matter if it's Umbraco.Web or Umbraco.Infrastructure since all assemblies are in that same path and we are
// getting rid of netframework.
Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly()), runtimeHash);
Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(), _loggerFactory), runtimeHash);
}
/// <summary>