From d2376bf4e387ea1f3be14c64fe6565a3f109c4f6 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 23 Jul 2018 08:56:08 +0200 Subject: [PATCH] Cleanup registrations --- src/Umbraco.Core/Components/BootLoader.cs | 2 +- .../Composers/FileSystemsComposer.cs | 9 ++-- .../Composing/ContainerExtensions.cs | 2 +- src/Umbraco.Core/Composing/IContainer.cs | 36 +++++++++++--- .../LightInject/LightInjectContainer.cs | 49 ++++++++++++++----- src/Umbraco.Core/IO/FileSystems.cs | 2 +- .../Migrations/MigrationBuilder.cs | 17 +------ src/Umbraco.Tests/CoreThings/UdiTests.cs | 1 - .../Integration/ContentEventsTests.cs | 4 -- .../Membership/MembershipProviderBaseTests.cs | 8 --- .../Misc/ApplicationUrlHelperTests.cs | 21 +++----- .../DataTypeDefinitionRepositoryTest.cs | 1 - .../PublishedContent/PublishedMediaTests.cs | 3 -- .../Scoping/ScopeFileSystemsTests.cs | 12 ++++- .../Scoping/ScopedNuCacheTests.cs | 2 - .../Scoping/ScopedRepositoryTests.cs | 2 - src/Umbraco.Tests/Scoping/ScopedXmlTests.cs | 2 - .../Services/Importing/PackageImportTests.cs | 11 +++++ .../TestHelpers/TestWithDatabaseBase.cs | 2 - 19 files changed, 102 insertions(+), 84 deletions(-) diff --git a/src/Umbraco.Core/Components/BootLoader.cs b/src/Umbraco.Core/Components/BootLoader.cs index b80fa93500..70e62c799f 100644 --- a/src/Umbraco.Core/Components/BootLoader.cs +++ b/src/Umbraco.Core/Components/BootLoader.cs @@ -313,7 +313,7 @@ namespace Umbraco.Core.Components { var componentType = component.GetType(); var initializers = componentType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .Where(x => x.Name == "Initialize" && x.IsGenericMethod == false); + .Where(x => x.Name == "Initialize" && x.IsGenericMethod == false && x.IsStatic == false); using (_proflog.DebugDuration($"Initializing {componentType.FullName}.", $"Initialised {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds)) { foreach (var initializer in initializers) diff --git a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs index 565db9c623..cb8466bd13 100644 --- a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs +++ b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Configuration.UmbracoSettings; +using System.Linq; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -15,11 +16,7 @@ namespace Umbraco.Core.Composing.Composers container.RegisterSingleton(factory => factory.GetInstance()); // register MediaFileSystem, which can be injected directly - container.RegisterSingleton(factory => factory.GetInstance().MediaFileSystem); - - // register MediaFileSystem, so that FileSystems can create it - container.Register((f, wrappedFileSystem) - => new MediaFileSystem(wrappedFileSystem, f.GetInstance(), f.GetInstance(), f.GetInstance())); + container.Register/*Singleton*/(factory => factory.GetInstance().MediaFileSystem); return container; } diff --git a/src/Umbraco.Core/Composing/ContainerExtensions.cs b/src/Umbraco.Core/Composing/ContainerExtensions.cs index e51fc07aa4..db040393bc 100644 --- a/src/Umbraco.Core/Composing/ContainerExtensions.cs +++ b/src/Umbraco.Core/Composing/ContainerExtensions.cs @@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing /// Throws an exception if the container failed to get an instance of the specified type. /// The arguments are used as dependencies by the container. /// - public static T GetInstance(this IContainer container, object[] args) + public static T GetInstance(this IContainer container, params object[] args) => (T) container.GetInstance(typeof(T), args); /// diff --git a/src/Umbraco.Core/Composing/IContainer.cs b/src/Umbraco.Core/Composing/IContainer.cs index 9d77a9b379..2be539551e 100644 --- a/src/Umbraco.Core/Composing/IContainer.cs +++ b/src/Umbraco.Core/Composing/IContainer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Reflection; namespace Umbraco.Core.Composing { @@ -43,7 +42,10 @@ namespace Umbraco.Core.Composing /// Throws an exception if the container failed to get an instance of the specified type. /// The arguments are used as dependencies by the container. /// - object GetInstance(Type type, object[] args); + // fixme - some restrictions: + // method is not optimized, .Invoke-ing the ctor, no compiled dynamic method + // uses the ctor with most args, always, not trying to figure out which one to use + object GetInstance(Type type, params object[] args); /// /// Tries to get an instance. @@ -67,13 +69,23 @@ namespace Umbraco.Core.Composing /// The type of the service. IEnumerable GetAllInstances(); - // fixme + /// + /// Gets registration for a service. + /// + /// The type of the service. + /// The registrations for the service. IEnumerable GetRegistered(Type serviceType); #endregion #region Registry + // notes + // when implementing IContainer, the following rules apply + // - it is possible to register a service, even after some instances of other services have been created + // - it is possible to re-register a service, as long as an instance of that service has not been created + // - once an instance of a service has been created, it is not possible to change its registration + /// /// Registers a service as its own implementation. /// @@ -107,6 +119,13 @@ namespace Umbraco.Core.Composing /// /// Registers a base type for auto-registration. /// + /// + /// Auto-registration means that anytime the container is asked to create an instance + /// of a type deriving from , it will first register that + /// type automatically. + /// This can be used for instance for views or controllers. Then, one just needs to + /// register a common base class or interface, and the container knows how to create instances. + /// void RegisterAuto(Type serviceBaseType); /// @@ -114,11 +133,6 @@ namespace Umbraco.Core.Composing /// void RegisterOrdered(Type serviceType, Type[] implementingTypes, Lifetime lifetime = Lifetime.Transient); - // fixme - very LightInject specific? or? - // beware! does NOT work on singletons, see https://github.com/seesharper/LightInject/issues/294 - void RegisterConstructorDependency(Func factory); - void RegisterConstructorDependency(Func factory); - #endregion #region Control @@ -134,6 +148,12 @@ namespace Umbraco.Core.Composing // fixme - document all these + /// + /// Configures the container for Umbraco. + /// + /// + /// + /// IContainer ConfigureForUmbraco(); IContainer ConfigureForWeb(); diff --git a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs index 8d8197f10c..6e4b08eaed 100644 --- a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs +++ b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs @@ -62,8 +62,26 @@ namespace Umbraco.Core.Composing.LightInject => Container.GetInstance(type, name); /// - public object GetInstance(Type type, object[] args) - => Container.GetInstance(type, args); + public object GetInstance(Type type, params object[] args) + { + // LightInject has this, but then it requires RegisterConstructorDependency etc and has various oddities + //return Container.GetInstance(type, args); + + var ctor = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public).OrderByDescending(x => x.GetParameters().Length).FirstOrDefault(); + if (ctor == null) throw new InvalidOperationException($"Could not find a public constructor for type {type.FullName}."); + + var ctorParameters = ctor.GetParameters(); + var ctorArgs = new object[ctorParameters.Length]; + var i = 0; + foreach (var parameter in ctorParameters) + { + // no! IsInstanceOfType is not ok here + // ReSharper disable once UseMethodIsInstanceOfType + var arg = args?.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType())); + ctorArgs[i++] = arg ?? GetInstance(parameter.ParameterType); + } + return ctor.Invoke(ctorArgs); + } /// public object TryGetInstance(Type type) @@ -198,13 +216,16 @@ namespace Umbraco.Core.Composing.LightInject public void RegisterOrdered(Type serviceType, Type[] implementingTypes, Lifetime lifetime = Lifetime.Transient) => Container.RegisterOrdered(serviceType, implementingTypes, _ => GetLifetime(lifetime)); - /// - public void RegisterConstructorDependency(Func factory) - => Container.RegisterConstructorDependency((f, x) => factory(this, x)); - - /// - public void RegisterConstructorDependency(Func factory) - => Container.RegisterConstructorDependency((f, x, a) => factory(this, x, a)); + // was the Light-Inject specific way of dealing with args, but we've replaced it with our own + // beware! does NOT work on singletons, see https://github.com/seesharper/LightInject/issues/294 + // + ///// + //public void RegisterConstructorDependency(Func factory) + // => Container.RegisterConstructorDependency((f, x) => factory(this, x)); + // + ///// + //public void RegisterConstructorDependency(Func factory) + // => Container.RegisterConstructorDependency((f, x, a) => factory(this, x, a)); #endregion @@ -251,9 +272,13 @@ namespace Umbraco.Core.Composing.LightInject // if looking for a IContainer, and one was passed in args, use it // this is for collection builders which require the IContainer //Container.RegisterConstructorDependency((c, i, a) => a.OfType().FirstOrDefault()); - - // which means that the only way to inject the container into builders is to register it - Container.RegisterInstance(this); + // + // and, the block below is also disabled, because it is ugly + // + //// which means that the only way to inject the container into builders is to register it + //Container.RegisterInstance(this); + // + // instead, we use an explicit GetInstance with arguments implementation return this; } diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index ab7f75a521..e9114d5310 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -299,7 +299,7 @@ namespace Umbraco.Core.IO var shadowWrapper = new ShadowWrapper(innerFs, "typed/" + alias, () => IsScoped()); // getting the fs from the container - see FileSystemsComposer - var fs = Current.Container.GetInstance(new object[] { (IFileSystem) shadowWrapper }); + var fs = Current.Container.GetInstance((IFileSystem) shadowWrapper); _wrappers.Add(shadowWrapper); // keeping a reference to the wrapper return fs; }); diff --git a/src/Umbraco.Core/Migrations/MigrationBuilder.cs b/src/Umbraco.Core/Migrations/MigrationBuilder.cs index c4a06f4789..fa22c96595 100644 --- a/src/Umbraco.Core/Migrations/MigrationBuilder.cs +++ b/src/Umbraco.Core/Migrations/MigrationBuilder.cs @@ -10,27 +10,12 @@ namespace Umbraco.Core.Migrations public MigrationBuilder(IContainer container) { _container = container; - - // because the builder should be "per container" this ctor should run only once per container. - // - // note: constructor dependencies do NOT work with lifetimes other than transient - // see https://github.com/seesharper/LightInject/issues/294 - // - // resolve ctor dependency from GetInstance() runtimeArguments, if possible - 'factory' is - // the container, 'info' describes the ctor argument, and 'args' contains the args that - // were passed to GetInstance() - use first arg if it is the right type. - // - // for IMigrationContext - container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IMigrationContext : null); } public IMigration Build(Type migrationType, IMigrationContext context) { - // LightInject .Create() is a shortcut for .Register() + .GetInstance() - // but it does not support parameters, so we do it ourselves here - _container.Register(migrationType); - return (IMigration) _container.GetInstance(migrationType, new object[] { context }); + return (IMigration) _container.GetInstance(migrationType, context); } } } diff --git a/src/Umbraco.Tests/CoreThings/UdiTests.cs b/src/Umbraco.Tests/CoreThings/UdiTests.cs index 12ce3227e1..77f3b10a2f 100644 --- a/src/Umbraco.Tests/CoreThings/UdiTests.cs +++ b/src/Umbraco.Tests/CoreThings/UdiTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using LightInject; using Moq; using Newtonsoft.Json; using NUnit.Framework; diff --git a/src/Umbraco.Tests/Integration/ContentEventsTests.cs b/src/Umbraco.Tests/Integration/ContentEventsTests.cs index 4356d3733f..6075ab3371 100644 --- a/src/Umbraco.Tests/Integration/ContentEventsTests.cs +++ b/src/Umbraco.Tests/Integration/ContentEventsTests.cs @@ -1,20 +1,16 @@ using System; using System.Collections.Generic; using System.Linq; -using LightInject; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Sync; -using Umbraco.Tests.Cache.DistributedCache; using Umbraco.Tests.Services; using Umbraco.Tests.TestHelpers.Entities; -using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; using Umbraco.Web.Cache; using static Umbraco.Tests.Cache.DistributedCache.DistributedCacheTests; diff --git a/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs b/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs index 2a5b76e1bd..f1f46133c3 100644 --- a/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs +++ b/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs @@ -3,17 +3,9 @@ using System.Collections.Specialized; using System.Configuration.Provider; using System.Security.Cryptography; using System.Web.Security; -using LightInject; using Moq; using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; -using Umbraco.Core.Scoping; using Umbraco.Core.Security; -using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; namespace Umbraco.Tests.Membership diff --git a/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs b/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs index 9c0560351b..ae72d996a8 100644 --- a/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs +++ b/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs @@ -1,7 +1,4 @@ using System; -using System.Configuration; -using System.Linq; -using LightInject; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -11,8 +8,6 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Sync; using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.Cache.DistributedCache; -using Umbraco.Tests.TestHelpers.Stubs; namespace Umbraco.Tests.Misc @@ -75,7 +70,7 @@ namespace Umbraco.Tests.Misc ApplicationUrlHelper.ApplicationUrlProvider = request => "http://server1.com/umbraco"; - + var state = new RuntimeState(Mock.Of(), new Lazy(Mock.Of), new Lazy(Mock.Of), settings, globalConfig.Object); @@ -101,7 +96,7 @@ namespace Umbraco.Tests.Misc // still NOT set Assert.IsNull(url); } - + [Test] public void SetApplicationUrlFromStSettingsNoSsl() { @@ -112,8 +107,8 @@ namespace Umbraco.Tests.Misc var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); globalConfig.Setup(x => x.UseHttps).Returns(false); - - + + var url = ApplicationUrlHelper.TryGetApplicationUrl(settings, Mock.Of(), globalConfig.Object, Mock.Of()); Assert.AreEqual("http://mycoolhost.com/umbraco", url); @@ -129,8 +124,8 @@ namespace Umbraco.Tests.Misc var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); globalConfig.Setup(x => x.UseHttps).Returns(true); - - + + var url = ApplicationUrlHelper.TryGetApplicationUrl(settings, Mock.Of(), globalConfig.Object, Mock.Of()); Assert.AreEqual("https://mycoolhost.com/umbraco", url); @@ -146,13 +141,13 @@ namespace Umbraco.Tests.Misc var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); globalConfig.Setup(x => x.UseHttps).Returns(true); - + var url = ApplicationUrlHelper.TryGetApplicationUrl(settings, Mock.Of(), globalConfig.Object, Mock.Of()); Assert.AreEqual("httpx://whatever.com/umbraco", url); } - + } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index 8b3af9838c..f9b8281285 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -6,7 +6,6 @@ using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; -using LightInject; using Umbraco.Core.Composing; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 5f0831bfc6..e9d133c901 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -1,7 +1,6 @@ using System.Web; using System.Xml.Linq; using System.Xml.XPath; -using Lucene.Net.Store; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; @@ -20,10 +19,8 @@ using Umbraco.Core.Strings; using Umbraco.Examine; using Current = Umbraco.Web.Composing.Current; using Umbraco.Tests.Testing; -using LightInject; using Umbraco.Core.Composing; using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; namespace Umbraco.Tests.PublishedContent { diff --git a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs index ae16ba484f..f095e30553 100644 --- a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs @@ -4,8 +4,8 @@ using System.Text; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; using Umbraco.Core.IO; -using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; @@ -23,6 +23,16 @@ namespace Umbraco.Tests.Scoping ClearFiles(); } + protected override void ComposeApplication(bool withApplication) + { + base.ComposeApplication(withApplication); + + if (!withApplication) return; + + // re-register with actual media fs + Container.ComposeFileSystems(); + } + public override void TearDown() { base.TearDown(); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index cf3285cd7e..9308e9bbaf 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Web.Routing; -using LightInject; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -14,7 +13,6 @@ using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence.Repositories; -using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; diff --git a/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs index 875eabb13c..4f6fafbbbf 100644 --- a/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; -using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Models; @@ -11,7 +10,6 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; using Umbraco.Web.Cache; -using LightInject; using Moq; using Umbraco.Core.Events; using Umbraco.Core.Sync; diff --git a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs index 948b0f6378..65bc5762c7 100644 --- a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Xml; using Moq; using NUnit.Framework; -using LightInject; -using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Events; diff --git a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs index d925caa23f..002306fdc2 100644 --- a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs +++ b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; @@ -53,6 +54,16 @@ namespace Umbraco.Tests.Services.Importing .Add(); } + protected override void ComposeApplication(bool withApplication) + { + base.ComposeApplication(withApplication); + + if (!withApplication) return; + + // re-register with actual media fs + Container.ComposeFileSystems(); + } + [Test] public void PackagingService_Can_Import_uBlogsy_ContentTypes_And_Verify_Structure() { diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 38cd8f727d..00457d510d 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -26,9 +26,7 @@ using File = System.IO.File; using Umbraco.Core.Composing; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; -using LightInject; using Umbraco.Core.Migrations.Install; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence.Repositories;