Dictionary params & error handling
This commit is contained in:
committed by
Lars-Erik Aabech
parent
70d93d4668
commit
bc80affcf1
@@ -19,6 +19,17 @@ namespace Umbraco.Core.Composing
|
||||
public static T GetInstance<T>(this IContainer container)
|
||||
=> (T) container.GetInstance(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a named instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the instance.</typeparam>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="name">The name of the instance.</typeparam>
|
||||
/// <returns>An instance of the specified type and name.</returns>
|
||||
/// <remarks>Throws an exception if the container failed to get an instance of the specified type.</remarks>
|
||||
public static T GetInstance<T>(this IContainer container, string name)
|
||||
=> (T) container.GetInstance(typeof(T), name);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get an instance.
|
||||
/// </summary>
|
||||
@@ -49,7 +60,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 CreateInstance<T>(this IContainer container, params object[] args)
|
||||
public static T CreateInstance<T>(this IContainer container, IDictionary<string, object> args)
|
||||
=> (T) container.CreateInstance(typeof(T), args);
|
||||
|
||||
/// <summary>
|
||||
@@ -64,6 +75,12 @@ namespace Umbraco.Core.Composing
|
||||
public static void Register<TService, TImplementing>(this IContainer container, string name, Lifetime lifetime = Lifetime.Transient)
|
||||
=> container.Register(typeof(TService), typeof(TImplementing), name, lifetime);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service with a named implementation type and factory.
|
||||
/// </summary>
|
||||
public static void Register<TService, TImplementing>(this IContainer container, string name, Func<IContainer, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
=> container.Register(factory, name, lifetime);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service as its own implementation.
|
||||
/// </summary>
|
||||
@@ -112,8 +129,8 @@ namespace Umbraco.Core.Composing
|
||||
if (container.GetRegistered<TBuilder>().Any())
|
||||
throw new InvalidOperationException("Collection builders should be registered only once.");
|
||||
|
||||
// register the builder - passing the container as an arg to the factory
|
||||
container.RegisterSingleton(c => c.CreateInstance<TBuilder>(container));
|
||||
// register the builder
|
||||
container.RegisterSingleton<TBuilder>();
|
||||
|
||||
// initialize and return the builder
|
||||
return container.GetInstance<TBuilder>();
|
||||
|
||||
@@ -70,14 +70,14 @@ namespace Umbraco.Core.Composing
|
||||
/// Creates an instance with arguments.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the instance.</param>
|
||||
/// <param name="args">Arguments.</param>
|
||||
/// <param name="args">Named arguments.</param>
|
||||
/// <returns>An instance of the specified type.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The instance type does not need to be registered into the container.</para>
|
||||
/// <para>The arguments are used as dependencies by the container. Other dependencies
|
||||
/// are retrieved from the container.</para>
|
||||
/// </remarks>
|
||||
object CreateInstance(Type type, params object[] args);
|
||||
object CreateInstance(Type type, IDictionary<string, object> args);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -104,6 +104,11 @@ namespace Umbraco.Core.Composing
|
||||
/// </summary>
|
||||
void Register(Type serviceType, Type implementingType, string name, Lifetime lifetime = Lifetime.Transient);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a named service with an implementation factory.
|
||||
/// </summary>
|
||||
void Register<TService>(Func<IContainer, TService> factory, string name, Lifetime lifetime = Lifetime.Transient);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service with an implementation factory.
|
||||
/// </summary>
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
=> Container.AvailableServices.Where(x => x.ServiceType == type).Select(x => new Registration(x.ServiceType, x.ServiceName));
|
||||
|
||||
/// <inheritdoc />
|
||||
public object CreateInstance(Type type, params object[] args)
|
||||
public object CreateInstance(Type type, IDictionary<string, object> args)
|
||||
{
|
||||
// LightInject has this, but then it requires RegisterConstructorDependency etc and has various oddities
|
||||
// including the most annoying one, which is that it does not work on singletons (hard to fix)
|
||||
@@ -146,7 +146,7 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
{
|
||||
// no! IsInstanceOfType is not ok here
|
||||
// ReSharper disable once UseMethodIsInstanceOfType
|
||||
var arg = args?.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType()));
|
||||
var arg = args?.Values.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType()));
|
||||
ctorArgs[i++] = arg ?? GetInstance(parameter.ParameterType);
|
||||
}
|
||||
return ctor.Invoke(ctorArgs);
|
||||
@@ -234,6 +234,24 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register<TService>(Func<IContainer, TService> factory, string name, Lifetime lifetime = Lifetime.Transient)
|
||||
{
|
||||
switch (lifetime)
|
||||
{
|
||||
case Lifetime.Transient:
|
||||
case Lifetime.Request:
|
||||
case Lifetime.Scope:
|
||||
Container.Register(f => factory(this), name, GetLifetime(lifetime));
|
||||
break;
|
||||
case Lifetime.Singleton:
|
||||
Container.RegisterSingleton(f => factory(this), name);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Lifetime {lifetime} is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
private ILifetime GetLifetime(Lifetime lifetime)
|
||||
{
|
||||
switch (lifetime)
|
||||
|
||||
@@ -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.CreateInstance<TFileSystem>((IFileSystem) shadowWrapper);
|
||||
var fs = Current.Container.CreateInstance<TFileSystem>(new Dictionary<string, object>{{ "wrapped", (IFileSystem) shadowWrapper }});
|
||||
_wrappers.Add(shadowWrapper); // keeping a reference to the wrapper
|
||||
return fs;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
@@ -14,7 +15,7 @@ namespace Umbraco.Core.Migrations
|
||||
|
||||
public IMigration Build(Type migrationType, IMigrationContext context)
|
||||
{
|
||||
return (IMigration) _container.CreateInstance(migrationType, context);
|
||||
return (IMigration) _container.CreateInstance(migrationType, new Dictionary<string, object>{{"context", context}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Tests.Composing
|
||||
@@ -46,7 +47,7 @@ namespace Umbraco.Tests.Composing
|
||||
public void CanRegisterSingletonWithCreate()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
container.RegisterSingleton(c => c.CreateInstance<TestClass3>(new TestClass1()));
|
||||
container.RegisterSingleton(c => c.CreateInstance<TestClass3>(new Dictionary<string, object>{{"c", new TestClass1()}}));
|
||||
var s1 = container.GetInstance<TestClass3>();
|
||||
var s2 = container.GetInstance<TestClass3>();
|
||||
Assert.AreSame(s1, s2);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Web;
|
||||
using System;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
@@ -16,9 +17,20 @@ namespace Umbraco.Web.Composing
|
||||
/// <inheritdoc />
|
||||
public void Init(HttpApplication context)
|
||||
{
|
||||
// using the service locator here - no other way, really
|
||||
Module = Current.Container.GetInstance<TModule>();
|
||||
Module.Init(context);
|
||||
try
|
||||
{
|
||||
// using the service locator here - no other way, really
|
||||
Module = Current.Container.GetInstance<TModule>();
|
||||
Module.Init(context);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var runtimeState = Current.Container.GetInstance<IRuntimeState>();
|
||||
if (runtimeState.BootFailedException != null)
|
||||
{
|
||||
throw new Exception("Failed to boot", runtimeState.BootFailedException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user