diff --git a/src/Umbraco.Core/DI/CollectionBuilderBase.cs b/src/Umbraco.Core/DI/CollectionBuilderBase.cs index 3a0e3124d4..23ddda9509 100644 --- a/src/Umbraco.Core/DI/CollectionBuilderBase.cs +++ b/src/Umbraco.Core/DI/CollectionBuilderBase.cs @@ -60,6 +60,11 @@ namespace Umbraco.Core.DI var expr = Expression.Lambda, TCollection>>(exprNew, exprArg); _collectionCtor = expr.Compile(); + // we just don't want to support re-registering collections here + var registration = Container.GetAvailableService(); + if (registration != null) + throw new InvalidOperationException("Collection builders cannot be registered once the collection itself has been registered."); + // register the collection Container.Register(_ => CreateCollection(), CollectionLifetime); } diff --git a/src/Umbraco.Core/DI/LightInjectExtensions.cs b/src/Umbraco.Core/DI/LightInjectExtensions.cs index b6d3cda1a4..c7676b02cb 100644 --- a/src/Umbraco.Core/DI/LightInjectExtensions.cs +++ b/src/Umbraco.Core/DI/LightInjectExtensions.cs @@ -277,6 +277,12 @@ namespace Umbraco.Core.DI public static TBuilder RegisterCollectionBuilder(this IServiceContainer container) { + // make sure it's not already registered + // we just don't want to support re-registering collection builders + var registration = container.GetAvailableService(); + if (registration != null) + throw new InvalidOperationException("Collection builders should be registered only once."); + // register the builder - per container var builderLifetime = new PerContainerLifetime(); container.Register(builderLifetime); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index e60d1ce99d..7eba6798a5 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -24,7 +24,8 @@ namespace Umbraco.Tests.Cache.PublishedCache { base.Compose(); - Container.RegisterCollectionBuilder() + Container.GetInstance() + .Clear() .Append(); } diff --git a/src/Umbraco.Tests/Models/Mapping/AutoMapperTests.cs b/src/Umbraco.Tests/Models/Mapping/AutoMapperTests.cs index 1704a99229..28d4dcdbf6 100644 --- a/src/Umbraco.Tests/Models/Mapping/AutoMapperTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/AutoMapperTests.cs @@ -28,7 +28,8 @@ namespace Umbraco.Tests.Models.Mapping Container.Register(_ => manifestBuilder); Func> typeListProducerList = Enumerable.Empty; - Container.RegisterCollectionBuilder() + Container.GetInstance() + .Clear() .Add(typeListProducerList); } diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index b9de2d1010..1ebae82e2c 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -13,6 +13,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web.Models.ContentEditing; using Umbraco.Core.DI; +using Umbraco.Core.Plugins; using Current = Umbraco.Web.Current; namespace Umbraco.Tests.Models.Mapping @@ -25,9 +26,6 @@ namespace Umbraco.Tests.Models.Mapping { base.Compose(); - //Container.RegisterSingleton(f => new PropertyEditorCollection(new[] { new TestPropertyEditor(f.GetInstance()) })); - //Container.RegisterCollectionBuilder() - // .Add(f => f.GetInstance().ResolvePropertyEditors()); Container.RegisterSingleton(f => Mock.Of()); } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 781a5acbc7..d7fa85014f 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -46,7 +46,7 @@ namespace Umbraco.Tests.PublishedContent protected override void Compose() { - Container.RegisterCollectionBuilder(); + base.Compose(); Container.RegisterSingleton(f => new PublishedContentModelFactory(f.GetInstance().ResolveTypes())); } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index a64e7a3fab..2f24e08f48 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -36,7 +36,8 @@ namespace Umbraco.Tests.PublishedContent { base.Compose(); - Container.RegisterCollectionBuilder() + Container.GetInstance() + .Clear() .Append(); } diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 1ab7d2c5f5..77700b11ab 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -40,7 +40,6 @@ namespace Umbraco.Tests.Services base.Compose(); // fixme - do it differently - Container.RegisterCollectionBuilder(); Container.Register(factory => factory.GetInstance().TextService); } diff --git a/src/Umbraco.Tests/TestHelpers/TestWithApplicationBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithApplicationBase.cs index ee8483a155..17a94413c1 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithApplicationBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithApplicationBase.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using Moq; using NUnit.Framework; @@ -13,6 +14,7 @@ using Umbraco.Core.Strings; using Umbraco.Core.DI; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Events; +using Umbraco.Core.Manifest; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Plugins; using Umbraco.Core.Services; @@ -134,7 +136,14 @@ namespace Umbraco.Tests.TestHelpers Container.RegisterSingleton(); Container.RegisterSingleton(); - Container.RegisterSingleton(f => new PropertyEditorCollection(Enumerable.Empty())); + // somehow property editor ends up wanting this + Container.RegisterSingleton(f => new ManifestBuilder( + f.GetInstance(), + new ManifestParser(f.GetInstance(), new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")), f.GetInstance()) + )); + + // note - don't register collections, use builders + Container.RegisterCollectionBuilder(); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index d7c0169b99..d8f6bff78b 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -30,6 +30,7 @@ using Umbraco.Web.Routing; using File = System.IO.File; using Umbraco.Core.DI; using Umbraco.Core.Events; +using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers.Stubs; @@ -87,13 +88,9 @@ namespace Umbraco.Tests.TestHelpers Container.Register(); Container.Register(factory => _facadeService); - var manifestBuilder = new ManifestBuilder( - new NullCacheProvider(), - new ManifestParser(Logger, new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")), new NullCacheProvider())); - Container.Register(_ => manifestBuilder); - - Container.RegisterCollectionBuilder() - .Add(() => Core.DI.Current.PluginManager.ResolvePropertyEditors()); + Container.GetInstance() + .Clear() + .Add(f => f.GetInstance().ResolvePropertyEditors()); Container.RegisterSingleton(f => { @@ -101,7 +98,10 @@ namespace Umbraco.Tests.TestHelpers return TestObjects.GetDatabaseFactoryMock(); var sqlSyntaxProviders = new[] { new SqlCeSyntaxProvider() }; - var factory = new DefaultDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), sqlSyntaxProviders, Logger, f.GetInstance(), Mappers); + var logger = f.GetInstance(); + var umbracoDatabaseAccessor = f.GetInstance(); + var mappers = f.GetInstance(); + var factory = new DefaultDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), sqlSyntaxProviders, logger, umbracoDatabaseAccessor, mappers); factory.ResetForTests(); return factory; }); @@ -119,7 +119,9 @@ namespace Umbraco.Tests.TestHelpers _isFirstInFixture = false; _isFirstInSession = false; - using (ProfilingLogger.TraceDuration("teardown")) // fixme move that one up + var profilingLogger = Container.TryGetInstance(); + var timer = profilingLogger?.TraceDuration("teardown"); // fixme move that one up + try { if (Options.Database == UmbracoTestOptions.Database.NewSchemaPerTest) RemoveDatabaseFile(Core.DI.Current.HasContainer ? Core.DI.Current.Container.TryGetInstance()?.Database : null); @@ -130,6 +132,10 @@ namespace Umbraco.Tests.TestHelpers _facadeService?.Dispose(); _facadeService = null; } + finally + { + timer?.Dispose(); + } base.TearDown(); } @@ -150,78 +156,6 @@ namespace Umbraco.Tests.TestHelpers } } - // fixme implement this one way or another!!! - // - //protected override ApplicationContext CreateApplicationContext() - //{ - // var sqlSyntaxProviders = new[] { new SqlCeSyntaxProvider() }; - - // // create the database if required - // // note: must do before instanciating the database factory else it will - // // not find the database and will remain un-configured. - // using (ProfilingLogger.TraceDuration("Create database.")) - // { - // //TODO make it faster - // CreateSqlCeDatabase(); - // } - - // // ensure the configuration matches the current version for tests - // SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3); - - // // create the database factory - if the test does not require an actual database, - // // use a mock factory; otherwise use a real factory. - // IDatabaseFactory databaseFactory; - // if (DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture) - // { - // databaseFactory = TestObjects.GetIDatabaseFactoryMock(); - // } - // else - // { - // var f = new DefaultDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), sqlSyntaxProviders, Logger, new TestUmbracoDatabaseAccessor(), Mappers); - // f.ResetForTests(); - // databaseFactory = f; - // } - - // // so, using the above code to create a mock IDatabaseFactory if we don't have a real database - // // but, that will NOT prevent _appContext from NOT being configured, because it cannot connect - // // to the database to check the migrations ;-( - - // var evtMsgs = new TransientEventMessagesFactory(); - // var databaseContext = new DatabaseContext(databaseFactory, Logger, Mock.Of(), Mock.Of()); - // var repositoryFactory = Container.GetInstance(); - // var serviceContext = TestObjects.GetServiceContext( - // repositoryFactory, - // _uowProvider = new NPocoUnitOfWorkProvider(databaseFactory, repositoryFactory), - // new FileUnitOfWorkProvider(), - // CacheHelper, - // Logger, - // evtMsgs, - // Enumerable.Empty()); - - // // if the test does not require an actual database, or runs with an empty database, the application - // // context will not be able to check the migration status in the database, so we have to force it - // // to think it is configured. - // var appContextMock = new Mock(databaseContext, serviceContext, CacheHelper, ProfilingLogger); - // //if (DatabaseTestBehavior == DatabaseBehavior.NoDatabasePerFixture // no db at all - // // || DatabaseTestBehavior == DatabaseBehavior.EmptyDbFilePerTest) // empty db - // // appContextMock.Setup(x => x.IsConfigured).Returns(true); - // _appContext = appContextMock.Object; - - // // initialize the database if required - // // note: must do after creating the application context as - // // it is using it - // using (ProfilingLogger.TraceDuration("Initialize database.")) - // { - // // TODO make it faster - // InitializeDatabase(_appContext); - // } - - // // application is ready - // //_appContext.IsReady = true; - - // return _appContext; - //} - protected virtual ISqlSyntaxProvider GetSyntaxProvider() { return new SqlCeSyntaxProvider(); @@ -305,19 +239,12 @@ namespace Umbraco.Tests.TestHelpers } } - } - /// - /// sets up resolvers before resolution is frozen - /// protected override void Initialize() // fixme - should NOT be here! { base.Initialize(); - // fixme - what about if (PropertyValueConvertersResolver.HasCurrent == false) ?? - Container.RegisterCollectionBuilder(); - // ensure we have a FacadeService if (_facadeService == null) {