From 7c78b5b34f18bee22ee04f21fa346575b4ef97a3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 4 Sep 2020 00:27:43 +1000 Subject: [PATCH] Updates CoreRuntime with better dependencies so we can disable caches, fixes integration test to run multiple callbacks registered for TearDown, ensure we TearDown the runtime. --- .../Implement/ContentTypeRepository.cs | 5 +- .../Implement/ContentTypeRepositoryBase.cs | 18 ++++++ .../Implement/MediaTypeRepository.cs | 5 +- .../Implement/MemberTypeRepository.cs | 5 +- .../Runtime/CoreRuntime.cs | 36 +++-------- src/Umbraco.Tests.Integration/RuntimeTests.cs | 6 +- .../UmbracoBuilderExtensions.cs | 22 +++++-- .../UmbracoTestServerTestBase.cs | 17 ++--- .../Testing/IntegrationTestComposer.cs | 2 + .../Testing/UmbracoIntegrationTest.cs | 62 +++++++++++++------ .../Routing/RenderRouteHandlerTests.cs | 2 +- .../Runtimes/CoreRuntimeTests.cs | 2 +- src/Umbraco.Tests/Runtimes/StandaloneTests.cs | 4 +- .../UmbracoCoreServiceCollectionExtensions.cs | 30 +++++---- src/Umbraco.Web/UmbracoApplication.cs | 7 ++- 15 files changed, 133 insertions(+), 90 deletions(-) diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs index 61aabdc1b5..868e088d93 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs @@ -54,11 +54,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement protected override bool PerformExists(Guid id) => GetMany().FirstOrDefault(x => x.Key == id) != null; - protected override IEnumerable PerformGetAll(params int[] ids) + protected override IEnumerable GetAllWithFullCachePolicy() { - // the cache policy will always want everything - // even GetMany(ids) gets everything and filters afterwards - if (ids.Any()) throw new PanicException("There can be no ids specified"); return CommonRepository.GetAllTypes().OfType(); } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index b2a83e83fd..50ba0a698b 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -90,6 +90,24 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return moveInfo; } + protected override IEnumerable PerformGetAll(params int[] ids) + { + var result = GetAllWithFullCachePolicy(); + + // By default the cache policy will always want everything + // even GetMany(ids) gets everything and filters afterwards, + // however if we are using No Cache, we must still be able to support + // collections of Ids, so this is to work around that: + if (ids.Any()) + { + return result.Where(x => ids.Contains(x.Id)); + } + + return result; + } + + protected abstract IEnumerable GetAllWithFullCachePolicy(); + protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, ValueStorageType storageType, string propertyTypeAlias) { return new PropertyType(_shortStringHelper, propertyEditorAlias, storageType, propertyTypeAlias); diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs index c6caa40750..818b5c9f21 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs @@ -48,11 +48,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement protected override IMediaType PerformGet(string alias) => GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); - protected override IEnumerable PerformGetAll(params int[] ids) + protected override IEnumerable GetAllWithFullCachePolicy() { - // the cache policy will always want everything - // even GetMany(ids) gets everything and filters afterwards - if (ids.Any()) throw new PanicException("There can be no ids specified"); return CommonRepository.GetAllTypes().OfType(); } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs index b9c40eebc9..059035a9bc 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs @@ -59,11 +59,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement protected override IMemberType PerformGet(string alias) => GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); - protected override IEnumerable PerformGetAll(params int[] ids) + protected override IEnumerable GetAllWithFullCachePolicy() { - // the cache policy will always want everything - // even GetMany(ids) gets everything and filters afterwards - if (ids.Any()) throw new PanicException("There can be no ids specified"); return CommonRepository.GetAllTypes().OfType(); } diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index ff86f87569..2a925f9de9 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -27,12 +27,11 @@ namespace Umbraco.Core.Runtime // runtime state, this instance will get replaced again once the essential services are available to run the check private RuntimeState _state = RuntimeState.Booting(); private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker; - private readonly IRequestCache _requestCache; private readonly IGlobalSettings _globalSettings; private readonly IConnectionStrings _connectionStrings; public CoreRuntime( - Configs configs, + Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, @@ -43,10 +42,11 @@ namespace Umbraco.Core.Runtime IDbProviderFactoryCreator dbProviderFactoryCreator, IMainDom mainDom, ITypeFinder typeFinder, - IRequestCache requestCache) + AppCaches appCaches) { IOHelper = ioHelper; Configs = configs; + AppCaches = appCaches; UmbracoVersion = umbracoVersion ; Profiler = profiler; HostingEnvironment = hostingEnvironment; @@ -54,8 +54,7 @@ namespace Umbraco.Core.Runtime DbProviderFactoryCreator = dbProviderFactoryCreator; _umbracoBootPermissionChecker = umbracoBootPermissionChecker; - _requestCache = requestCache; - + Logger = logger; MainDom = mainDom; TypeFinder = typeFinder; @@ -95,6 +94,7 @@ namespace Umbraco.Core.Runtime protected IIOHelper IOHelper { get; } protected IHostingEnvironment HostingEnvironment { get; } public Configs Configs { get; } + public AppCaches AppCaches { get; } public IUmbracoVersion UmbracoVersion { get; } /// @@ -161,28 +161,25 @@ namespace Umbraco.Core.Runtime // run handlers OnRuntimeBoot(); - // application caches - var appCaches = CreateAppCaches(); - // database factory var databaseFactory = CreateDatabaseFactory(); // type finder/loader - var typeLoader = new TypeLoader(TypeFinder, appCaches.RuntimeCache, new DirectoryInfo(HostingEnvironment.LocalTempPath), ProfilingLogger); + var typeLoader = new TypeLoader(TypeFinder, AppCaches.RuntimeCache, new DirectoryInfo(HostingEnvironment.LocalTempPath), ProfilingLogger); // re-create the state object with the essential services _state = new RuntimeState(Configs.Global(), UmbracoVersion, databaseFactory, Logger); // create the composition - composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs, IOHelper, appCaches); + composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs, IOHelper, AppCaches); - composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, appCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator, HostingEnvironment, BackOfficeInfo); + composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, AppCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator, HostingEnvironment, BackOfficeInfo); // register ourselves (TODO: Should we put this in RegisterEssentials?) composition.Register(_ => this, Lifetime.Singleton); // run handlers - OnRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory); + OnRuntimeEssentials(composition, AppCaches, typeLoader, databaseFactory); try { @@ -366,21 +363,6 @@ namespace Umbraco.Core.Runtime protected virtual IEnumerable GetComposerTypes(TypeLoader typeLoader) => typeLoader.GetTypes(); - /// - /// Creates the application caches. - /// - protected virtual AppCaches CreateAppCaches() - { - // need the deep clone runtime cache provider to ensure entities are cached properly, ie - // are cloned in and cloned out - no request-based cache here since no web-based context, - // is overridden by the web runtime - - return new AppCaches( - new DeepCloneAppCache(new ObjectCacheAppCache()), - _requestCache, - new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); - } - /// /// Returns the application path of the site/solution /// diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index b41ef4ac02..07a0db167c 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -58,7 +58,7 @@ namespace Umbraco.Tests.Integration var coreRuntime = new CoreRuntime(testHelper.GetConfigs(), testHelper.GetUmbracoVersion(), testHelper.IOHelper, testHelper.Logger, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker, testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator, - testHelper.MainDom, testHelper.GetTypeFinder(), NoAppCache.Instance); + testHelper.MainDom, testHelper.GetTypeFinder(), AppCaches.NoCache); // boot it! var factory = coreRuntime.Configure(umbracoContainer); @@ -101,7 +101,7 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _); + services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), out _); }); var host = await hostBuilder.StartAsync(); @@ -141,7 +141,7 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _); + services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), out _); }); var host = await hostBuilder.StartAsync(); diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index 7c919e3894..ba96c06826 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -26,13 +26,27 @@ namespace Umbraco.Tests.Integration.TestServerTest builder.WebHostEnvironment, container, typeof(UmbracoBuilderExtensions).Assembly, - NoAppCache.Instance, + AppCaches.NoCache, // Disable caches in integration tests testHelper.GetLoggingConfiguration(), // TODO: Yep that's extremely ugly - (a, b, c, d, e, f, g, h, i, j) => - UmbracoIntegrationTest.CreateTestRuntime(a, b, c, d, e, f, g, h, i, j, + (configs, umbVersion, ioHelper, logger, profiler, hostingEnv, backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator) => + { + var runtime = UmbracoIntegrationTest.CreateTestRuntime( + configs, + umbVersion, + ioHelper, + logger, + profiler, + hostingEnv, + backOfficeInfo, + typeFinder, + appCaches, + dbProviderFactoryCreator, testHelper.MainDom, // SimpleMainDom - dbInstallEventHandler), // DB Installation event handler + dbInstallEventHandler); // DB Installation event handler + + return runtime; + }, out _); }); } diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index 145b9d2848..08be22c07b 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -49,8 +49,8 @@ namespace Umbraco.Tests.Integration.TestServerTest }); Client = Factory.CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false + { + AllowAutoRedirect = false }); LinkGenerator = Factory.Services.GetRequiredService(); @@ -62,9 +62,10 @@ namespace Umbraco.Tests.Integration.TestServerTest { var builder = base.CreateHostBuilder(); builder.ConfigureWebHost(builder => - { + { // need to configure the IWebHostEnvironment too - builder.ConfigureServices((c, s) => { + builder.ConfigureServices((c, s) => + { c.HostingEnvironment = TestHelper.GetWebHostEnvironment(); }); @@ -74,8 +75,8 @@ namespace Umbraco.Tests.Integration.TestServerTest Services = app.ApplicationServices; Configure(app); }); - }) - .UseEnvironment(Environments.Development); + }).UseEnvironment(Environments.Development); + return builder; } @@ -140,14 +141,14 @@ namespace Umbraco.Tests.Integration.TestServerTest //.WithMiniProfiler() // we don't want this running in tests .WithMvcAndRazor(mvcBuilding: mvcBuilder => { - mvcBuilder.AddApplicationPart(typeof(ContentController).Assembly); + mvcBuilder.AddApplicationPart(typeof(ContentController).Assembly); }) .WithWebServer() .Build(); } public override void Configure(IApplicationBuilder app) - { + { app.UseUmbraco(); } diff --git a/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs b/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs index 97482f9482..7cf114bfc3 100644 --- a/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs +++ b/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Services; using Umbraco.Core.WebAssets; using Umbraco.Examine; +using Umbraco.Web.Compose; using Umbraco.Web.PublishedCache.NuCache; using Umbraco.Web.Scheduling; using Umbraco.Web.Search; @@ -28,6 +29,7 @@ namespace Umbraco.Tests.Integration.Testing base.Compose(composition); composition.Components().Remove(); + composition.Components().Remove(); composition.RegisterUnique(); composition.RegisterUnique(factory => Mock.Of()); diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index ee03e2a146..c9e88b9deb 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -25,7 +25,6 @@ using Umbraco.Core.Runtime; using Umbraco.Core; using Moq; using System.Collections.Generic; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using System.Data.SqlClient; using System.Data.Common; @@ -52,18 +51,30 @@ namespace Umbraco.Tests.Integration.Testing return umbracoContainer; } - private Action _testTeardown = null; - private Action _fixtureTeardown = null; + private List _testTeardown = null; + private List _fixtureTeardown = new List(); - public void OnTestTearDown(Action tearDown) => _testTeardown = tearDown; + public void OnTestTearDown(Action tearDown) + { + if (_testTeardown == null) + _testTeardown = new List(); + _testTeardown.Add(tearDown); + } - public void OnFixtureTearDown(Action tearDown) => _fixtureTeardown = tearDown; + public void OnFixtureTearDown(Action tearDown) => _fixtureTeardown.Add(tearDown); [OneTimeTearDown] - public void FixtureTearDown() => _fixtureTeardown?.Invoke(); + public void FixtureTearDown() + { + foreach (var a in _fixtureTeardown) a(); + } [TearDown] - public virtual void TearDown() => _testTeardown?.Invoke(); + public virtual void TearDown() + { + foreach (var a in _testTeardown) a(); + _testTeardown = null; + } [SetUp] public virtual async Task Setup() @@ -117,14 +128,14 @@ namespace Umbraco.Tests.Integration.Testing /// /// /// - /// + /// /// /// public CoreRuntime CreateTestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo, - ITypeFinder typeFinder, IRequestCache requestCache, IDbProviderFactoryCreator dbProviderFactoryCreator) + ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator) { - return CreateTestRuntime(configs, + var runtime = CreateTestRuntime(configs, umbracoVersion, ioHelper, logger, @@ -132,11 +143,13 @@ namespace Umbraco.Tests.Integration.Testing hostingEnvironment, backOfficeInfo, typeFinder, - requestCache, + appCaches, dbProviderFactoryCreator, TestHelper.MainDom, // SimpleMainDom UseTestLocalDb // DB Installation event handler - ); + ); + + return runtime; } /// @@ -157,7 +170,7 @@ namespace Umbraco.Tests.Integration.Testing /// public static CoreRuntime CreateTestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo, - ITypeFinder typeFinder, IRequestCache requestCache, IDbProviderFactoryCreator dbProviderFactoryCreator, + ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator, IMainDom mainDom, Action eventHandler) { var runtime = new CoreRuntime( @@ -172,7 +185,7 @@ namespace Umbraco.Tests.Integration.Testing dbProviderFactoryCreator, mainDom, typeFinder, - requestCache); + appCaches); runtime.RuntimeEssentials += (sender, args) => eventHandler(sender, args); @@ -191,7 +204,15 @@ namespace Umbraco.Tests.Integration.Testing // Add it! services.AddUmbracoConfiguration(Configuration); - services.AddUmbracoCore(webHostEnvironment, UmbracoContainer, GetType().Assembly, NoAppCache.Instance, TestHelper.GetLoggingConfiguration(), CreateTestRuntime, out _); + services.AddUmbracoCore( + webHostEnvironment, + UmbracoContainer, + GetType().Assembly, + AppCaches.NoCache, // Disable caches for integration tests + TestHelper.GetLoggingConfiguration(), + CreateTestRuntime, + out _); + services.AddUmbracoWebComponents(); services.AddUmbracoRuntimeMinifier(Configuration); services.AddUmbracoBackOffice(); @@ -225,14 +246,17 @@ namespace Umbraco.Tests.Integration.Testing private static LocalDbTestDatabase _dbInstance; /// - /// Event handler for the to install the database + /// Event handler for the to install the database and register the to Terminate /// - /// + /// /// - protected void UseTestLocalDb(CoreRuntime sender, RuntimeEssentialsEventArgs args) + protected void UseTestLocalDb(CoreRuntime runtime, RuntimeEssentialsEventArgs args) { + // MUST be terminated on teardown + OnTestTearDown(() => runtime.Terminate()); + // This will create a db, install the schema and ensure the app is configured to run - InstallTestLocalDb(args.DatabaseFactory, sender.ProfilingLogger, sender.Configs.Global(), sender.State, TestHelper.WorkingDirectory, out var connectionString); + InstallTestLocalDb(args.DatabaseFactory, runtime.ProfilingLogger, runtime.Configs.Global(), runtime.State, TestHelper.WorkingDirectory, out var connectionString); TestDBConnectionString = connectionString; InMemoryConfiguration["ConnectionStrings:" + Constants.System.UmbracoConnectionName] = TestDBConnectionString; } diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 358a47f09b..9a4531b4e9 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Routing public class TestRuntime : CoreRuntime { public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) - : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), NoAppCache.Instance) + : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), AppCaches.NoCache) { } diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index c338cf8a50..e53e6bfb8a 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -118,7 +118,7 @@ namespace Umbraco.Tests.Runtimes public class TestRuntime : CoreRuntime { public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) - :base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), NoAppCache.Instance) + :base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), AppCaches.NoCache) { } diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs index bf26b2167c..70dfc9ccc6 100644 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs @@ -84,7 +84,7 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo); // create the core runtime and have it compose itself - var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, NoAppCache.Instance); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, AppCaches.NoCache); // determine actual runtime level runtimeState.DetermineRuntimeLevel(); @@ -278,7 +278,7 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo); // create the core runtime and have it compose itself - var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, NoAppCache.Instance); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder, AppCaches.NoCache); // get the components // all of them? diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index f4ae6ed5e5..b5d581afd7 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -146,12 +146,17 @@ namespace Umbraco.Extensions IHttpContextAccessor httpContextAccessor = new HttpContextAccessor(); services.AddSingleton(httpContextAccessor); + var requestCache = new GenericDictionaryRequestAppCache(() => httpContextAccessor.HttpContext?.Items); + var appCaches = new AppCaches( + new DeepCloneAppCache(new ObjectCacheAppCache()), + requestCache, + new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); services.AddUmbracoCore(webHostEnvironment, umbContainer, Assembly.GetEntryAssembly(), - requestCache, + appCaches, loggingConfig, out factory); @@ -165,7 +170,7 @@ namespace Umbraco.Extensions /// /// /// - /// + /// /// /// /// @@ -175,10 +180,11 @@ namespace Umbraco.Extensions IWebHostEnvironment webHostEnvironment, IRegister umbContainer, Assembly entryAssembly, - IRequestCache requestCache, + AppCaches appCaches, ILoggingConfiguration loggingConfiguration, out IFactory factory) - => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, requestCache, loggingConfiguration, GetCoreRuntime, out factory); + => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, appCaches, loggingConfiguration, GetCoreRuntime, out factory); + /// /// Adds the Umbraco Back Core requirements @@ -187,7 +193,7 @@ namespace Umbraco.Extensions /// /// /// - /// + /// /// /// /// Delegate to create an @@ -198,10 +204,10 @@ namespace Umbraco.Extensions IWebHostEnvironment webHostEnvironment, IRegister umbContainer, Assembly entryAssembly, - IRequestCache requestCache, + AppCaches appCaches, ILoggingConfiguration loggingConfiguration, // TODO: Yep that's extremely ugly - Func getRuntime, + Func getRuntime, out IFactory factory) { if (services is null) throw new ArgumentNullException(nameof(services)); @@ -242,7 +248,7 @@ namespace Umbraco.Extensions var typeFinder = CreateTypeFinder(logger, profiler, webHostEnvironment, entryAssembly, configs.TypeFinder()); var runtime = getRuntime( - configs, + configs, umbracoVersion, ioHelper, logger, @@ -250,7 +256,7 @@ namespace Umbraco.Extensions hostingEnvironment, backOfficeInfo, typeFinder, - requestCache, + appCaches, dbProviderFactoryCreator); factory = runtime.Configure(container); @@ -269,7 +275,7 @@ namespace Umbraco.Extensions private static IRuntime GetCoreRuntime( Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, Core.Logging.ILogger logger, IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo, - ITypeFinder typeFinder, IRequestCache requestCache, IDbProviderFactoryCreator dbProviderFactoryCreator) + ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator) { // Determine if we should use the sql main dom or the default @@ -285,7 +291,7 @@ namespace Umbraco.Extensions var mainDom = new MainDom(logger, mainDomLock); var coreRuntime = new CoreRuntime( - configs, + configs, umbracoVersion, ioHelper, logger, @@ -296,7 +302,7 @@ namespace Umbraco.Extensions dbProviderFactoryCreator, mainDom, typeFinder, - requestCache); + appCaches); return coreRuntime; } diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs index 6334f96d4b..2e9ba11866 100644 --- a/src/Umbraco.Web/UmbracoApplication.cs +++ b/src/Umbraco.Web/UmbracoApplication.cs @@ -43,9 +43,14 @@ namespace Umbraco.Web var mainDom = new MainDom(logger, mainDomLock); var requestCache = new HttpRequestAppCache(() => HttpContext.Current != null ? HttpContext.Current.Items : null); + var appCaches = new AppCaches( + new DeepCloneAppCache(new ObjectCacheAppCache()), + requestCache, + new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); + var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker(); return new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, umbracoBootPermissionChecker, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, - GetTypeFinder(hostingEnvironment, logger, profiler), requestCache); + GetTypeFinder(hostingEnvironment, logger, profiler), appCaches); }