Adjust type finder and adds benchmark
This commit is contained in:
@@ -16,6 +16,13 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IAssemblyProvider _assemblyProvider;
|
||||
private volatile HashSet<Assembly> _localFilteredAssemblyCache;
|
||||
private readonly object _localFilteredAssemblyCacheLocker = new object();
|
||||
private readonly List<string> _notifiedLoadExceptionAssemblies = new List<string>();
|
||||
private static readonly ConcurrentDictionary<string, Type> TypeNamesCache = new ConcurrentDictionary<string, Type>();
|
||||
private readonly string[] _assembliesAcceptingLoadExceptions;
|
||||
|
||||
internal bool QueryWithReferencingAssemblies = true;
|
||||
|
||||
public TypeFinder(ILogger logger, IAssemblyProvider assemblyProvider, ITypeFinderConfig typeFinderConfig = null)
|
||||
{
|
||||
@@ -24,12 +31,6 @@ namespace Umbraco.Core.Composing
|
||||
_assembliesAcceptingLoadExceptions = typeFinderConfig?.AssembliesAcceptingLoadExceptions.Where(x => !x.IsNullOrWhiteSpace()).ToArray() ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
private volatile HashSet<Assembly> _localFilteredAssemblyCache;
|
||||
private readonly object _localFilteredAssemblyCacheLocker = new object();
|
||||
private readonly List<string> _notifiedLoadExceptionAssemblies = new List<string>();
|
||||
private static readonly ConcurrentDictionary<string, Type> TypeNamesCache= new ConcurrentDictionary<string, Type>();
|
||||
private readonly string[] _assembliesAcceptingLoadExceptions;
|
||||
|
||||
private bool AcceptsLoadExceptions(Assembly a)
|
||||
{
|
||||
if (_assembliesAcceptingLoadExceptions.Length == 0)
|
||||
@@ -268,18 +269,24 @@ namespace Umbraco.Core.Composing
|
||||
var stack = new Stack<Assembly>();
|
||||
stack.Push(attributeType.Assembly);
|
||||
|
||||
if (!QueryWithReferencingAssemblies)
|
||||
{
|
||||
foreach (var a in candidateAssemblies)
|
||||
stack.Push(a);
|
||||
}
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var assembly = stack.Pop();
|
||||
|
||||
Type[] assemblyTypes = null;
|
||||
IReadOnlyList<Type> assemblyTypes = null;
|
||||
if (assembly != attributeType.Assembly || attributeAssemblyIsCandidate)
|
||||
{
|
||||
// get all assembly types that can be assigned to baseType
|
||||
try
|
||||
{
|
||||
assemblyTypes = GetTypesWithFormattedException(assembly)
|
||||
.ToArray(); // in try block
|
||||
.ToList(); // in try block
|
||||
}
|
||||
catch (TypeLoadException ex)
|
||||
{
|
||||
@@ -299,10 +306,13 @@ namespace Umbraco.Core.Composing
|
||||
if (assembly != attributeType.Assembly && assemblyTypes.Where(attributeType.IsAssignableFrom).Any() == false)
|
||||
continue;
|
||||
|
||||
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
|
||||
if (QueryWithReferencingAssemblies)
|
||||
{
|
||||
candidateAssemblies.Remove(referencing);
|
||||
stack.Push(referencing);
|
||||
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
|
||||
{
|
||||
candidateAssemblies.Remove(referencing);
|
||||
stack.Push(referencing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,19 +343,25 @@ namespace Umbraco.Core.Composing
|
||||
var stack = new Stack<Assembly>();
|
||||
stack.Push(baseType.Assembly);
|
||||
|
||||
if (!QueryWithReferencingAssemblies)
|
||||
{
|
||||
foreach (var a in candidateAssemblies)
|
||||
stack.Push(a);
|
||||
}
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var assembly = stack.Pop();
|
||||
|
||||
// get all assembly types that can be assigned to baseType
|
||||
Type[] assemblyTypes = null;
|
||||
IReadOnlyList<Type> assemblyTypes = null;
|
||||
if (assembly != baseType.Assembly || baseTypeAssemblyIsCandidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
assemblyTypes = GetTypesWithFormattedException(assembly)
|
||||
.Where(baseType.IsAssignableFrom)
|
||||
.ToArray(); // in try block
|
||||
.ToList(); // in try block
|
||||
}
|
||||
catch (TypeLoadException ex)
|
||||
{
|
||||
@@ -365,10 +381,13 @@ namespace Umbraco.Core.Composing
|
||||
if (assembly != baseType.Assembly && assemblyTypes.All(x => x.IsSealed))
|
||||
continue;
|
||||
|
||||
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
|
||||
if (QueryWithReferencingAssemblies)
|
||||
{
|
||||
candidateAssemblies.Remove(referencing);
|
||||
stack.Push(referencing);
|
||||
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
|
||||
{
|
||||
candidateAssemblies.Remove(referencing);
|
||||
stack.Push(referencing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,9 +82,9 @@ namespace Umbraco.Core.Composing
|
||||
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
|
||||
/// reference that assembly, same with the global.asax assembly.
|
||||
/// </remarks>
|
||||
public static Assembly[] GetReferencingAssemblies(Assembly assembly, IEnumerable<Assembly> assemblies)
|
||||
public static IReadOnlyList<Assembly> GetReferencingAssemblies(Assembly assembly, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
if (assembly.IsAppCodeAssembly() || assembly.IsGlobalAsaxAssembly())
|
||||
if (assembly.IsDynamic || assembly.IsAppCodeAssembly() || assembly.IsGlobalAsaxAssembly())
|
||||
return EmptyAssemblies;
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Composing
|
||||
// should only be scanning those assemblies because any other assembly will definitely not
|
||||
// contain sub type's of the one we're currently looking for
|
||||
var name = assembly.GetName().Name;
|
||||
return assemblies.Where(x => x == assembly || HasReference(x, name)).ToArray();
|
||||
return assemblies.Where(x => x == assembly || HasReference(x, name)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
30
src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs
Normal file
30
src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Tests.Benchmarks.Config;
|
||||
|
||||
namespace Umbraco.Tests.Benchmarks
|
||||
{
|
||||
[MediumRunJob]
|
||||
[MemoryDiagnoser]
|
||||
public class TypeFinderBenchmarks
|
||||
{
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public void WithGetReferencingAssembliesCheck()
|
||||
{
|
||||
var typeFinder1 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly));
|
||||
var found = typeFinder1.FindClassesOfType<IDiscoverable>().Count();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void WithoutGetReferencingAssembliesCheck()
|
||||
{
|
||||
var typeFinder2 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly));
|
||||
typeFinder2.QueryWithReferencingAssemblies = false;
|
||||
var found = typeFinder2.FindClassesOfType<IDiscoverable>().Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@
|
||||
<Compile Include="SqlTemplatesBenchmark.cs" />
|
||||
<Compile Include="StringReplaceManyBenchmarks.cs" />
|
||||
<Compile Include="TryConvertToBenchmarks.cs" />
|
||||
<Compile Include="TypeFinderBenchmarks.cs" />
|
||||
<Compile Include="XmlBenchmarks.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user