Fixes typefinder/loader dependency refs, allows config to specify additional entry assemblies
This commit is contained in:
@@ -17,12 +17,17 @@ namespace Umbraco.Cms.Core.Composing
|
||||
{
|
||||
private readonly Assembly _entryPointAssembly;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly IEnumerable<string> _additionalTargetAssemblies;
|
||||
private List<Assembly> _discovered;
|
||||
|
||||
public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly, ILoggerFactory loggerFactory)
|
||||
public DefaultUmbracoAssemblyProvider(
|
||||
Assembly entryPointAssembly,
|
||||
ILoggerFactory loggerFactory,
|
||||
IEnumerable<string> additionalTargetAssemblies = null)
|
||||
{
|
||||
_entryPointAssembly = entryPointAssembly ?? throw new ArgumentNullException(nameof(entryPointAssembly));
|
||||
_loggerFactory = loggerFactory;
|
||||
_additionalTargetAssemblies = additionalTargetAssemblies;
|
||||
}
|
||||
|
||||
// TODO: It would be worth investigating a netcore3 version of this which would use
|
||||
@@ -40,7 +45,9 @@ namespace Umbraco.Cms.Core.Composing
|
||||
return _discovered;
|
||||
}
|
||||
|
||||
var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, Constants.Composing.UmbracoCoreAssemblyNames, true, _loggerFactory);
|
||||
IEnumerable<string> additionalTargetAssemblies = _additionalTargetAssemblies.Concat(Constants.Composing.UmbracoCoreAssemblyNames);
|
||||
|
||||
var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, additionalTargetAssemblies.ToArray(), true, _loggerFactory);
|
||||
_discovered = finder.Find().ToList();
|
||||
|
||||
return _discovered;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -18,6 +18,7 @@ namespace Umbraco.Cms.Core.Composing
|
||||
private readonly string[] _targetAssemblies;
|
||||
private readonly bool _includeTargets;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly ILogger<FindAssembliesWithReferencesTo> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -32,6 +33,7 @@ namespace Umbraco.Cms.Core.Composing
|
||||
_targetAssemblies = targetAssemblyNames;
|
||||
_includeTargets = includeTargets;
|
||||
_loggerFactory = loggerFactory;
|
||||
_logger = _loggerFactory.CreateLogger<FindAssembliesWithReferencesTo>();
|
||||
}
|
||||
|
||||
public IEnumerable<Assembly> Find()
|
||||
@@ -50,9 +52,10 @@ namespace Umbraco.Cms.Core.Composing
|
||||
{
|
||||
referenceItems.Add(Assembly.Load(target));
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
// occurs if we cannot load this ... for example in a test project where we aren't currently referencing Umbraco.Web, etc...
|
||||
_logger.LogDebug(ex, "Could not load assembly " + target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -51,14 +51,5 @@ namespace Umbraco.Cms.Core.Composing
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a hash value of the current runtime
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is used to detect if the runtime itself has changed, like a DLL has changed or another dynamically compiled
|
||||
/// part of the application has changed. This is used to detect if we need to re-type scan.
|
||||
/// </remarks>
|
||||
string GetRuntimeHash();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Umbraco.Cms.Core.Composing
|
||||
{
|
||||
private readonly ILogger<TypeFinder> _logger;
|
||||
private readonly IAssemblyProvider _assemblyProvider;
|
||||
private readonly IRuntimeHash _runtimeHash;
|
||||
private volatile HashSet<Assembly> _localFilteredAssemblyCache;
|
||||
private readonly object _localFilteredAssemblyCacheLocker = new object();
|
||||
private readonly List<string> _notifiedLoadExceptionAssemblies = new List<string>();
|
||||
@@ -27,13 +26,12 @@ namespace Umbraco.Cms.Core.Composing
|
||||
// used for benchmark tests
|
||||
internal bool QueryWithReferencingAssemblies { get; set; } = true;
|
||||
|
||||
public TypeFinder(ILogger<TypeFinder> logger, IAssemblyProvider assemblyProvider, IRuntimeHash runtimeHash, ITypeFinderConfig typeFinderConfig = null)
|
||||
public TypeFinder(ILogger<TypeFinder> logger, IAssemblyProvider assemblyProvider, ITypeFinderConfig typeFinderConfig = null)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_assemblyProvider = assemblyProvider;
|
||||
_runtimeHash = runtimeHash;
|
||||
_typeFinderConfig = typeFinderConfig;
|
||||
}
|
||||
}
|
||||
|
||||
private string[] _assembliesAcceptingLoadExceptions = null;
|
||||
|
||||
@@ -64,9 +62,12 @@ namespace Umbraco.Cms.Core.Composing
|
||||
var name = a.GetName().Name; // simple name of the assembly
|
||||
return AssembliesAcceptingLoadExceptions.Any(pattern =>
|
||||
{
|
||||
if (pattern.Length > name.Length) return false; // pattern longer than name
|
||||
if (pattern.Length == name.Length) return pattern.InvariantEquals(name); // same length, must be identical
|
||||
if (pattern[pattern.Length] != '.') return false; // pattern is shorter than name, must end with dot
|
||||
if (pattern.Length > name.Length)
|
||||
return false; // pattern longer than name
|
||||
if (pattern.Length == name.Length)
|
||||
return pattern.InvariantEquals(name); // same length, must be identical
|
||||
if (pattern[pattern.Length] != '.')
|
||||
return false; // pattern is shorter than name, must end with dot
|
||||
return name.StartsWith(pattern); // and name must start with pattern
|
||||
});
|
||||
}
|
||||
@@ -112,6 +113,8 @@ namespace Umbraco.Cms.Core.Composing
|
||||
&& exclusionFilter.Any(f => x.FullName.StartsWith(f)) == false);
|
||||
}
|
||||
|
||||
// TODO: Kill this
|
||||
|
||||
/// <summary>
|
||||
/// this is our assembly filter to filter out known types that def don't contain types we'd like to find or plugins
|
||||
/// </summary>
|
||||
@@ -232,9 +235,6 @@ namespace Umbraco.Cms.Core.Composing
|
||||
return GetClassesWithAttribute(attributeType, assemblyList, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetRuntimeHash() => _runtimeHash.GetHashValue();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Type for the string type name
|
||||
/// </summary>
|
||||
@@ -455,7 +455,8 @@ namespace Umbraco.Cms.Core.Composing
|
||||
var ex = new ReflectionTypeLoadException(rex.Types, rex.LoaderExceptions, sb.ToString());
|
||||
|
||||
// rethrow with new message, unless accepted
|
||||
if (AcceptsLoadExceptions(a) == false) throw ex;
|
||||
if (AcceptsLoadExceptions(a) == false)
|
||||
throw ex;
|
||||
|
||||
// log a warning, and return what we can
|
||||
lock (_notifiedLoadExceptionAssemblies)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Configuration.UmbracoSettings;
|
||||
@@ -15,17 +16,16 @@ namespace Umbraco.Cms.Core.Composing
|
||||
private readonly TypeFinderSettings _settings;
|
||||
private IEnumerable<string> _assembliesAcceptingLoadExceptions;
|
||||
|
||||
public TypeFinderConfig(IOptions<TypeFinderSettings> settings)
|
||||
{
|
||||
_settings = settings.Value;
|
||||
}
|
||||
public TypeFinderConfig(IOptions<TypeFinderSettings> settings) => _settings = settings.Value;
|
||||
|
||||
public IEnumerable<string> AssembliesAcceptingLoadExceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_assembliesAcceptingLoadExceptions != null)
|
||||
{
|
||||
return _assembliesAcceptingLoadExceptions;
|
||||
}
|
||||
|
||||
var s = _settings.AssembliesAcceptingLoadExceptions;
|
||||
return _assembliesAcceptingLoadExceptions = string.IsNullOrWhiteSpace(s)
|
||||
|
||||
@@ -25,9 +25,8 @@ namespace Umbraco.Cms.Core.Composing
|
||||
/// on a hash of the DLLs in the ~/bin folder to check for cache expiration.</para>
|
||||
/// </remarks>
|
||||
public sealed class TypeLoader
|
||||
{
|
||||
internal const string CacheKey = "umbraco-types.list";
|
||||
|
||||
{
|
||||
private readonly IRuntimeHash _runtimeHash;
|
||||
private readonly IAppPolicyCache _runtimeCache;
|
||||
private readonly ILogger<TypeLoader> _logger;
|
||||
private readonly IProfilingLogger _profilingLogger;
|
||||
@@ -44,7 +43,9 @@ namespace Umbraco.Cms.Core.Composing
|
||||
private bool _reportedChange;
|
||||
private readonly DirectoryInfo _localTempPath;
|
||||
private readonly Lazy<string> _fileBasePath;
|
||||
private readonly Dictionary<(string, string), IEnumerable<string>> EmptyCache = new Dictionary<(string, string), IEnumerable<string>>();
|
||||
private readonly Dictionary<(string, string), IEnumerable<string>> _emptyCache = new Dictionary<(string, string), IEnumerable<string>>();
|
||||
private string _typesListFilePath;
|
||||
private string _typesHashFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
|
||||
@@ -54,8 +55,8 @@ namespace Umbraco.Cms.Core.Composing
|
||||
/// <param name="localTempPath">Files storage location.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <param name="assembliesToScan"></param>
|
||||
public TypeLoader(ITypeFinder typeFinder, IAppPolicyCache runtimeCache, DirectoryInfo localTempPath, ILogger<TypeLoader> logger, IProfiler profiler, IEnumerable<Assembly> assembliesToScan = null)
|
||||
: this(typeFinder, runtimeCache, localTempPath, logger, profiler, true, assembliesToScan)
|
||||
public TypeLoader(ITypeFinder typeFinder, IRuntimeHash runtimeHash, IAppPolicyCache runtimeCache, DirectoryInfo localTempPath, ILogger<TypeLoader> logger, IProfiler profiler, IEnumerable<Assembly> assembliesToScan = null)
|
||||
: this(typeFinder, runtimeHash, runtimeCache, localTempPath, logger, profiler, true, assembliesToScan)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
@@ -67,14 +68,18 @@ namespace Umbraco.Cms.Core.Composing
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <param name="detectChanges">Whether to detect changes using hashes.</param>
|
||||
/// <param name="assembliesToScan"></param>
|
||||
public TypeLoader(ITypeFinder typeFinder, IAppPolicyCache runtimeCache, DirectoryInfo localTempPath, ILogger<TypeLoader> logger, IProfiler profiler, bool detectChanges, IEnumerable<Assembly> assembliesToScan = null)
|
||||
public TypeLoader(ITypeFinder typeFinder, IRuntimeHash runtimeHash, IAppPolicyCache runtimeCache, DirectoryInfo localTempPath, ILogger<TypeLoader> logger, IProfiler profiler, bool detectChanges, IEnumerable<Assembly> assembliesToScan = null)
|
||||
{
|
||||
if (profiler is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(profiler));
|
||||
}
|
||||
|
||||
var runtimeHashValue = runtimeHash.GetHashValue();
|
||||
CacheKey = runtimeHashValue + "umbraco-types.list";
|
||||
|
||||
TypeFinder = typeFinder ?? throw new ArgumentNullException(nameof(typeFinder));
|
||||
_runtimeHash = runtimeHash;
|
||||
_runtimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
|
||||
_localTempPath = localTempPath;
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -119,6 +124,8 @@ namespace Umbraco.Cms.Core.Composing
|
||||
}
|
||||
}
|
||||
|
||||
internal string CacheKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying <see cref="ITypeFinder"/>
|
||||
/// </summary>
|
||||
@@ -202,9 +209,11 @@ namespace Umbraco.Cms.Core.Composing
|
||||
get
|
||||
{
|
||||
if (_currentAssembliesHash != null)
|
||||
{
|
||||
return _currentAssembliesHash;
|
||||
}
|
||||
|
||||
_currentAssembliesHash = TypeFinder.GetRuntimeHash();
|
||||
_currentAssembliesHash = _runtimeHash.GetHashValue();
|
||||
|
||||
return _currentAssembliesHash;
|
||||
}
|
||||
@@ -268,7 +277,7 @@ namespace Umbraco.Cms.Core.Composing
|
||||
}
|
||||
}
|
||||
|
||||
return EmptyCache;
|
||||
return _emptyCache;
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
@@ -277,7 +286,7 @@ namespace Umbraco.Cms.Core.Composing
|
||||
var typesListFilePath = GetTypesListFilePath();
|
||||
if (typesListFilePath == null || File.Exists(typesListFilePath) == false)
|
||||
{
|
||||
return EmptyCache;
|
||||
return _emptyCache;
|
||||
}
|
||||
|
||||
var cache = new Dictionary<(string, string), IEnumerable<string>>();
|
||||
@@ -332,9 +341,9 @@ namespace Umbraco.Cms.Core.Composing
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
public string GetTypesListFilePath() => _fileBasePath.Value == null ? null : _fileBasePath.Value + ".list";
|
||||
public string GetTypesListFilePath() => _typesListFilePath ??= _fileBasePath.Value == null ? null : _fileBasePath.Value + ".list";
|
||||
|
||||
private string GetTypesHashFilePath() => _fileBasePath.Value == null ? null : _fileBasePath.Value + ".hash";
|
||||
private string GetTypesHashFilePath() => _typesHashFilePath ??= _fileBasePath.Value == null ? null : _fileBasePath.Value + ".hash";
|
||||
|
||||
/// <summary>
|
||||
/// Used to produce the Lazy value of _fileBasePath
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Cms.Core.Configuration.Models
|
||||
{
|
||||
/// <summary>
|
||||
@@ -13,5 +16,11 @@ namespace Umbraco.Cms.Core.Configuration.Models
|
||||
/// Gets or sets a value for the assemblies that accept load exceptions during type finder operations.
|
||||
/// </summary>
|
||||
public string AssembliesAcceptingLoadExceptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// By default the entry assemblies for scanning plugin types is the Umbraco DLLs. If you require
|
||||
/// scanning for plugins based on different root referenced assemblies you can add the assembly name to this list.
|
||||
/// </summary>
|
||||
public IEnumerable<string> AdditionalEntryAssemblies { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace Umbraco.Tests.Benchmarks
|
||||
|
||||
public TypeFinderBenchmarks()
|
||||
{
|
||||
_typeFinder1 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
|
||||
_typeFinder2 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash())
|
||||
_typeFinder1 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance));
|
||||
_typeFinder2 = new TypeFinder(new NullLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance))
|
||||
{
|
||||
QueryWithReferencingAssemblies = false
|
||||
};
|
||||
|
||||
@@ -21,12 +21,12 @@ namespace Umbraco.Tests.Benchmarks
|
||||
{
|
||||
var typeFinder1 = new TypeFinder(
|
||||
new NullLogger<TypeFinder>(),
|
||||
new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance),
|
||||
new VaryingRuntimeHash());
|
||||
new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance));
|
||||
|
||||
var cache = new ObjectCacheAppCache();
|
||||
_typeLoader1 = new TypeLoader(
|
||||
typeFinder1,
|
||||
new VaryingRuntimeHash(),
|
||||
cache,
|
||||
null,
|
||||
new NullLogger<TypeLoader>(),
|
||||
@@ -40,6 +40,7 @@ namespace Umbraco.Tests.Benchmarks
|
||||
|
||||
_typeLoader2 = new TypeLoader(
|
||||
typeFinder1,
|
||||
new VaryingRuntimeHash(),
|
||||
NoAppCache.Instance,
|
||||
null,
|
||||
new NullLogger<TypeLoader>(),
|
||||
|
||||
@@ -44,13 +44,13 @@ namespace Umbraco.Cms.Tests.Common
|
||||
protected TestHelperBase(Assembly entryAssembly)
|
||||
{
|
||||
MainDom = new SimpleMainDom();
|
||||
_typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(entryAssembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
|
||||
_typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger<TypeFinder>(), new DefaultUmbracoAssemblyProvider(entryAssembly, NullLoggerFactory.Instance));
|
||||
}
|
||||
|
||||
public ITypeFinder GetTypeFinder() => _typeFinder;
|
||||
|
||||
public TypeLoader GetMockedTypeLoader() =>
|
||||
new TypeLoader(Mock.Of<ITypeFinder>(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
new TypeLoader(Mock.Of<ITypeFinder>(), new VaryingRuntimeHash(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
|
||||
//// public Configs GetConfigs() => GetConfigsFactory().Create();
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Components
|
||||
|
||||
private static IServiceCollection MockRegister() => new ServiceCollection();
|
||||
|
||||
private static TypeLoader MockTypeLoader() => new TypeLoader(Mock.Of<ITypeFinder>(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
private static TypeLoader MockTypeLoader() => new TypeLoader(Mock.Of<ITypeFinder>(), new VaryingRuntimeHash(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
|
||||
[Test]
|
||||
public void Boot1A()
|
||||
@@ -438,7 +438,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Components
|
||||
public void AllComposers()
|
||||
{
|
||||
ITypeFinder typeFinder = TestHelper.GetTypeFinder();
|
||||
var typeLoader = new TypeLoader(typeFinder, AppCaches.Disabled.RuntimeCache, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
var typeLoader = new TypeLoader(typeFinder, new VaryingRuntimeHash(), AppCaches.Disabled.RuntimeCache, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
|
||||
|
||||
IServiceCollection register = MockRegister();
|
||||
var builder = new UmbracoBuilder(register, Mock.Of<IConfiguration>(), TestHelper.GetMockedTypeLoader());
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Composing
|
||||
public void Initialize()
|
||||
{
|
||||
var typeFinder = TestHelper.GetTypeFinder();
|
||||
TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>(), false, AssembliesToScan);
|
||||
TypeLoader = new TypeLoader(typeFinder, new VaryingRuntimeHash(), NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>(), false, AssembliesToScan);
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<Assembly> AssembliesToScan
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Cms.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, NullLoggerFactory.Instance), new VaryingRuntimeHash());
|
||||
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance));
|
||||
IEnumerable<Type> typesFound = typeFinder.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies);
|
||||
Assert.AreEqual(2, typesFound.Count());
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Composing
|
||||
[Test]
|
||||
public void Find_Classes_With_Attribute()
|
||||
{
|
||||
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash());
|
||||
var typeFinder = new TypeFinder(Mock.Of<ILogger<TypeFinder>>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance));
|
||||
IEnumerable<Type> typesFound = typeFinder.FindClassesWithAttribute<TreeAttribute>(_assemblies);
|
||||
Assert.AreEqual(0, typesFound.Count()); // 0 classes in _assemblies are marked with [Tree]
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Composing
|
||||
};
|
||||
_typeLoader = new TypeLoader(
|
||||
typeFinder,
|
||||
new VaryingRuntimeHash(),
|
||||
NoAppCache.Instance,
|
||||
new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)),
|
||||
Mock.Of<ILogger<TypeLoader>>(),
|
||||
|
||||
@@ -106,7 +106,14 @@ namespace Umbraco.Extensions
|
||||
IProfiler profiler = GetWebProfiler(config);
|
||||
|
||||
ILoggerFactory loggerFactory = LoggerFactory.Create(cfg => cfg.AddSerilog(Log.Logger, false));
|
||||
TypeLoader typeLoader = services.AddTypeLoader(Assembly.GetEntryAssembly(), tempHostingEnvironment, loggerFactory, appCaches, config, profiler);
|
||||
|
||||
TypeLoader typeLoader = services.AddTypeLoader(
|
||||
Assembly.GetEntryAssembly(),
|
||||
tempHostingEnvironment,
|
||||
loggerFactory,
|
||||
appCaches,
|
||||
config,
|
||||
profiler);
|
||||
|
||||
// adds the umbraco startup filter which will call UseUmbraco early on before
|
||||
// other start filters are applied (depending on the ordering of IStartupFilters in DI).
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog;
|
||||
@@ -60,37 +61,22 @@ namespace Umbraco.Extensions
|
||||
return services;
|
||||
}
|
||||
|
||||
internal static ITypeFinder AddTypeFinder(
|
||||
this IServiceCollection services,
|
||||
ILoggerFactory loggerFactory,
|
||||
Assembly entryAssembly,
|
||||
IConfiguration config,
|
||||
IProfiler profiler)
|
||||
{
|
||||
TypeFinderSettings typeFinderSettings = config.GetSection(Cms.Core.Constants.Configuration.ConfigTypeFinder).Get<TypeFinderSettings>() ?? new TypeFinderSettings();
|
||||
|
||||
var assemblyProvider = new DefaultUmbracoAssemblyProvider(entryAssembly, loggerFactory);
|
||||
|
||||
RuntimeHashPaths runtimeHashPaths = new RuntimeHashPaths().AddAssemblies(assemblyProvider);
|
||||
|
||||
var runtimeHash = new RuntimeHash(
|
||||
new ProfilingLogger(
|
||||
loggerFactory.CreateLogger<RuntimeHash>(),
|
||||
profiler),
|
||||
runtimeHashPaths);
|
||||
|
||||
var typeFinder = new TypeFinder(
|
||||
loggerFactory.CreateLogger<TypeFinder>(),
|
||||
assemblyProvider,
|
||||
runtimeHash,
|
||||
new TypeFinderConfig(Options.Create(typeFinderSettings))
|
||||
);
|
||||
|
||||
services.AddUnique<ITypeFinder>(typeFinder);
|
||||
|
||||
return typeFinder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called to create the <see cref="TypeLoader"/> to assign to the <see cref="IUmbracoBuilder"/>
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="entryAssembly"></param>
|
||||
/// <param name="hostingEnvironment"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="appCaches"></param>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="profiler"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This should never be called in a web project. It is used internally by Umbraco but could be used in unit tests.
|
||||
/// If called in a web project it will have no affect except to create and return a new TypeLoader but this will not
|
||||
/// be the instance in DI.
|
||||
/// </remarks>
|
||||
public static TypeLoader AddTypeLoader(
|
||||
this IServiceCollection services,
|
||||
Assembly entryAssembly,
|
||||
@@ -100,17 +86,42 @@ namespace Umbraco.Extensions
|
||||
IConfiguration configuration,
|
||||
IProfiler profiler)
|
||||
{
|
||||
ITypeFinder typeFinder = services.AddTypeFinder(loggerFactory, entryAssembly, configuration, profiler);
|
||||
TypeFinderSettings typeFinderSettings = configuration.GetSection(Cms.Core.Constants.Configuration.ConfigTypeFinder).Get<TypeFinderSettings>() ?? new TypeFinderSettings();
|
||||
|
||||
var assemblyProvider = new DefaultUmbracoAssemblyProvider(
|
||||
entryAssembly,
|
||||
loggerFactory,
|
||||
typeFinderSettings.AdditionalEntryAssemblies);
|
||||
|
||||
RuntimeHashPaths runtimeHashPaths = new RuntimeHashPaths().AddAssemblies(assemblyProvider);
|
||||
|
||||
var runtimeHash = new RuntimeHash(
|
||||
new ProfilingLogger(
|
||||
loggerFactory.CreateLogger<RuntimeHash>(),
|
||||
profiler),
|
||||
runtimeHashPaths);
|
||||
|
||||
var typeFinderConfig = new TypeFinderConfig(Options.Create(typeFinderSettings));
|
||||
|
||||
var typeFinder = new TypeFinder(
|
||||
loggerFactory.CreateLogger<TypeFinder>(),
|
||||
assemblyProvider,
|
||||
typeFinderConfig
|
||||
);
|
||||
|
||||
var typeLoader = new TypeLoader(
|
||||
typeFinder,
|
||||
runtimeHash,
|
||||
appCaches.RuntimeCache,
|
||||
new DirectoryInfo(hostingEnvironment.LocalTempPath),
|
||||
loggerFactory.CreateLogger<TypeLoader>(),
|
||||
profiler
|
||||
);
|
||||
|
||||
services.AddUnique<TypeLoader>(typeLoader);
|
||||
// This will add it ONCE and not again which is what we want since we don't actually want people to call this method
|
||||
// in the web project.
|
||||
services.TryAddSingleton<ITypeFinder>(typeFinder);
|
||||
services.TryAddSingleton<TypeLoader>(typeLoader);
|
||||
|
||||
return typeLoader;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user