Refactor collection builders to be nicer with DI
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,29 +18,22 @@ namespace Umbraco.Core.Composing
|
||||
private readonly object _locker = new object();
|
||||
private Type[] _registeredTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the container.
|
||||
/// </summary>
|
||||
protected IRegister Container { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal list of types as an IEnumerable (immutable).
|
||||
/// </summary>
|
||||
public IEnumerable<Type> GetTypes() => _types;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the builder.
|
||||
/// </summary>
|
||||
/// <remarks>By default, this registers the collection automatically.</remarks>
|
||||
public virtual void Initialize(IRegister container)
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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
|
||||
/// <returns>The collection items.</returns>
|
||||
protected virtual IEnumerable<TItem> 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))
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
public interface ICollectionBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
void Initialize(IRegister container);
|
||||
void RegisterWith(IRegister register);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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<IMapperCollection>(factory => factory.GetInstance<MapperCollection>());
|
||||
register.Register<IMapperCollection>(factory => factory.GetInstance<MapperCollection>());
|
||||
}
|
||||
|
||||
public MapperCollectionBuilder AddCoreMappers()
|
||||
|
||||
@@ -184,7 +184,9 @@ namespace Umbraco.Tests.Components
|
||||
Composed.Clear();
|
||||
Initialized.Clear();
|
||||
composers.Compose();
|
||||
var components = composition.WithCollectionBuilder<ComponentCollectionBuilder>().CreateCollection(factory);
|
||||
var builder = composition.WithCollectionBuilder<ComponentCollectionBuilder>();
|
||||
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<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
composers.Compose();
|
||||
var components = composition.WithCollectionBuilder<ComponentCollectionBuilder>().CreateCollection(factory);
|
||||
var builder = composition.WithCollectionBuilder<ComponentCollectionBuilder>();
|
||||
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]);
|
||||
|
||||
@@ -129,12 +129,10 @@ namespace Umbraco.Tests.Composing
|
||||
// legal so far...
|
||||
.Add(() => new[] { typeof(TransientObject4) });
|
||||
|
||||
var factory = composition.CreateFactory();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
// but throws here when trying to register the types
|
||||
var values = factory.GetInstance<TestCollection>();
|
||||
// but throws here when trying to register the types, right before creating the factory
|
||||
var factory = composition.CreateFactory();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -37,20 +37,21 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
var container = RegisterFactory.Create();
|
||||
|
||||
var composition = new Composition(container, new TypeLoader(), Mock.Of<IProfilingLogger>(), ComponentTests.MockRuntimeState(RuntimeLevel.Run));
|
||||
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
|
||||
var typeLoader = new TypeLoader(NullCacheProvider.Instance,
|
||||
LocalTempStorage.Default,
|
||||
logger,
|
||||
false);
|
||||
|
||||
var composition = new Composition(container, typeLoader, Mock.Of<IProfilingLogger>(), ComponentTests.MockRuntimeState(RuntimeLevel.Run));
|
||||
|
||||
composition.RegisterUnique<ILogger>(_ => Mock.Of<ILogger>());
|
||||
composition.RegisterUnique<IProfiler>(_ => Mock.Of<IProfiler>());
|
||||
|
||||
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
|
||||
var pluginManager = new TypeLoader(NullCacheProvider.Instance,
|
||||
LocalTempStorage.Default,
|
||||
logger,
|
||||
false);
|
||||
composition.RegisterUnique(pluginManager);
|
||||
composition.RegisterUnique(typeLoader);
|
||||
|
||||
composition.WithCollectionBuilder<MapperCollectionBuilder>()
|
||||
.Add(() => Current.TypeLoader.GetAssignedMapperTypes());
|
||||
.Add(() => composition.TypeLoader.GetAssignedMapperTypes());
|
||||
|
||||
var factory = Current.Factory = composition.CreateFactory();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user