From f6cd13488ee730916be4aa3fe4b925c6bd165b0f Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 4 Jan 2019 08:53:51 +0100 Subject: [PATCH] Refactor collection builders to be nicer with DI --- src/Umbraco.Core/Components/Composition.cs | 12 +++---- .../Composing/CollectionBuilderBase.cs | 32 ++++++++----------- .../Composing/ICollectionBuilder.cs | 5 +-- .../Mappers/MapperCollectionBuilder.cs | 6 ++-- .../Components/ComponentTests.cs | 8 +++-- .../Composing/LazyCollectionBuilderTests.cs | 6 ++-- .../TestHelpers/BaseUsingSqlCeSyntax.cs | 17 +++++----- .../Runtime/WebRuntimeComponent.cs | 2 +- 8 files changed, 43 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Core/Components/Composition.cs b/src/Umbraco.Core/Components/Composition.cs index cc52b2d814..53acbdb132 100644 --- a/src/Umbraco.Core/Components/Composition.cs +++ b/src/Umbraco.Core/Components/Composition.cs @@ -89,7 +89,10 @@ namespace Umbraco.Core.Components onCreating(); foreach (var unique in _uniques.Values) - unique.RegisterTo(_register); + unique.RegisterWith(_register); + + foreach (var builder in _builders.Values) + builder.RegisterWith(_register); return _register.CreateFactory(); } @@ -147,7 +150,7 @@ namespace Umbraco.Core.Components _instance = instance; } - public virtual void RegisterTo(IRegister register) + public virtual void RegisterWith(IRegister register) { if (_implementingType != null) register.Register(_serviceType, _implementingType, Lifetime.Singleton); @@ -166,7 +169,7 @@ namespace Umbraco.Core.Components _factory = factory; } - public override void RegisterTo(IRegister register) + public override void RegisterWith(IRegister register) { register.Register(_factory, Lifetime.Singleton); } @@ -190,10 +193,7 @@ namespace Umbraco.Core.Components return (TBuilder) o; var builder = new TBuilder(); - builder.Initialize(_register); - _builders[typeOfBuilder] = builder; - return builder; } diff --git a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs index f370e9bd8c..7633f6b001 100644 --- a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs +++ b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs @@ -18,29 +18,22 @@ namespace Umbraco.Core.Composing private readonly object _locker = new object(); private Type[] _registeredTypes; - /// - /// Gets the container. - /// - protected IRegister Container { get; private set; } - /// /// Gets the internal list of types as an IEnumerable (immutable). /// public IEnumerable GetTypes() => _types; - /// - /// Initializes a new instance of the builder. - /// - /// By default, this registers the collection automatically. - public virtual void Initialize(IRegister container) + /// + public virtual void RegisterWith(IRegister register) { - if (Container != null) - throw new InvalidOperationException("This builder has already been initialized."); - - Container = container; + if (_registeredTypes != null) + throw new InvalidOperationException("This builder has already been registered."); // register the collection - Container.Register(CreateCollection, CollectionLifetime); + register.Register(CreateCollection, CollectionLifetime); + + // register the types + RegisterTypes(register); } /// @@ -58,7 +51,7 @@ namespace Umbraco.Core.Composing lock (_locker) { if (_registeredTypes != null) - throw new InvalidOperationException("Cannot configure a collection builder after its types have been resolved."); + throw new InvalidOperationException("Cannot configure a collection builder after it has been registered."); action(_types); } } @@ -74,7 +67,7 @@ namespace Umbraco.Core.Composing return types; } - private void RegisterTypes() + private void RegisterTypes(IRegister register) { lock (_locker) { @@ -88,7 +81,7 @@ namespace Umbraco.Core.Composing // register them foreach (var type in types) - Container.Register(type); + register.Register(type); _registeredTypes = types; } @@ -100,7 +93,8 @@ namespace Umbraco.Core.Composing /// The collection items. protected virtual IEnumerable CreateItems(IFactory factory) { - RegisterTypes(); // will do it only once + if (_registeredTypes == null) + throw new InvalidOperationException("Cannot create items before the collection builder has been registered."); return _registeredTypes // respect order .Select(x => CreateItem(factory, x)) diff --git a/src/Umbraco.Core/Composing/ICollectionBuilder.cs b/src/Umbraco.Core/Composing/ICollectionBuilder.cs index e17a362e6d..84ff3ba747 100644 --- a/src/Umbraco.Core/Composing/ICollectionBuilder.cs +++ b/src/Umbraco.Core/Composing/ICollectionBuilder.cs @@ -6,9 +6,10 @@ public interface ICollectionBuilder { /// - /// Initializes a new instance of the builder, and registers the collection. + /// Registers the builder so it can build the collection, by + /// registering the collection and the types. /// - void Initialize(IRegister container); + void RegisterWith(IRegister register); } /// diff --git a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs index 40bc76928b..80819933f5 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs @@ -6,9 +6,9 @@ namespace Umbraco.Core.Persistence.Mappers { protected override MapperCollectionBuilder This => this; - public override void Initialize(IRegister container) + public override void RegisterWith(IRegister register) { - base.Initialize(container); + base.RegisterWith(register); // default initializer registers // - service MapperCollectionBuilder, returns MapperCollectionBuilder @@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.Mappers // we want to register extra // - service IMapperCollection, returns MappersCollectionBuilder's collection - Container.Register(factory => factory.GetInstance()); + register.Register(factory => factory.GetInstance()); } public MapperCollectionBuilder AddCoreMappers() diff --git a/src/Umbraco.Tests/Components/ComponentTests.cs b/src/Umbraco.Tests/Components/ComponentTests.cs index f50feb1d00..6836ca433c 100644 --- a/src/Umbraco.Tests/Components/ComponentTests.cs +++ b/src/Umbraco.Tests/Components/ComponentTests.cs @@ -184,7 +184,9 @@ namespace Umbraco.Tests.Components Composed.Clear(); Initialized.Clear(); composers.Compose(); - var components = composition.WithCollectionBuilder().CreateCollection(factory); + var builder = composition.WithCollectionBuilder(); + builder.RegisterWith(register); + var components = builder.CreateCollection(factory); Assert.AreEqual(2, Composed.Count); Assert.AreEqual(typeof(Composer1), Composed[0]); Assert.AreEqual(typeof(Composer5), Composed[1]); @@ -234,7 +236,9 @@ namespace Umbraco.Tests.Components var composers = new Composers(composition, types, Mock.Of()); Composed.Clear(); composers.Compose(); - var components = composition.WithCollectionBuilder().CreateCollection(factory); + var builder = composition.WithCollectionBuilder(); + builder.RegisterWith(register); + var components = builder.CreateCollection(factory); Assert.AreEqual(3, Composed.Count); Assert.AreEqual(typeof(Composer4), Composed[0]); Assert.AreEqual(typeof(Composer2), Composed[1]); diff --git a/src/Umbraco.Tests/Composing/LazyCollectionBuilderTests.cs b/src/Umbraco.Tests/Composing/LazyCollectionBuilderTests.cs index b9edb96f1c..cbabae1a83 100644 --- a/src/Umbraco.Tests/Composing/LazyCollectionBuilderTests.cs +++ b/src/Umbraco.Tests/Composing/LazyCollectionBuilderTests.cs @@ -129,12 +129,10 @@ namespace Umbraco.Tests.Composing // legal so far... .Add(() => new[] { typeof(TransientObject4) }); - var factory = composition.CreateFactory(); - Assert.Throws(() => { - // but throws here when trying to register the types - var values = factory.GetInstance(); + // but throws here when trying to register the types, right before creating the factory + var factory = composition.CreateFactory(); }); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 9ba8c6fb83..7fd2f0f18b 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -37,20 +37,21 @@ namespace Umbraco.Tests.TestHelpers var container = RegisterFactory.Create(); - var composition = new Composition(container, new TypeLoader(), Mock.Of(), ComponentTests.MockRuntimeState(RuntimeLevel.Run)); + var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); + var typeLoader = new TypeLoader(NullCacheProvider.Instance, + LocalTempStorage.Default, + logger, + false); + + var composition = new Composition(container, typeLoader, Mock.Of(), ComponentTests.MockRuntimeState(RuntimeLevel.Run)); composition.RegisterUnique(_ => Mock.Of()); composition.RegisterUnique(_ => Mock.Of()); - var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); - var pluginManager = new TypeLoader(NullCacheProvider.Instance, - LocalTempStorage.Default, - logger, - false); - composition.RegisterUnique(pluginManager); + composition.RegisterUnique(typeLoader); composition.WithCollectionBuilder() - .Add(() => Current.TypeLoader.GetAssignedMapperTypes()); + .Add(() => composition.TypeLoader.GetAssignedMapperTypes()); var factory = Current.Factory = composition.CreateFactory(); diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs index 4d31c4a351..8aff0457ea 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs @@ -32,7 +32,7 @@ using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Web.Runtime { - internal sealed class WebRuntimeComponent : IComponent + public sealed class WebRuntimeComponent : IComponent { public WebRuntimeComponent( IRuntimeState runtime,