Fixes tests and some issues discovered
This commit is contained in:
@@ -8,13 +8,21 @@ namespace Umbraco.Core.Composing
|
||||
/// Returns a list of scannable assemblies based on an entry point assembly and it's references
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will recursively search through the entry point's assemblies and Umbraco's core assemblies (Core/Web) and their references
|
||||
/// This will recursively search through the entry point's assemblies and Umbraco's core assemblies and their references
|
||||
/// to create a list of scannable assemblies based on whether they themselves or their transitive dependencies reference Umbraco core assemblies.
|
||||
/// </remarks>
|
||||
public class DefaultUmbracoAssemblyProvider : IAssemblyProvider
|
||||
{
|
||||
private readonly Assembly _entryPointAssembly;
|
||||
private static readonly string[] UmbracoCoreAssemblyNames = new[] { "Umbraco.Core", "Umbraco.Web" };
|
||||
private static readonly string[] UmbracoCoreAssemblyNames = new[]
|
||||
{
|
||||
"Umbraco.Core",
|
||||
"Umbraco.Web",
|
||||
"Umbraco.Infrastructure",
|
||||
"Umbraco.PublishedCache.NuCache",
|
||||
"Umbraco.ModelsBuilder.Embedded",
|
||||
"Umbraco.Examine.Lucene",
|
||||
};
|
||||
|
||||
public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly)
|
||||
{
|
||||
@@ -26,10 +34,7 @@ namespace Umbraco.Core.Composing
|
||||
get
|
||||
{
|
||||
var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, UmbracoCoreAssemblyNames, true);
|
||||
foreach(var found in finder.Find())
|
||||
{
|
||||
yield return found;
|
||||
}
|
||||
return finder.Find();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,12 @@ namespace Umbraco.Core.Composing
|
||||
var assemblies = new HashSet<Assembly>(_assemblies);
|
||||
|
||||
// Get the unique directories of the assemblies
|
||||
var assemblyLocations = GetAssemblyLocations(assemblies).ToList();
|
||||
var assemblyLocations = GetAssemblyFolders(assemblies).ToList();
|
||||
|
||||
// Load in each assembly in the directory of the entry assembly to be included in the search
|
||||
// for Umbraco dependencies/transitive dependencies
|
||||
foreach(var location in assemblyLocations)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(location);
|
||||
|
||||
foreach(var dir in assemblyLocations)
|
||||
{
|
||||
foreach(var dll in Directory.EnumerateFiles(dir, "*.dll"))
|
||||
{
|
||||
var assemblyName = AssemblyName.GetAssemblyName(dll);
|
||||
@@ -85,9 +83,9 @@ namespace Umbraco.Core.Composing
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<string> GetAssemblyLocations(IEnumerable<Assembly> assemblies)
|
||||
private IEnumerable<string> GetAssemblyFolders(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
return assemblies.Select(x => GetAssemblyLocation(x).ToLowerInvariant()).Distinct();
|
||||
return assemblies.Select(x => Path.GetDirectoryName(GetAssemblyLocation(x)).ToLowerInvariant()).Distinct();
|
||||
}
|
||||
|
||||
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/ApplicationParts/RelatedAssemblyAttribute.cs
|
||||
@@ -102,25 +100,30 @@ namespace Umbraco.Core.Composing
|
||||
return assembly.Location;
|
||||
}
|
||||
|
||||
private Classification Resolve(Assembly assemblyItem)
|
||||
private Classification Resolve(Assembly assembly)
|
||||
{
|
||||
if (_classifications.TryGetValue(assemblyItem, out var classification))
|
||||
if (_classifications.TryGetValue(assembly, out var classification))
|
||||
{
|
||||
return classification;
|
||||
}
|
||||
|
||||
// Initialize the dictionary with a value to short-circuit recursive references.
|
||||
classification = Classification.Unknown;
|
||||
_classifications[assemblyItem] = classification;
|
||||
|
||||
if (_umbracoAssemblies.Contains(assemblyItem.GetName().Name))
|
||||
_classifications[assembly] = classification;
|
||||
|
||||
if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => assembly.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
// if its part of the filter it doesn't reference umbraco
|
||||
classification = Classification.DoesNotReferenceUmbraco;
|
||||
}
|
||||
else if (_umbracoAssemblies.Contains(assembly.GetName().Name))
|
||||
{
|
||||
classification = Classification.IsUmbraco;
|
||||
}
|
||||
else
|
||||
{
|
||||
classification = Classification.DoesNotReferenceUmbraco;
|
||||
foreach (var reference in GetReferences(assemblyItem))
|
||||
foreach (var reference in GetReferences(assembly))
|
||||
{
|
||||
// recurse
|
||||
var referenceClassification = Resolve(reference);
|
||||
@@ -134,7 +137,7 @@ namespace Umbraco.Core.Composing
|
||||
}
|
||||
|
||||
Debug.Assert(classification != Classification.Unknown);
|
||||
_classifications[assemblyItem] = classification;
|
||||
_classifications[assembly] = classification;
|
||||
return classification;
|
||||
}
|
||||
|
||||
@@ -147,15 +150,15 @@ namespace Umbraco.Core.Composing
|
||||
continue;
|
||||
|
||||
var reference = Assembly.Load(referenceName);
|
||||
|
||||
if (!_lookup.Contains(reference))
|
||||
{
|
||||
// A dependency references an item that isn't referenced by this project.
|
||||
// We'll construct an item for so that we can calculate the classification based on it's name.
|
||||
// We'll add this reference so that we can calculate the classification.
|
||||
|
||||
_lookup.Add(reference);
|
||||
|
||||
yield return reference;
|
||||
}
|
||||
_lookup.Add(reference);
|
||||
}
|
||||
yield return reference;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,9 @@ namespace Umbraco.Core.Composing
|
||||
/// NOTE this means that "foo." will NOT exclude "foo.dll" but only "foo.*.dll"
|
||||
/// </remarks>
|
||||
internal static readonly string[] KnownAssemblyExclusionFilter = {
|
||||
"mscorlib",
|
||||
"mscorlib,",
|
||||
"netstandard,",
|
||||
"System,",
|
||||
"Antlr3.",
|
||||
"AutoMapper,",
|
||||
"AutoMapper.",
|
||||
@@ -148,6 +150,7 @@ namespace Umbraco.Core.Composing
|
||||
"ImageProcessor",
|
||||
"MiniProfiler.",
|
||||
"Owin,",
|
||||
"SQLite",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -378,7 +378,8 @@ namespace Umbraco.Tests.Components
|
||||
var composition = new Composition(register, typeLoader, Mock.Of<IProfilingLogger>(),
|
||||
MockRuntimeState(RuntimeLevel.Run), Configs, TestHelper.IOHelper, AppCaches.NoCache);
|
||||
|
||||
var types = typeLoader.GetTypes<IComposer>().Where(x => x.FullName.StartsWith("Umbraco.Core.") || x.FullName.StartsWith("Umbraco.Web"));
|
||||
var allComposers = typeLoader.GetTypes<IComposer>().ToList();
|
||||
var types = allComposers.Where(x => x.FullName.StartsWith("Umbraco.Core.") || x.FullName.StartsWith("Umbraco.Web")).ToList();
|
||||
var composers = new Composers(composition, types, Enumerable.Empty<Attribute>(), Mock.Of<IProfilingLogger>());
|
||||
var requirements = composers.GetRequirements();
|
||||
var report = Composers.GetComposersReport(requirements);
|
||||
|
||||
@@ -125,6 +125,10 @@ namespace Umbraco.Tests.Runtimes
|
||||
|
||||
}
|
||||
|
||||
// override because we cannot use Assembly.GetEntryAssembly in Nunit tests since that is always null
|
||||
protected override ITypeFinder GetTypeFinder()
|
||||
=> new TypeFinder(Logger, new DefaultUmbracoAssemblyProvider(GetType().Assembly));
|
||||
|
||||
// must override the database factory
|
||||
// else BootFailedException because U cannot connect to the configured db
|
||||
protected internal override IUmbracoDatabaseFactory GetDatabaseFactory()
|
||||
|
||||
@@ -45,7 +45,9 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
public static ITypeFinder GetTypeFinder()
|
||||
{
|
||||
var typeFinder = new TypeFinder(Mock.Of<ILogger>(), new DefaultUmbracoAssemblyProvider(typeof(TestHelper).Assembly));
|
||||
|
||||
var typeFinder = new TypeFinder(Mock.Of<ILogger>(),
|
||||
new DefaultUmbracoAssemblyProvider(typeof(TestHelper).Assembly));
|
||||
return typeFinder;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user