Cleanup registrations
This commit is contained in:
@@ -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<IFileSystems>(factory => factory.GetInstance<FileSystems>());
|
||||
|
||||
// register MediaFileSystem, which can be injected directly
|
||||
container.RegisterSingleton(factory => factory.GetInstance<IFileSystems>().MediaFileSystem);
|
||||
|
||||
// register MediaFileSystem, so that FileSystems can create it
|
||||
container.Register<IFileSystem, MediaFileSystem>((f, wrappedFileSystem)
|
||||
=> new MediaFileSystem(wrappedFileSystem, f.GetInstance<IContentSection>(), f.GetInstance<IMediaPathScheme>(), f.GetInstance<ILogger>()));
|
||||
container.Register/*Singleton*/(factory => factory.GetInstance<IFileSystems>().MediaFileSystem);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <para>Throws an exception if the container failed to get an instance of the specified type.</para>
|
||||
/// <para>The arguments are used as dependencies by the container.</para>
|
||||
/// </remarks>
|
||||
public static T GetInstance<T>(this IContainer container, object[] args)
|
||||
public static T GetInstance<T>(this IContainer container, params object[] args)
|
||||
=> (T) container.GetInstance(typeof(T), args);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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
|
||||
/// <para>Throws an exception if the container failed to get an instance of the specified type.</para>
|
||||
/// <para>The arguments are used as dependencies by the container.</para>
|
||||
/// </remarks>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get an instance.
|
||||
@@ -67,13 +69,23 @@ namespace Umbraco.Core.Composing
|
||||
/// <typeparam name="TService">The type of the service.</typeparam>
|
||||
IEnumerable<TService> GetAllInstances<TService>();
|
||||
|
||||
// fixme
|
||||
/// <summary>
|
||||
/// Gets registration for a service.
|
||||
/// </summary>
|
||||
/// <param name="serviceType">The type of the service.</param>
|
||||
/// <returns>The registrations for the service.</returns>
|
||||
IEnumerable<Registration> 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
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service as its own implementation.
|
||||
/// </summary>
|
||||
@@ -107,6 +119,13 @@ namespace Umbraco.Core.Composing
|
||||
/// <summary>
|
||||
/// Registers a base type for auto-registration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Auto-registration means that anytime the container is asked to create an instance
|
||||
/// of a type deriving from <paramref name="serviceBaseType"/>, it will first register that
|
||||
/// type automatically.</para>
|
||||
/// <para>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.</para>
|
||||
/// </remarks>
|
||||
void RegisterAuto(Type serviceBaseType);
|
||||
|
||||
/// <summary>
|
||||
@@ -114,11 +133,6 @@ namespace Umbraco.Core.Composing
|
||||
/// </summary>
|
||||
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<TDependency>(Func<IContainer, ParameterInfo, TDependency> factory);
|
||||
void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, object[], TDependency> factory);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Control
|
||||
@@ -134,6 +148,12 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
// fixme - document all these
|
||||
|
||||
/// <summary>
|
||||
/// Configures the container for Umbraco.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para></para>
|
||||
/// </remarks>
|
||||
IContainer ConfigureForUmbraco();
|
||||
|
||||
IContainer ConfigureForWeb();
|
||||
|
||||
@@ -62,8 +62,26 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
=> Container.GetInstance(type, name);
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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));
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, TDependency> factory)
|
||||
=> Container.RegisterConstructorDependency((f, x) => factory(this, x));
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, object[], TDependency> 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
|
||||
//
|
||||
///// <inheritdoc />
|
||||
//public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, TDependency> factory)
|
||||
// => Container.RegisterConstructorDependency((f, x) => factory(this, x));
|
||||
//
|
||||
///// <inheritdoc />
|
||||
//public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, object[], TDependency> 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<IContainer>().FirstOrDefault());
|
||||
|
||||
// which means that the only way to inject the container into builders is to register it
|
||||
Container.RegisterInstance<IContainer>(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<IContainer>(this);
|
||||
//
|
||||
// instead, we use an explicit GetInstance with arguments implementation
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user