Adds new ctor to runtime hash class. Adds startup objects to the IUmbracoBuilder that are not otherwise available during configuration.

This commit is contained in:
Shannon
2021-07-09 15:31:01 -06:00
parent 1ef5290576
commit 7ec3afa5ff
13 changed files with 96 additions and 42 deletions

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Umbraco.Cms.Core.Composing
{
@@ -17,6 +18,24 @@ namespace Umbraco.Cms.Core.Composing
return this;
}
/// <summary>
/// Creates a runtime hash based on the assembly provider
/// </summary>
/// <param name="assemblyProvider"></param>
/// <returns></returns>
public RuntimeHashPaths AddAssemblies(IAssemblyProvider assemblyProvider)
{
foreach (Assembly assembly in assemblyProvider.Assemblies)
{
// TODO: We need to test this on a published website
if (!assembly.IsDynamic && assembly.Location != null)
{
AddFile(new FileInfo(assembly.Location));
}
}
return this;
}
public void AddFile(FileInfo fileInfo, bool scanFileContent = false) => _files.Add(fileInfo, scanFileContent);
public IEnumerable<DirectoryInfo> GetFolders() => _paths;

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
@@ -55,8 +54,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, IProfilingLogger profilingLogger, IEnumerable<Assembly> assembliesToScan = null)
: this(typeFinder, runtimeCache, localTempPath, logger, profilingLogger, true, assembliesToScan)
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)
{ }
/// <summary>
@@ -68,13 +67,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, IProfilingLogger profilingLogger, bool detectChanges, IEnumerable<Assembly> assembliesToScan = null)
public TypeLoader(ITypeFinder typeFinder, IAppPolicyCache runtimeCache, DirectoryInfo localTempPath, ILogger<TypeLoader> logger, IProfiler profiler, bool detectChanges, IEnumerable<Assembly> assembliesToScan = null)
{
if (profiler is null)
{
throw new ArgumentNullException(nameof(profiler));
}
TypeFinder = typeFinder ?? throw new ArgumentNullException(nameof(typeFinder));
_runtimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
_localTempPath = localTempPath;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_profilingLogger = profilingLogger ?? throw new ArgumentNullException(nameof(profilingLogger));
_profilingLogger = new ProfilingLogger(logger, profiler);
_assemblies = assembliesToScan;
_fileBasePath = new Lazy<string>(GetFileBasePath);

View File

@@ -1,7 +1,10 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Logging;
namespace Umbraco.Cms.Core.DependencyInjection
{
@@ -10,7 +13,24 @@ namespace Umbraco.Cms.Core.DependencyInjection
IServiceCollection Services { get; }
IConfiguration Config { get; }
TypeLoader TypeLoader { get; }
/// <summary>
/// A Logger factory created specifically for the <see cref="IUmbracoBuilder"/>. This is NOT the same
/// instance that will be resolved from DI. Use only if required during configuration.
/// </summary>
ILoggerFactory BuilderLoggerFactory { get; }
/// <summary>
/// A hosting environment created specifically for the <see cref="IUmbracoBuilder"/>. This is NOT the same
/// instance that will be resolved from DI. Use only if required during configuration.
/// </summary>
/// <remarks>
/// This may be null.
/// </remarks>
IHostingEnvironment BuilderHostingEnvironment { get; }
IProfiler Profiler { get; }
AppCaches AppCaches { get; }
TBuilder WithCollectionBuilder<TBuilder>() where TBuilder : ICollectionBuilder, new();
void Build();
}

View File

@@ -52,23 +52,41 @@ namespace Umbraco.Cms.Core.DependencyInjection
public TypeLoader TypeLoader { get; }
/// <inheritdoc />
public ILoggerFactory BuilderLoggerFactory { get; }
/// <inheritdoc />
public IHostingEnvironment BuilderHostingEnvironment { get; }
public IProfiler Profiler { get; }
public AppCaches AppCaches { get; }
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoBuilder"/> class.
/// Initializes a new instance of the <see cref="UmbracoBuilder"/> class primarily for testing.
/// </summary>
public UmbracoBuilder(IServiceCollection services, IConfiguration config, TypeLoader typeLoader)
: this(services, config, typeLoader, NullLoggerFactory.Instance)
: this(services, config, typeLoader, NullLoggerFactory.Instance, new NoopProfiler(), AppCaches.Disabled, null)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoBuilder"/> class.
/// </summary>
public UmbracoBuilder(IServiceCollection services, IConfiguration config, TypeLoader typeLoader, ILoggerFactory loggerFactory)
public UmbracoBuilder(
IServiceCollection services,
IConfiguration config,
TypeLoader typeLoader,
ILoggerFactory loggerFactory,
IProfiler profiler,
AppCaches appCaches,
IHostingEnvironment hostingEnvironment)
{
Services = services;
Config = config;
BuilderLoggerFactory = loggerFactory;
BuilderHostingEnvironment = hostingEnvironment;
Profiler = profiler;
AppCaches = appCaches;
TypeLoader = typeLoader;
AddCoreServices();
@@ -106,6 +124,9 @@ namespace Umbraco.Cms.Core.DependencyInjection
private void AddCoreServices()
{
Services.AddSingleton(AppCaches);
Services.AddSingleton(Profiler);
// Register as singleton to allow injection everywhere.
Services.AddSingleton<ServiceFactory>(p => p.GetService);
Services.AddSingleton<IEventAggregator, EventAggregator>();

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Cms.Core.Logging
/// <summary>
/// Initializes a new instance of the <see cref="ProfilingLogger"/> class.
/// </summary>
public ProfilingLogger(ILogger<ProfilingLogger> logger, IProfiler profiler)
public ProfilingLogger(ILogger logger, IProfiler profiler)
{
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
Profiler = profiler ?? throw new ArgumentNullException(nameof(profiler));

View File

@@ -30,7 +30,7 @@ namespace Umbraco.Tests.Benchmarks
cache,
null,
new NullLogger<TypeLoader>(),
new ProfilingLogger(new NullLogger<ProfilingLogger>(), new NoopProfiler()));
new NoopProfiler());
// populate the cache
cache.Insert(
@@ -43,7 +43,7 @@ namespace Umbraco.Tests.Benchmarks
NoAppCache.Instance,
null,
new NullLogger<TypeLoader>(),
new ProfilingLogger(new NullLogger<ProfilingLogger>(), new NoopProfiler()));
new NoopProfiler());
}
/// <summary>

View File

@@ -50,7 +50,7 @@ namespace Umbraco.Cms.Tests.Common
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<IProfilingLogger>());
new TypeLoader(Mock.Of<ITypeFinder>(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>());
//// public Configs GetConfigs() => GetConfigsFactory().Create();

View File

@@ -202,14 +202,15 @@ namespace Umbraco.Cms.Tests.Integration.Testing
services.AddRequiredNetCoreServices(TestHelper, webHostEnvironment);
// Add it!
Core.Hosting.IHostingEnvironment hostingEnvironment = TestHelper.GetHostingEnvironment();
TypeLoader typeLoader = services.AddTypeLoader(
GetType().Assembly,
TestHelper.GetHostingEnvironment(),
hostingEnvironment,
TestHelper.ConsoleLoggerFactory,
AppCaches.NoCache,
Configuration,
TestHelper.Profiler);
var builder = new UmbracoBuilder(services, Configuration, typeLoader, TestHelper.ConsoleLoggerFactory);
var builder = new UmbracoBuilder(services, Configuration, typeLoader, TestHelper.ConsoleLoggerFactory, TestHelper.Profiler, AppCaches.NoCache, hostingEnvironment);
builder.Services.AddLogger(TestHelper.GetHostingEnvironment(), TestHelper.GetLoggingConfiguration(), Configuration);

View File

@@ -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<IProfilingLogger>());
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>());
[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<IProfilingLogger>());
var typeLoader = new TypeLoader(typeFinder, 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());

View File

@@ -19,15 +19,11 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Composing
{
protected TypeLoader TypeLoader { get; private set; }
protected IProfilingLogger ProfilingLogger { get; private set; }
[SetUp]
public void Initialize()
{
ProfilingLogger = new ProfilingLogger(Mock.Of<ILogger<ProfilingLogger>>(), Mock.Of<IProfiler>());
var typeFinder = TestHelper.GetTypeFinder();
TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), ProfilingLogger, false, AssembliesToScan);
TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of<ILogger<TypeLoader>>(), Mock.Of<IProfiler>(), false, AssembliesToScan);
}
protected virtual IEnumerable<Assembly> AssembliesToScan

View File

@@ -51,7 +51,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Composing
NoAppCache.Instance,
new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)),
Mock.Of<ILogger<TypeLoader>>(),
new ProfilingLogger(Mock.Of<ILogger<ProfilingLogger>>(), Mock.Of<IProfiler>()),
Mock.Of<IProfiler>(),
false,
assemblies);
}

View File

@@ -101,12 +101,10 @@ namespace Umbraco.Extensions
services.AddSingleton(httpContextAccessor);
var requestCache = new HttpContextRequestAppCache(httpContextAccessor);
var appCaches = AppCaches.Create(requestCache);
services.AddUnique(appCaches);
var appCaches = AppCaches.Create(requestCache);
IProfiler profiler = GetWebProfiler(config);
services.AddUnique(profiler);
ILoggerFactory loggerFactory = LoggerFactory.Create(cfg => cfg.AddSerilog(Log.Logger, false));
TypeLoader typeLoader = services.AddTypeLoader(Assembly.GetEntryAssembly(), tempHostingEnvironment, loggerFactory, appCaches, config, profiler);
@@ -114,7 +112,7 @@ namespace Umbraco.Extensions
// other start filters are applied (depending on the ordering of IStartupFilters in DI).
services.AddTransient<IStartupFilter, UmbracoApplicationServicesCapture>();
return new UmbracoBuilder(services, config, typeLoader, loggerFactory);
return new UmbracoBuilder(services, config, typeLoader, loggerFactory, profiler, appCaches, tempHostingEnvironment);
}
/// <summary>

View File

@@ -65,23 +65,19 @@ namespace Umbraco.Extensions
ILoggerFactory loggerFactory,
Assembly entryAssembly,
IConfiguration config,
IProfilingLogger profilingLogger)
IProfiler profiler)
{
TypeFinderSettings typeFinderSettings = config.GetSection(Cms.Core.Constants.Configuration.ConfigTypeFinder).Get<TypeFinderSettings>() ?? new TypeFinderSettings();
var assemblyProvider = new DefaultUmbracoAssemblyProvider(entryAssembly, loggerFactory);
var runtimeHashPaths = new RuntimeHashPaths();
foreach(Assembly assembly in assemblyProvider.Assemblies)
{
// TODO: We need to test this on a published website
if (!assembly.IsDynamic && assembly.Location != null)
{
runtimeHashPaths.AddFile(new FileInfo(assembly.Location));
}
}
RuntimeHashPaths runtimeHashPaths = new RuntimeHashPaths().AddAssemblies(assemblyProvider);
var runtimeHash = new RuntimeHash(profilingLogger, runtimeHashPaths);
var runtimeHash = new RuntimeHash(
new ProfilingLogger(
loggerFactory.CreateLogger<RuntimeHash>(),
profiler),
runtimeHashPaths);
var typeFinder = new TypeFinder(
loggerFactory.CreateLogger<TypeFinder>(),
@@ -104,15 +100,14 @@ namespace Umbraco.Extensions
IConfiguration configuration,
IProfiler profiler)
{
var profilingLogger = new ProfilingLogger(loggerFactory.CreateLogger<ProfilingLogger>(), profiler);
var typeFinder = services.AddTypeFinder(loggerFactory, entryAssembly, configuration, profilingLogger);
ITypeFinder typeFinder = services.AddTypeFinder(loggerFactory, entryAssembly, configuration, profiler);
var typeLoader = new TypeLoader(
typeFinder,
appCaches.RuntimeCache,
new DirectoryInfo(hostingEnvironment.LocalTempPath),
loggerFactory.CreateLogger<TypeLoader>(),
profilingLogger
profiler
);
services.AddUnique<TypeLoader>(typeLoader);