diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs index ecc74ec61f..a6db0b7b2b 100644 --- a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs +++ b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs @@ -91,7 +91,7 @@ namespace Umbraco.Core.Composing.LightInject /// /// Gets the LightInject container. /// - protected ServiceContainer Container { get; } + public ServiceContainer Container { get; } /// /// diff --git a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs b/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs index 1bf3b8187f..9794de733a 100644 --- a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs +++ b/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs @@ -20,9 +20,9 @@ namespace Umbraco.Core.Composing /// public static IRegister CreateFrom(IServiceCollection services, out IServiceProvider serviceProvider) { - var liContainer = new ServiceContainer(ContainerOptions.Default.WithMicrosoftSettings()); - serviceProvider = liContainer.CreateServiceProvider(services); - return new LightInjectContainer(liContainer); + var lightInjectContainer = new ServiceContainer(ContainerOptions.Default.WithMicrosoftSettings()); + serviceProvider = lightInjectContainer.CreateServiceProvider(services); + return new LightInjectContainer(lightInjectContainer); } //TODO: The following can die when net framework is gone diff --git a/src/Umbraco.Tests.Common/Assertions.cs b/src/Umbraco.Tests.Common/Assertions.cs new file mode 100644 index 0000000000..0f99a6a091 --- /dev/null +++ b/src/Umbraco.Tests.Common/Assertions.cs @@ -0,0 +1,35 @@ +using LightInject; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Umbraco.Tests.Common.Composing; + +namespace Umbraco.Tests.Common +{ + public class Assertions + { + public static void AssertContainer(ServiceContainer container, bool reportOnly = false) + { + var results = container.Validate().ToList(); + foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) + { + Console.WriteLine($"{resultGroup.Key}: {resultGroup.Count()}"); + } + + foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) + { + foreach (var result in resultGroup) + { + Console.WriteLine(); + Console.Write(result.ToText()); + } + } + + if (!reportOnly) + Assert.AreEqual(0, results.Count); + } + + } +} diff --git a/src/Umbraco.Tests/Composing/LightInjectValidation.cs b/src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs similarity index 92% rename from src/Umbraco.Tests/Composing/LightInjectValidation.cs rename to src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs index 75062e613c..4925074b9e 100644 --- a/src/Umbraco.Tests/Composing/LightInjectValidation.cs +++ b/src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs @@ -35,7 +35,7 @@ using ServiceMap = System.Collections.Generic.Dictionary 1; } } diff --git a/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs b/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs new file mode 100644 index 0000000000..10f27418ea --- /dev/null +++ b/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs @@ -0,0 +1,106 @@ +using System; +using System.Text; +using Umbraco.Core; + +namespace Umbraco.Tests.Common.Composing +{ + public static class ValidationResultExtensions + { + public static string ToText(this ValidationResult result) + { + var text = new StringBuilder(); + + text.AppendLine($"{result.Severity}: {WordWrap(result.Message, 120)}"); + var target = result.ValidationTarget; + text.Append("\tsvce: "); + text.Append(target.ServiceName); + text.Append(target.DeclaringService.ServiceType); + if (!target.DeclaringService.ServiceName.IsNullOrWhiteSpace()) + { + text.Append(" '"); + text.Append(target.DeclaringService.ServiceName); + text.Append("'"); + } + + text.Append(" ("); + if (target.DeclaringService.Lifetime == null) + text.Append("Transient"); + else + text.Append(target.DeclaringService.Lifetime.ToString().TrimStart("LightInject.").TrimEnd("Lifetime")); + text.AppendLine(")"); + text.Append("\timpl: "); + text.Append(target.DeclaringService.ImplementingType); + text.AppendLine(); + text.Append("\tparm: "); + text.Append(target.Parameter); + text.AppendLine(); + + return text.ToString(); + } + + private static string WordWrap(string text, int width) + { + int pos, next; + var sb = new StringBuilder(); + var nl = Environment.NewLine; + + // Lucidity check + if (width < 1) + return text; + + // Parse each line of text + for (pos = 0; pos < text.Length; pos = next) + { + // Find end of line + var eol = text.IndexOf(nl, pos, StringComparison.Ordinal); + + if (eol == -1) + next = eol = text.Length; + else + next = eol + nl.Length; + + // Copy this line of text, breaking into smaller lines as needed + if (eol > pos) + { + do + { + var len = eol - pos; + + if (len > width) + len = BreakLine(text, pos, width); + + if (pos > 0) + sb.Append("\t\t"); + sb.Append(text, pos, len); + sb.Append(nl); + + // Trim whitespace following break + pos += len; + + while (pos < eol && char.IsWhiteSpace(text[pos])) + pos++; + + } while (eol > pos); + } + else sb.Append(nl); // Empty line + } + + return sb.ToString(); + } + + private static int BreakLine(string text, int pos, int max) + { + // Find last whitespace in line + var i = max - 1; + while (i >= 0 && !char.IsWhiteSpace(text[pos + i])) + i--; + if (i < 0) + return max; // No whitespace found; break at maximum length + // Find start of whitespace + while (i >= 0 && char.IsWhiteSpace(text[pos + i])) + i--; + // Return length of text before whitespace + return i + 1; + } + } +} diff --git a/src/Umbraco.Tests.Integration/ContainerTests.cs b/src/Umbraco.Tests.Integration/ContainerTests.cs index 336c8007d5..b231e6def0 100644 --- a/src/Umbraco.Tests.Integration/ContainerTests.cs +++ b/src/Umbraco.Tests.Integration/ContainerTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Composing.LightInject; using Umbraco.Core.Configuration; using Umbraco.Core.Persistence; +using Umbraco.Tests.Common; using Umbraco.Tests.Integration.Implementations; namespace Umbraco.Tests.Integration @@ -56,6 +57,8 @@ namespace Umbraco.Tests.Integration Assert.AreNotSame(foo1, foo2); // These are the same because the umbraco container wraps the light inject container Assert.AreSame(foo2, foo3); + + Assertions.AssertContainer(umbracoContainer.Container); } private class Foo diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 2823761afd..871520d1c6 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -1,10 +1,14 @@ using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; +using System; using System.Linq; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Composing.LightInject; using Umbraco.Core.Configuration; using Umbraco.Core.Runtime; +using Umbraco.Tests.Common; +using Umbraco.Tests.Common.Composing; using Umbraco.Tests.Integration.Implementations; namespace Umbraco.Tests.Integration @@ -19,7 +23,7 @@ namespace Umbraco.Tests.Integration var services = new ServiceCollection(); // LightInject / Umbraco - var umbracoContainer = RegisterFactory.CreateFrom(services, out var lightInjectServiceProvider); + var umbracoContainer = (LightInjectContainer)RegisterFactory.CreateFrom(services, out var lightInjectServiceProvider); // Dependencies needed for Core Runtime var testHelper = new TestHelper(); @@ -35,17 +39,21 @@ namespace Umbraco.Tests.Integration Assert.IsNull(coreRuntime.State.BootFailedException); Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level); Assert.IsTrue(MyComposer.IsComposed); - } - } - [RuntimeLevel(MinLevel = RuntimeLevel.Install)] - public class MyComposer : IUserComposer - { - public void Compose(Composition composition) - { - IsComposed = true; + Assertions.AssertContainer(umbracoContainer.Container, reportOnly: true); // TODO Change that to false eventually when we clean up the container } - public static bool IsComposed { get; private set; } + [RuntimeLevel(MinLevel = RuntimeLevel.Install)] + public class MyComposer : IUserComposer + { + public void Compose(Composition composition) + { + IsComposed = true; + } + + public static bool IsComposed { get; private set; } + } } + + } diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs index a0486218e4..d261afc0da 100644 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs @@ -25,7 +25,6 @@ using Umbraco.Core.Runtime; using Umbraco.Core.Scoping; using Umbraco.Core.Services; using Umbraco.Core.Sync; -using Umbraco.Tests.Composing; using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.Cache; @@ -36,6 +35,7 @@ using Umbraco.Web.Runtime; using File = System.IO.File; using Current = Umbraco.Web.Composing.Current; using Umbraco.Tests.Common; +using Umbraco.Tests.Common.Composing; namespace Umbraco.Tests.Runtimes { @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Runtimes var profilingLogger = new ProfilingLogger(logger, profiler); var appCaches = AppCaches.Disabled; var databaseFactory = new UmbracoDatabaseFactory(logger, new Lazy(() => factory.GetInstance()), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator); - var typeFinder = new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(GetType().Assembly)); + var typeFinder = TestHelper.GetTypeFinder(); var ioHelper = TestHelper.IOHelper; var hostingEnvironment = Mock.Of(); var typeLoader = new TypeLoader(ioHelper, typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), profilingLogger); @@ -73,6 +73,7 @@ namespace Umbraco.Tests.Runtimes var runtimeState = new RuntimeState(logger, null, new Lazy(() => mainDom), new Lazy(() => factory.GetInstance()), umbracoVersion, hostingEnvironment, backOfficeInfo); var configs = TestHelper.GetConfigs(); var variationContextAccessor = TestHelper.VariationContextAccessor; + // create the register and the composition var register = TestHelper.GetRegister(); @@ -80,7 +81,8 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator); // 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);coreRuntime.Compose(composition); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder); + coreRuntime.Compose(composition); // determine actual runtime level runtimeState.DetermineRuntimeLevel(databaseFactory, logger); @@ -274,7 +276,7 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator); // 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); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder); coreRuntime.Compose(composition); // get the components @@ -313,107 +315,14 @@ namespace Umbraco.Tests.Runtimes foreach (var result in resultGroup) { Console.WriteLine(); - Console.Write(ToText(result)); + Console.Write(result.ToText()); } Assert.AreEqual(0, results.Count); } - private static string ToText(ValidationResult result) - { - var text = new StringBuilder(); + - text.AppendLine($"{result.Severity}: {WordWrap(result.Message, 120)}"); - var target = result.ValidationTarget; - text.Append("\tsvce: "); - text.Append(target.ServiceName); - text.Append(target.DeclaringService.ServiceType); - if (!target.DeclaringService.ServiceName.IsNullOrWhiteSpace()) - { - text.Append(" '"); - text.Append(target.DeclaringService.ServiceName); - text.Append("'"); - } - - text.Append(" ("); - if (target.DeclaringService.Lifetime == null) - text.Append("Transient"); - else - text.Append(target.DeclaringService.Lifetime.ToString().TrimStart("LightInject.").TrimEnd("Lifetime")); - text.AppendLine(")"); - text.Append("\timpl: "); - text.Append(target.DeclaringService.ImplementingType); - text.AppendLine(); - text.Append("\tparm: "); - text.Append(target.Parameter); - text.AppendLine(); - - return text.ToString(); - } - - private static string WordWrap(string text, int width) - { - int pos, next; - var sb = new StringBuilder(); - var nl = Environment.NewLine; - - // Lucidity check - if (width < 1) - return text; - - // Parse each line of text - for (pos = 0; pos < text.Length; pos = next) - { - // Find end of line - var eol = text.IndexOf(nl, pos, StringComparison.Ordinal); - - if (eol == -1) - next = eol = text.Length; - else - next = eol + nl.Length; - - // Copy this line of text, breaking into smaller lines as needed - if (eol > pos) - { - do - { - var len = eol - pos; - - if (len > width) - len = BreakLine(text, pos, width); - - if (pos > 0) - sb.Append("\t\t"); - sb.Append(text, pos, len); - sb.Append(nl); - - // Trim whitespace following break - pos += len; - - while (pos < eol && char.IsWhiteSpace(text[pos])) - pos++; - - } while (eol > pos); - } - else sb.Append(nl); // Empty line - } - - return sb.ToString(); - } - - private static int BreakLine(string text, int pos, int max) - { - // Find last whitespace in line - var i = max - 1; - while (i >= 0 && !char.IsWhiteSpace(text[pos + i])) - i--; - if (i < 0) - return max; // No whitespace found; break at maximum length - // Find start of whitespace - while (i >= 0 && char.IsWhiteSpace(text[pos + i])) - i--; - // Return length of text before whitespace - return i + 1; - } + } } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index ca150c7c5e..12d3ae111c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -120,7 +120,6 @@ -