From 6a30cd3158cdc46ec2aed034e463894f3c51e77b Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 30 Oct 2020 14:08:05 +0100 Subject: [PATCH 1/2] Changed the test from using IsoCode to IsMandatory, as this is not important to the test, but changing IsoCode leads PublishedSnapshotService to rebuild its caches Signed-off-by: Bjarke Berg --- .../Scoping/ScopedRepositoryTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs index 6dd0d58a75..2976aca085 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs @@ -127,7 +127,6 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping Assert.AreEqual(complete ? "changed" : "name", globalCached.Name); } - [Explicit("Current having issues if RuntimeTests.cs is running in same session")] [TestCase(true)] [TestCase(false)] public void FullDataSetRepositoryCachePolicy(bool complete) @@ -166,7 +165,8 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping var scopedCache = scope.IsolatedCaches.GetOrCreate(typeof (ILanguage)); Assert.AreNotSame(globalCache, scopedCache); - lang.IsoCode = "de-DE"; + //Use IsMandatory of isocode to ensure publishedContent cache is not also rebuild + lang.IsMandatory = true; service.Save(lang); // scoped cache has been flushed, reload @@ -180,7 +180,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping var scopeCached = scopeFullCached.First(x => x.Id == lang.Id); Assert.IsNotNull(scopeCached); Assert.AreEqual(lang.Id, scopeCached.Id); - Assert.AreEqual("de-DE", scopeCached.IsoCode); + Assert.AreEqual(true, scopeCached.IsMandatory); // global cache is unchanged globalFullCached = (IEnumerable) globalCache.Get(GetCacheTypeKey(), () => null); @@ -188,7 +188,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping globalCached = globalFullCached.First(x => x.Id == lang.Id); Assert.IsNotNull(globalCached); Assert.AreEqual(lang.Id, globalCached.Id); - Assert.AreEqual("fr-FR", globalCached.IsoCode); + Assert.AreEqual(false, globalCached.IsMandatory); if (complete) scope.Complete(); @@ -209,7 +209,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping // get again, updated if completed lang = service.GetLanguageById(lang.Id); - Assert.AreEqual(complete ? "de-DE" : "fr-FR", lang.IsoCode); + Assert.AreEqual(complete ? true : false, lang.IsMandatory); // global cache contains the entity again globalFullCached = (IEnumerable) globalCache.Get(GetCacheTypeKey(), () => null); @@ -217,7 +217,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Scoping globalCached = globalFullCached.First(x => x.Id == lang.Id); Assert.IsNotNull(globalCached); Assert.AreEqual(lang.Id, globalCached.Id); - Assert.AreEqual(complete ? "de-DE" : "fr-FR", lang.IsoCode); + Assert.AreEqual(complete ? true : false, lang.IsMandatory); } [TestCase(true)] From 98b1798bbe7ed1a15e5177bd136e6d43f877d1ab Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Fri, 30 Oct 2020 19:56:26 +0100 Subject: [PATCH 2/2] Fixes issue with introduced MSDI abstractions where a single implemention is used for two interfaces, ensuring only one singleton instance is created. --- src/Umbraco.Core/ServiceCollectionExtensions.cs | 15 +++++++++++++++ .../Runtime/AspNetCoreComposer.cs | 7 ++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/ServiceCollectionExtensions.cs b/src/Umbraco.Core/ServiceCollectionExtensions.cs index 3202cc3a38..e6fcd43af1 100644 --- a/src/Umbraco.Core/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Core/ServiceCollectionExtensions.cs @@ -12,6 +12,21 @@ namespace Umbraco.Core where TImplementing : class, TService => services.Replace(ServiceDescriptor.Singleton()); + /// + /// Registers a unique service as a single instance implementing two interfaces. + /// + /// + /// Hat-tip: https://stackoverflow.com/a/55402016/489433 + /// + public static void AddUnique(this IServiceCollection services) + where TService1 : class + where TService2 : class + where TImplementing : class, TService1, TService2 + { + services.Replace(ServiceDescriptor.Singleton()); + services.Replace(ServiceDescriptor.Singleton(x => (TImplementing)x.GetService())); + } + public static void AddUnique(this IServiceCollection services) where TImplementing : class => services.Replace(ServiceDescriptor.Singleton()); diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index 39742dcb0d..832cfdb488 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -55,13 +55,11 @@ namespace Umbraco.Web.Common.Runtime composition.Services.AddUnique(); // The umbraco request lifetime - composition.Services.AddUnique(); - composition.Services.AddUnique(); + composition.Services.AddUnique(); - //Password hasher + // Password hasher composition.Services.AddUnique(); - composition.Services.AddUnique(); composition.Services.AddTransient(); composition.Services.AddUnique(); @@ -76,7 +74,6 @@ namespace Umbraco.Web.Common.Runtime composition.Services.AddUnique(); composition.Services.AddUnique(); - // register the umbraco context factory composition.Services.AddUnique(); composition.Services.AddUnique();