Change fluent registration #29
pull/37/head
Simon G 6 years ago committed by GitHub
commit 0ff27b114b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      LightweightIocContainer/Exceptions/UnknownRegistrationException.cs
  2. 20
      LightweightIocContainer/Interfaces/IIocContainer.cs
  3. 2
      LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs
  4. 31
      LightweightIocContainer/Interfaces/Registrations/IDefaultRegistration.cs
  5. 24
      LightweightIocContainer/Interfaces/Registrations/IRegistration.cs
  6. 48
      LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs
  7. 27
      LightweightIocContainer/Interfaces/Registrations/ISingleTypeRegistration.cs
  8. 2
      LightweightIocContainer/Interfaces/Registrations/ITypedFactoryRegistration.cs
  9. 8
      LightweightIocContainer/Interfaces/Registrations/IUnitTestCallbackRegistration.cs
  10. 14
      LightweightIocContainer/InternalResolvePlaceholder.cs
  11. 121
      LightweightIocContainer/IocContainer.cs
  12. 2
      LightweightIocContainer/Lifestyle.cs
  13. 289
      LightweightIocContainer/LightweightIocContainer.xml
  14. 59
      LightweightIocContainer/Registrations/DefaultRegistration.cs
  15. 119
      LightweightIocContainer/Registrations/RegistrationBase.cs
  16. 19
      LightweightIocContainer/Registrations/RegistrationFactory.cs
  17. 44
      LightweightIocContainer/Registrations/SingleTypeRegistration.cs
  18. 5
      LightweightIocContainer/Registrations/UnitTestCallbackRegistration.cs
  19. 4
      Test.LightweightIocContainer/AssemblyInstallerTest.cs
  20. 47
      Test.LightweightIocContainer/DefaultRegistrationTest.cs
  21. 169
      Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs
  22. 43
      Test.LightweightIocContainer/IocContainerTest.cs
  23. 119
      Test.LightweightIocContainer/RegistrationBaseTest.cs
  24. 61
      Test.LightweightIocContainer/SingleTypeRegistrationTest.cs
  25. 2
      Test.LightweightIocContainer/UnitTestCallbackRegistrationTest.cs

@ -8,12 +8,12 @@ using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Exceptions
{
/// <summary>
/// An unknown <see cref="IRegistrationBase"/> was used
/// An unknown <see cref="IRegistration"/> was used
/// </summary>
internal class UnknownRegistrationException : Exception
{
/// <summary>
/// An unknown <see cref="IRegistrationBase"/> was used
/// An unknown <see cref="IRegistration"/> was used
/// </summary>
/// <param name="message">The exception message</param>
public UnknownRegistrationException(string message)

@ -3,14 +3,13 @@
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Interfaces
{
/// <summary>
/// The main container that carries all the <see cref="IRegistrationBase"/>s and can resolve all the types you'll ever want
/// The main container that carries all the <see cref="IRegistration"/>s and can resolve all the types you'll ever want
/// </summary>
public interface IIocContainer : IDisposable
{
@ -26,17 +25,17 @@ namespace LightweightIocContainer.Interfaces
/// </summary>
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IDefaultRegistration{TInterface}"/></param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase{TInterface}"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
IDefaultRegistration<TInterface> Register<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface;
/// <summary>
/// Register a <see cref="Type"/> without an interface
/// </summary>
/// <typeparam name="TImplementation">The <see cref="Type"/> to register</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IDefaultRegistration{TInterface}"/></param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
IDefaultRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient);
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase{TInterface}"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
ISingleTypeRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient);
/// <summary>
/// Register an Interface with a Type that implements it as a multiton
@ -44,14 +43,14 @@ namespace LightweightIocContainer.Interfaces
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <typeparam name="TScope">The Type of the multiton scope</typeparam>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
IMultitonRegistration<TInterface> Register<TInterface, TImplementation, TScope>() where TImplementation : TInterface;
/// <summary>
/// Register an Interface as an abstract typed factory
/// </summary>
/// <typeparam name="TFactory">The abstract typed factory to register</typeparam>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
ITypedFactoryRegistration<TFactory> RegisterFactory<TFactory>();
/// <summary>
@ -59,7 +58,8 @@ namespace LightweightIocContainer.Interfaces
/// </summary>
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <param name="unitTestCallback">The <see cref="ResolveCallback{T}"/> for the callback</param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
[Obsolete("RegisterUnitTestCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
IUnitTestCallbackRegistration<TInterface> RegisterUnitTestCallback<TInterface>(ResolveCallback<TInterface> unitTestCallback);
/// <summary>

@ -12,7 +12,7 @@ namespace LightweightIocContainer.Interfaces.Installers
public interface IIocInstaller
{
/// <summary>
/// Install the needed <see cref="IRegistrationBase"/>s in the given <see cref="IIocContainer"/>
/// Install the needed <see cref="IRegistration"/>s in the given <see cref="IIocContainer"/>
/// </summary>
/// <param name="container">The current <see cref="IIocContainer"/></param>
void Install(IIocContainer container);

@ -1,39 +1,20 @@
// Author: simon.gockner
// Created: 2019-05-20
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Interfaces.Installers;
namespace LightweightIocContainer.Interfaces.Registrations
{
/// <summary>
/// The default registration that is used to register a <see cref="Type"/> for the Interface it implements
/// The <see cref="IDefaultRegistration{TInterface}"/> to register a <see cref="Type"/> for the Interface it implements
/// </summary>
/// <typeparam name="TInterface">The registered Interface</typeparam>
public interface IDefaultRegistration<TInterface> : IRegistrationBase
/// <typeparam name="TInterface">The <see cref="Type"/> of the interface</typeparam>
public interface IDefaultRegistration<TInterface> : IRegistrationBase<TInterface>
{
/// <summary>
/// The <see cref="Type"/> that implements the <see cref="IRegistrationBase.InterfaceType"/> that is registered with this <see cref="IDefaultRegistration{TInterface}"/>
/// The <see cref="Type"/> that implements the <see cref="IRegistration.InterfaceType"/> that is registered with this <see cref="IRegistrationBase{TInterface}"/>
/// </summary>
Type ImplementationType { get; }
/// <summary>
/// The Lifestyle of Instances that are created with this <see cref="IDefaultRegistration{TInterface}"/>
/// </summary>
Lifestyle Lifestyle { get; }
/// <summary>
/// This <see cref="Action{T}"/> is invoked when an instance of this type is created.
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="OnCreate"/></para>
/// </summary>
Action<TInterface> OnCreateAction { get; }
/// <summary>
/// Pass an <see cref="Action{T}"/> that will be invoked when an instance of this type is created
/// </summary>
/// <param name="action">The <see cref="Action{T}"/></param>
/// <returns>The current instance of this <see cref="IDefaultRegistration{TInterface}"/></returns>
IDefaultRegistration<TInterface> OnCreate(Action<TInterface> action);
}
}

@ -0,0 +1,24 @@
// Author: simon.gockner
// Created: 2019-05-20
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Interfaces.Registrations
{
/// <summary>
/// The base registration that is used to register an Interface
/// </summary>
public interface IRegistration
{
/// <summary>
/// The name of the <see cref="IRegistration"/>
/// </summary>
string Name { get; }
/// <summary>
/// The <see cref="Type"/> of the Interface that is registered with this <see cref="IRegistration"/>
/// </summary>
Type InterfaceType { get; }
}
}

@ -3,22 +3,58 @@
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces.Installers;
namespace LightweightIocContainer.Interfaces.Registrations
{
/// <summary>
/// The base registration that is used to register an Interface
/// The <see cref="IRegistrationBase{TInterface}"/> that is used to register an Interface
/// </summary>
public interface IRegistrationBase
/// <typeparam name="TInterface">The registered Interface</typeparam>
public interface IRegistrationBase<TInterface> : IRegistration
{
/// <summary>
/// The name of the <see cref="IRegistrationBase"/>
/// The Lifestyle of Instances that are created with this <see cref="IRegistrationBase{TInterface}"/>
/// </summary>
string Name { get; }
Lifestyle Lifestyle { get; }
/// <summary>
/// The <see cref="Type"/> of the Interface that is registered with this <see cref="IRegistrationBase"/>
/// This <see cref="Action{T}"/> is invoked when an instance of this type is created.
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="OnCreate"/></para>
/// </summary>
Type InterfaceType { get; }
Action<TInterface> OnCreateAction { get; }
/// <summary>
/// Pass an <see cref="Action{T}"/> that will be invoked when an instance of this type is created
/// </summary>
/// <param name="action">The <see cref="Action{T}"/></param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
IRegistrationBase<TInterface> OnCreate(Action<TInterface> action);
/// <summary>
/// An <see cref="Array"/> of parameters that are used to <see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="WithParameters(object[])"/></para>
/// </summary>
object[] Parameters { get; }
/// <summary>
/// Pass parameters that will be used to<see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving</para>
/// </summary>
/// <param name="parameters">The parameters</param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
/// <exception cref="InvalidRegistrationException"><see cref="Parameters"/> are already set or no parameters given</exception>
IRegistrationBase<TInterface> WithParameters(params object[] parameters);
/// <summary>
/// Pass parameters that will be used to<see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving</para>
/// </summary>
/// <param name="parameters">The parameters with their position</param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
/// <exception cref="InvalidRegistrationException"><see cref="Parameters"/> are already set or no parameters given</exception>
IRegistrationBase<TInterface> WithParameters(params (int index, object parameter)[] parameters);
}
}

@ -0,0 +1,27 @@
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Interfaces.Registrations
{
/// <summary>
/// The <see cref="IRegistrationBase{TInterface}"/> to register either only an interface or only a <see cref="Type"/>
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the <see cref="IRegistrationBase{TInterface}"/></typeparam>
public interface ISingleTypeRegistration<T> : IRegistrationBase<T>
{
/// <summary>
/// <see cref="Func{T,TResult}"/> that is invoked instead of creating an instance of this <see cref="Type"/> the default way
/// </summary>
Func<IIocContainer, T> FactoryMethod { get; }
/// <summary>
/// Pass a <see cref="Func{T,TResult}"/> that will be invoked instead of creating an instance of this <see cref="Type"/> the default way
/// </summary>
/// <param name="factoryMethod">The <see cref="Func{T,TResult}"/></param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
ISingleTypeRegistration<T> WithFactoryMethod(Func<IIocContainer, T> factoryMethod);
}
}

@ -10,7 +10,7 @@ namespace LightweightIocContainer.Interfaces.Registrations
/// The registration that is used to register an abstract typed factory
/// </summary>
/// <typeparam name="TFactory">The type of the abstract typed factory</typeparam>
public interface ITypedFactoryRegistration<TFactory> : IRegistrationBase
public interface ITypedFactoryRegistration<TFactory> : IRegistration
{
/// <summary>
/// The class that contains the implemented abstract factory of this <see cref="ITypedFactoryRegistration{TFactory}"/>

@ -2,17 +2,21 @@
// Created: 2019-10-15
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Interfaces.Registrations
{
/// <summary>
/// A special <see cref="IRegistrationBase"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// A special <see cref="IRegistration"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// </summary>
/// <typeparam name="TInterface"></typeparam>
public interface IUnitTestCallbackRegistration<out TInterface> : IRegistrationBase
[Obsolete("IUnitTestCallbackRegistration is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public interface IUnitTestCallbackRegistration<out TInterface> : IRegistration
{
/// <summary>
/// An <see cref="ResolveCallback{T}"/> that is set as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// </summary>
[Obsolete("UnitTestResolveCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
ResolveCallback<TInterface> UnitTestResolveCallback { get; }
}
}

@ -0,0 +1,14 @@
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
namespace LightweightIocContainer
{
/// <summary>
/// An internal placeholder that is used during the resolving process
/// </summary>
internal class InternalResolvePlaceholder
{
}
}

@ -17,19 +17,19 @@ using LightweightIocContainer.Registrations;
namespace LightweightIocContainer
{
/// <summary>
/// The main container that carries all the <see cref="IRegistrationBase"/>s and can resolve all the types you'll ever want
/// The main container that carries all the <see cref="IRegistration"/>s and can resolve all the types you'll ever want
/// </summary>
public class IocContainer : IIocContainer
{
private readonly RegistrationFactory _registrationFactory;
private readonly List<IRegistrationBase> _registrations = new List<IRegistrationBase>();
private readonly List<IRegistration> _registrations = new List<IRegistration>();
private readonly List<(Type type, object instance)> _singletons = new List<(Type, object)>();
private readonly List<(Type type, Type scope, ConditionalWeakTable<object, object> instances)> _multitons = new List<(Type, Type, ConditionalWeakTable<object, object>)>();
/// <summary>
/// The main container that carries all the <see cref="IRegistrationBase"/>s and can resolve all the types you'll ever want
/// The main container that carries all the <see cref="IRegistration"/>s and can resolve all the types you'll ever want
/// </summary>
public IocContainer()
{
@ -57,8 +57,8 @@ namespace LightweightIocContainer
/// </summary>
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IDefaultRegistration{TInterface}"/></param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase{TInterface}"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public IDefaultRegistration<TInterface> Register<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface
{
IDefaultRegistration<TInterface> registration = _registrationFactory.Register<TInterface, TImplementation>(lifestyle);
@ -71,11 +71,11 @@ namespace LightweightIocContainer
/// Register a <see cref="Type"/> without an interface
/// </summary>
/// <typeparam name="TImplementation">The <see cref="Type"/> to register</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IDefaultRegistration{TInterface}"/></param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
public IDefaultRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient)
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase{TInterface}"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public ISingleTypeRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient)
{
IDefaultRegistration<TImplementation> registration = _registrationFactory.Register<TImplementation>(lifestyle);
ISingleTypeRegistration<TImplementation> registration = _registrationFactory.Register<TImplementation>(lifestyle);
Register(registration);
return registration;
@ -87,7 +87,7 @@ namespace LightweightIocContainer
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <typeparam name="TScope">The Type of the multiton scope</typeparam>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
public IMultitonRegistration<TInterface> Register<TInterface, TImplementation, TScope>() where TImplementation : TInterface
{
IMultitonRegistration<TInterface> registration = _registrationFactory.Register<TInterface, TImplementation, TScope>();
@ -100,7 +100,7 @@ namespace LightweightIocContainer
/// Register an Interface as an abstract typed factory
/// </summary>
/// <typeparam name="TFactory">The abstract typed factory to register</typeparam>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
public ITypedFactoryRegistration<TFactory> RegisterFactory<TFactory>()
{
ITypedFactoryRegistration<TFactory> registration = _registrationFactory.RegisterFactory<TFactory>();
@ -114,7 +114,8 @@ namespace LightweightIocContainer
/// </summary>
/// <typeparam name="TInterface">The Interface to register</typeparam>
/// <param name="unitTestCallback">The <see cref="ResolveCallback{T}"/> for the callback</param>
/// <returns>The created <see cref="IRegistrationBase"/></returns>
/// <returns>The created <see cref="IRegistration"/></returns>
[Obsolete("RegisterUnitTestCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public IUnitTestCallbackRegistration<TInterface> RegisterUnitTestCallback<TInterface>(ResolveCallback<TInterface> unitTestCallback)
{
IUnitTestCallbackRegistration<TInterface> registration = _registrationFactory.RegisterUnitTestCallback(unitTestCallback);
@ -124,11 +125,11 @@ namespace LightweightIocContainer
}
/// <summary>
/// Add the <see cref="IRegistrationBase"/> to the the <see cref="IocContainer"/>
/// Add the <see cref="IRegistration"/> to the the <see cref="IocContainer"/>
/// </summary>
/// <param name="registration">The given <see cref="IRegistrationBase"/></param>
/// <param name="registration">The given <see cref="IRegistration"/></param>
/// <exception cref="MultipleRegistrationException">The <see cref="Type"/> is already registered in this <see cref="IocContainer"/></exception>
private void Register(IRegistrationBase registration)
private void Register(IRegistration registration)
{
//if type is already registered
if (_registrations.Any(r => r.InterfaceType == registration.InterfaceType))
@ -195,7 +196,7 @@ namespace LightweightIocContainer
/// <exception cref="UnknownRegistrationException">The registration for the given <see cref="Type"/> has an unknown <see cref="Type"/></exception>
private T ResolveInternal<T>(object[] arguments, List<Type> resolveStack = null)
{
IRegistrationBase registration = _registrations.FirstOrDefault(r => r.InterfaceType == typeof(T));
IRegistration registration = _registrations.FirstOrDefault(r => r.InterfaceType == typeof(T));
if (registration == null)
throw new TypeNotRegisteredException(typeof(T));
@ -209,11 +210,14 @@ namespace LightweightIocContainer
T resolvedInstance;
//TODO: remove this #pragma when IUnitTestCallbackRegistration is removed
#pragma warning disable 618
if (registration is IUnitTestCallbackRegistration<T> unitTestCallbackRegistration)
{
resolvedInstance = unitTestCallbackRegistration.UnitTestResolveCallback.Invoke(arguments);
}
else if (registration is IDefaultRegistration<T> defaultRegistration)
#pragma warning restore 618
else if (registration is IRegistrationBase<T> defaultRegistration)
{
if (defaultRegistration.Lifestyle == Lifestyle.Singleton)
resolvedInstance = GetOrCreateSingletonInstance(defaultRegistration, arguments, resolveStack);
@ -242,7 +246,7 @@ namespace LightweightIocContainer
/// <param name="arguments">The arguments to resolve</param>
/// <param name="resolveStack">The current resolve stack</param>
/// <returns>An existing or newly created singleton instance of the given <see cref="Type"/></returns>
private T GetOrCreateSingletonInstance<T>(IDefaultRegistration<T> registration, object[] arguments, List<Type> resolveStack)
private T GetOrCreateSingletonInstance<T>(IRegistrationBase<T> registration, object[] arguments, List<Type> resolveStack)
{
//if a singleton instance exists return it
object instance = _singletons.FirstOrDefault(s => s.type == typeof(T)).instance;
@ -306,15 +310,82 @@ namespace LightweightIocContainer
/// <param name="arguments">The constructor arguments</param>
/// <param name="resolveStack">The current resolve stack</param>
/// <returns>A newly created instance of the given <see cref="Type"/></returns>
private T CreateInstance<T>(IDefaultRegistration<T> registration, object[] arguments, List<Type> resolveStack)
private T CreateInstance<T>(IRegistrationBase<T> registration, object[] arguments, List<Type> resolveStack)
{
arguments = ResolveConstructorArguments(registration.ImplementationType, arguments, resolveStack);
T instance = (T) Activator.CreateInstance(registration.ImplementationType, arguments);
if (registration.Parameters != null)
arguments = UpdateArgumentsWithRegistrationParameters(registration, arguments);
T instance;
if (registration is IDefaultRegistration<T> defaultRegistration)
{
arguments = ResolveConstructorArguments(defaultRegistration.ImplementationType, arguments, resolveStack);
instance = (T) Activator.CreateInstance(defaultRegistration.ImplementationType, arguments);
}
else if (registration is ISingleTypeRegistration<T> singleTypeRegistration)
{
if (singleTypeRegistration.InterfaceType.IsInterface && singleTypeRegistration.FactoryMethod == null)
throw new InvalidRegistrationException($"Can't register an interface without its implementation type or without a factory method (Type: {singleTypeRegistration.InterfaceType}).");
if (singleTypeRegistration.FactoryMethod == null) //type registration without interface -> just create this type
{
arguments = ResolveConstructorArguments(singleTypeRegistration.InterfaceType, arguments, resolveStack);
instance = (T)Activator.CreateInstance(singleTypeRegistration.InterfaceType, arguments);
}
else //factory method set to create the instance
instance = singleTypeRegistration.FactoryMethod(this);
}
else
throw new UnknownRegistrationException($"There is no registration of type {registration.GetType().Name}.");
registration.OnCreateAction?.Invoke(instance); //TODO: Allow async OnCreateAction?
return instance;
}
/// <summary>
/// Update the given arguments with the <see cref="IRegistrationBase{TInterface}.Parameters"/> of the given <see cref="IRegistrationBase{TInterface}"/>
/// </summary>
/// <typeparam name="T">The given <see cref="Type"/></typeparam>
/// <param name="registration">The <see cref="IRegistrationBase{TInterface}"/> of the given <see cref="Type"/></param>
/// <param name="arguments">The constructor arguments</param>
/// <returns>The argument list updated with the <see cref="IRegistrationBase{TInterface}.Parameters"/></returns>
private object[] UpdateArgumentsWithRegistrationParameters<T>(IRegistrationBase<T> registration, object[] arguments)
{
if (arguments != null && arguments.Any()) //if more arguments were passed to resolve
{
int argumentsSize = registration.Parameters.Length + arguments.Length;
object[] newArguments = new object[argumentsSize];
for (int i = 0; i < argumentsSize; i++)
{
if (i < registration.Parameters.Length) //if `i` is bigger than the length of the parameters, take the given arguments
{
object currentParameter = registration.Parameters[i];
if (!(currentParameter is InternalResolvePlaceholder)) //use the parameter at the current index if it is not a placeholder
{
newArguments[i] = currentParameter;
continue;
}
}
object firstArgument = arguments.FirstOrGiven<object, InternalResolvePlaceholder>(a => !(a is InternalResolvePlaceholder)); //find the first argument that is not a placeholder
if (firstArgument is InternalResolvePlaceholder) //no more arguments available
break; //there won't be any more arguments
newArguments[i] = firstArgument;
int indexOfFirstArgument = Array.IndexOf(arguments, firstArgument);
arguments[indexOfFirstArgument] = new InternalResolvePlaceholder();
}
arguments = newArguments;
}
else //no more arguments were passed to resolve -> only use parameters set during registration
arguments = registration.Parameters;
return arguments;
}
/// <summary>
/// Resolve the missing constructor arguments
/// </summary>
@ -432,13 +503,5 @@ namespace LightweightIocContainer
_singletons.Clear();
_multitons.Clear();
}
/// <summary>
/// An internal placeholder that is used during the resolving process
/// </summary>
private class InternalResolvePlaceholder
{
}
}
}

@ -7,7 +7,7 @@ using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer
{
/// <summary>
/// The Lifestyles that can be used for a <see cref="IDefaultRegistration{TInterface}"/>
/// The Lifestyles that can be used for a <see cref="IRegistrationBase{TInterface}"/>
/// </summary>
public enum Lifestyle
{

@ -222,12 +222,12 @@
</member>
<member name="T:LightweightIocContainer.Exceptions.UnknownRegistrationException">
<summary>
An unknown <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> was used
An unknown <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> was used
</summary>
</member>
<member name="M:LightweightIocContainer.Exceptions.UnknownRegistrationException.#ctor(System.String)">
<summary>
An unknown <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> was used
An unknown <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> was used
</summary>
<param name="message">The exception message</param>
</member>
@ -295,7 +295,7 @@
</member>
<member name="T:LightweightIocContainer.Interfaces.IIocContainer">
<summary>
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>s and can resolve all the types you'll ever want
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s and can resolve all the types you'll ever want
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Install(LightweightIocContainer.Interfaces.Installers.IIocInstaller[])">
@ -311,16 +311,16 @@
</summary>
<typeparam name="TInterface">The Interface to register</typeparam>
<typeparam name="TImplementation">The Type that implements the interface</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``1(LightweightIocContainer.Lifestyle)">
<summary>
Register a <see cref="T:System.Type"/> without an interface
</summary>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> to register</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``3">
<summary>
@ -329,14 +329,14 @@
<typeparam name="TInterface">The Interface to register</typeparam>
<typeparam name="TImplementation">The Type that implements the interface</typeparam>
<typeparam name="TScope">The Type of the multiton scope</typeparam>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.RegisterFactory``1">
<summary>
Register an Interface as an abstract typed factory
</summary>
<typeparam name="TFactory">The abstract typed factory to register</typeparam>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.RegisterUnitTestCallback``1(LightweightIocContainer.ResolveCallback{``0})">
<summary>
@ -344,7 +344,7 @@
</summary>
<typeparam name="TInterface">The Interface to register</typeparam>
<param name="unitTestCallback">The <see cref="T:LightweightIocContainer.ResolveCallback`1"/> for the callback</param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1">
<summary>
@ -391,65 +391,113 @@
</member>
<member name="M:LightweightIocContainer.Interfaces.Installers.IIocInstaller.Install(LightweightIocContainer.Interfaces.IIocContainer)">
<summary>
Install the needed <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>s in the given <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/>
Install the needed <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s in the given <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/>
</summary>
<param name="container">The current <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/></param>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1">
<summary>
The default registration that is used to register a <see cref="T:System.Type"/> for the Interface it implements
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/> to register a <see cref="T:System.Type"/> for the Interface it implements
</summary>
<typeparam name="TInterface">The registered Interface</typeparam>
<typeparam name="TInterface">The <see cref="T:System.Type"/> of the interface</typeparam>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1.ImplementationType">
<summary>
The <see cref="T:System.Type"/> that implements the <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase.InterfaceType"/> that is registered with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/>
The <see cref="T:System.Type"/> that implements the <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/> that is registered with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IMultitonRegistration`1">
<summary>
The registration that is used to register a multiton
</summary>
<typeparam name="TInterface">The registered interface</typeparam>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IMultitonRegistration`1.Scope">
<summary>
The <see cref="T:System.Type"/> of the multiton scope
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IRegistration">
<summary>
The base registration that is used to register an Interface
</summary>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.Name">
<summary>
The name of the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType">
<summary>
The <see cref="T:System.Type"/> of the Interface that is registered with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1">
<summary>
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/> that is used to register an Interface
</summary>
<typeparam name="TInterface">The registered Interface</typeparam>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1.Lifestyle">
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Lifestyle">
<summary>
The Lifestyle of Instances that are created with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/>
The Lifestyle of Instances that are created with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1.OnCreateAction">
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.OnCreateAction">
<summary>
This <see cref="T:System.Action`1"/> is invoked when an instance of this type is created.
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1.OnCreate(System.Action{`0})"/></para>
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.OnCreate(System.Action{`0})"/></para>
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1.OnCreate(System.Action{`0})">
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.OnCreate(System.Action{`0})">
<summary>
Pass an <see cref="T:System.Action`1"/> that will be invoked when an instance of this type is created
</summary>
<param name="action">The <see cref="T:System.Action`1"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></returns>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IMultitonRegistration`1">
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Parameters">
<summary>
The registration that is used to register a multiton
An <see cref="T:System.Array"/> of parameters that are used to <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.WithParameters(System.Object[])"/></para>
</summary>
<typeparam name="TInterface">The registered interface</typeparam>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IMultitonRegistration`1.Scope">
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.WithParameters(System.Object[])">
<summary>
The <see cref="T:System.Type"/> of the multiton scope
Pass parameters that will be used to<see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving</para>
</summary>
<param name="parameters">The parameters</param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException"><see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Parameters"/> are already set or no parameters given</exception>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase">
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.WithParameters(System.ValueTuple{System.Int32,System.Object}[])">
<summary>
The base registration that is used to register an Interface
Pass parameters that will be used to<see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving</para>
</summary>
<param name="parameters">The parameters with their position</param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException"><see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Parameters"/> are already set or no parameters given</exception>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase.Name">
<member name="T:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1">
<summary>
The name of the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/> to register either only an interface or only a <see cref="T:System.Type"/>
</summary>
<typeparam name="T">The <see cref="T:System.Type"/> of the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></typeparam>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase.InterfaceType">
<member name="P:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1.FactoryMethod">
<summary>
The <see cref="T:System.Type"/> of the Interface that is registered with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
<see cref="T:System.Func`2"/> that is invoked instead of creating an instance of this <see cref="T:System.Type"/> the default way
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1.WithFactoryMethod(System.Func{LightweightIocContainer.Interfaces.IIocContainer,`0})">
<summary>
Pass a <see cref="T:System.Func`2"/> that will be invoked instead of creating an instance of this <see cref="T:System.Type"/> the default way
</summary>
<param name="factoryMethod">The <see cref="T:System.Func`2"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.ITypedFactoryRegistration`1">
<summary>
The registration that is used to register an abstract typed factory
@ -463,7 +511,7 @@
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IUnitTestCallbackRegistration`1">
<summary>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
</summary>
<typeparam name="TInterface"></typeparam>
</member>
@ -472,14 +520,19 @@
An <see cref="T:LightweightIocContainer.ResolveCallback`1"/> that is set as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
</summary>
</member>
<member name="T:LightweightIocContainer.InternalResolvePlaceholder">
<summary>
An internal placeholder that is used during the resolving process
</summary>
</member>
<member name="T:LightweightIocContainer.IocContainer">
<summary>
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>s and can resolve all the types you'll ever want
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s and can resolve all the types you'll ever want
</summary>
</member>
<member name="M:LightweightIocContainer.IocContainer.#ctor">
<summary>
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>s and can resolve all the types you'll ever want
The main container that carries all the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s and can resolve all the types you'll ever want
</summary>
</member>
<member name="M:LightweightIocContainer.IocContainer.Install(LightweightIocContainer.Interfaces.Installers.IIocInstaller[])">
@ -495,16 +548,16 @@
</summary>
<typeparam name="TInterface">The Interface to register</typeparam>
<typeparam name="TImplementation">The Type that implements the interface</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``1(LightweightIocContainer.Lifestyle)">
<summary>
Register a <see cref="T:System.Type"/> without an interface
</summary>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> to register</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``3">
<summary>
@ -513,14 +566,14 @@
<typeparam name="TInterface">The Interface to register</typeparam>
<typeparam name="TImplementation">The Type that implements the interface</typeparam>
<typeparam name="TScope">The Type of the multiton scope</typeparam>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterFactory``1">
<summary>
Register an Interface as an abstract typed factory
</summary>
<typeparam name="TFactory">The abstract typed factory to register</typeparam>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterUnitTestCallback``1(LightweightIocContainer.ResolveCallback{``0})">
<summary>
@ -528,13 +581,13 @@
</summary>
<typeparam name="TInterface">The Interface to register</typeparam>
<param name="unitTestCallback">The <see cref="T:LightweightIocContainer.ResolveCallback`1"/> for the callback</param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register(LightweightIocContainer.Interfaces.Registrations.IRegistrationBase)">
<member name="M:LightweightIocContainer.IocContainer.Register(LightweightIocContainer.Interfaces.Registrations.IRegistration)">
<summary>
Add the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> to the the <see cref="T:LightweightIocContainer.IocContainer"/>
Add the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> to the the <see cref="T:LightweightIocContainer.IocContainer"/>
</summary>
<param name="registration">The given <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></param>
<param name="registration">The given <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<exception cref="T:LightweightIocContainer.Exceptions.MultipleRegistrationException">The <see cref="T:System.Type"/> is already registered in this <see cref="T:LightweightIocContainer.IocContainer"/></exception>
</member>
<member name="M:LightweightIocContainer.IocContainer.Resolve``1">
@ -573,7 +626,7 @@
<exception cref="T:LightweightIocContainer.Exceptions.TypeNotRegisteredException">The given <see cref="T:System.Type"/> is not registered in this <see cref="T:LightweightIocContainer.IocContainer"/></exception>
<exception cref="T:LightweightIocContainer.Exceptions.UnknownRegistrationException">The registration for the given <see cref="T:System.Type"/> has an unknown <see cref="T:System.Type"/></exception>
</member>
<member name="M:LightweightIocContainer.IocContainer.GetOrCreateSingletonInstance``1(LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration{``0},System.Object[],System.Collections.Generic.List{System.Type})">
<member name="M:LightweightIocContainer.IocContainer.GetOrCreateSingletonInstance``1(LightweightIocContainer.Interfaces.Registrations.IRegistrationBase{``0},System.Object[],System.Collections.Generic.List{System.Type})">
<summary>
Gets or creates a singleton instance of a given <see cref="T:System.Type"/>
</summary>
@ -595,7 +648,7 @@
<exception cref="T:LightweightIocContainer.Exceptions.MultitonResolveException">No arguments given</exception>
<exception cref="T:LightweightIocContainer.Exceptions.MultitonResolveException">Scope argument not given</exception>
</member>
<member name="M:LightweightIocContainer.IocContainer.CreateInstance``1(LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration{``0},System.Object[],System.Collections.Generic.List{System.Type})">
<member name="M:LightweightIocContainer.IocContainer.CreateInstance``1(LightweightIocContainer.Interfaces.Registrations.IRegistrationBase{``0},System.Object[],System.Collections.Generic.List{System.Type})">
<summary>
Creates an instance of a given <see cref="T:System.Type"/>
</summary>
@ -605,6 +658,15 @@
<param name="resolveStack">The current resolve stack</param>
<returns>A newly created instance of the given <see cref="T:System.Type"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.UpdateArgumentsWithRegistrationParameters``1(LightweightIocContainer.Interfaces.Registrations.IRegistrationBase{``0},System.Object[])">
<summary>
Update the given arguments with the <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Parameters"/> of the given <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/>
</summary>
<typeparam name="T">The given <see cref="T:System.Type"/></typeparam>
<param name="registration">The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/> of the given <see cref="T:System.Type"/></param>
<param name="arguments">The constructor arguments</param>
<returns>The argument list updated with the <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1.Parameters"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.ResolveConstructorArguments(System.Type,System.Object[],System.Collections.Generic.List{System.Type})">
<summary>
Resolve the missing constructor arguments
@ -633,14 +695,9 @@
The <see cref="M:System.IDisposable.Dispose"/> method
</summary>
</member>
<member name="T:LightweightIocContainer.IocContainer.InternalResolvePlaceholder">
<summary>
An internal placeholder that is used during the resolving process
</summary>
</member>
<member name="T:LightweightIocContainer.Lifestyle">
<summary>
The Lifestyles that can be used for a <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/>
The Lifestyles that can be used for a <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/>
</summary>
</member>
<member name="F:LightweightIocContainer.Lifestyle.Transient">
@ -660,73 +717,110 @@
</member>
<member name="T:LightweightIocContainer.Registrations.DefaultRegistration`1">
<summary>
The default registration that is used to register a <see cref="T:System.Type"/> for the Interface it implements
The <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/> to register a <see cref="T:System.Type"/> for the Interface it implements
</summary>
<typeparam name="TInterface">The registered Interface</typeparam>
<typeparam name="TInterface">The <see cref="T:System.Type"/> of the interface</typeparam>
</member>
<member name="M:LightweightIocContainer.Registrations.DefaultRegistration`1.#ctor(System.Type,System.Type,LightweightIocContainer.Lifestyle)">
<summary>
The default registration that is used to register a <see cref="T:System.Type"/> for the Interface it implements
The <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/> to register a <see cref="T:System.Type"/> for the Interface it implements
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the interface</param>
<param name="implementationType">The <see cref="T:System.Type"/> of the implementation</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> of the <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/></param>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.ImplementationType">
<summary>
The <see cref="T:System.Type"/> that implements the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase`1.InterfaceType"/> that is registered with this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Registrations.MultitonRegistration`1">
<summary>
The registration that is used to register a multiton
</summary>
<typeparam name="TInterface">The registered interface</typeparam>
</member>
<member name="M:LightweightIocContainer.Registrations.MultitonRegistration`1.#ctor(System.Type,System.Type,System.Type)">
<summary>
The registration that is used to register a multiton
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the Interface</param>
<param name="implementationType">The <see cref="T:System.Type"/> of the Implementation</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> of the registration</param>
<param name="scope">The <see cref="T:System.Type"/> of the Multiton Scope</param>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.Name">
<member name="P:LightweightIocContainer.Registrations.MultitonRegistration`1.Scope">
<summary>
The name of the <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/>
The <see cref="T:System.Type"/> of the multiton scope
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.InterfaceType">
<member name="T:LightweightIocContainer.Registrations.RegistrationBase`1">
<summary>
The <see cref="T:System.Type"/> of the Interface that is registered with this <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/>
The <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/> that is used to register an Interface
</summary>
<typeparam name="TInterface">The registered Interface</typeparam>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.ImplementationType">
<member name="M:LightweightIocContainer.Registrations.RegistrationBase`1.#ctor(System.Type,LightweightIocContainer.Lifestyle)">
<summary>
The <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/> that is used to register an Interface
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the Interface</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> of the registration</param>
</member>
<member name="P:LightweightIocContainer.Registrations.RegistrationBase`1.Name">
<summary>
The name of the <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.RegistrationBase`1.InterfaceType">
<summary>
The <see cref="T:System.Type"/> that implements the <see cref="P:LightweightIocContainer.Registrations.DefaultRegistration`1.InterfaceType"/> that is registered with this <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/>
The <see cref="T:System.Type"/> of the Interface that is registered with this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.Lifestyle">
<member name="P:LightweightIocContainer.Registrations.RegistrationBase`1.Lifestyle">
<summary>
The <see cref="T:LightweightIocContainer.Lifestyle"/> of Instances that are created with this <see cref="T:LightweightIocContainer.Registrations.DefaultRegistration`1"/>
The <see cref="T:LightweightIocContainer.Lifestyle"/> of Instances that are created with this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.DefaultRegistration`1.OnCreateAction">
<member name="P:LightweightIocContainer.Registrations.RegistrationBase`1.OnCreateAction">
<summary>
This <see cref="T:System.Action`1"/> is invoked when an instance of this type is created.
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Registrations.DefaultRegistration`1.OnCreate(System.Action{`0})"/></para>
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Registrations.RegistrationBase`1.OnCreate(System.Action{`0})"/></para>
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.DefaultRegistration`1.OnCreate(System.Action{`0})">
<member name="M:LightweightIocContainer.Registrations.RegistrationBase`1.OnCreate(System.Action{`0})">
<summary>
Pass an <see cref="T:System.Action`1"/> that will be invoked when an instance of this <see cref="T:System.Type"/> is created
</summary>
<param name="action">The <see cref="T:System.Action`1"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></returns>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
</member>
<member name="T:LightweightIocContainer.Registrations.MultitonRegistration`1">
<member name="P:LightweightIocContainer.Registrations.RegistrationBase`1.Parameters">
<summary>
The registration that is used to register a multiton
An <see cref="T:System.Array"/> of parameters that are used to <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Registrations.RegistrationBase`1.WithParameters(System.Object[])"/></para>
</summary>
<typeparam name="TInterface">The registered interface</typeparam>
</member>
<member name="M:LightweightIocContainer.Registrations.MultitonRegistration`1.#ctor(System.Type,System.Type,System.Type)">
<member name="M:LightweightIocContainer.Registrations.RegistrationBase`1.WithParameters(System.Object[])">
<summary>
The registration that is used to register a multiton
Pass parameters that will be used to<see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving</para>
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the Interface</param>
<param name="implementationType">The <see cref="T:System.Type"/> of the Implementation</param>
<param name="scope">The <see cref="T:System.Type"/> of the Multiton Scope</param>
<param name="parameters">The parameters</param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException"><see cref="P:LightweightIocContainer.Registrations.RegistrationBase`1.Parameters"/> are already set or no parameters given</exception>
</member>
<member name="P:LightweightIocContainer.Registrations.MultitonRegistration`1.Scope">
<member name="M:LightweightIocContainer.Registrations.RegistrationBase`1.WithParameters(System.ValueTuple{System.Int32,System.Object}[])">
<summary>
The <see cref="T:System.Type"/> of the multiton scope
Pass parameters that will be used to<see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
<para>Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving</para>
</summary>
<param name="parameters">The parameters with their position</param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException"><see cref="P:LightweightIocContainer.Registrations.RegistrationBase`1.Parameters"/> are already set or no parameters given</exception>
</member>
<member name="T:LightweightIocContainer.Registrations.RegistrationFactory">
<summary>
A factory to register interfaces and factories in an <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> and create the needed <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>s
A factory to register interfaces and factories in an <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> and create the needed <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationFactory.Register``2(LightweightIocContainer.Lifestyle)">
@ -740,11 +834,11 @@
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationFactory.Register``1(LightweightIocContainer.Lifestyle)">
<summary>
Register a <see cref="T:System.Type"/> without an interface and create a <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/>
Register a <see cref="T:System.Type"/> without an interface and create a <see cref="T:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1"/>
</summary>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> to register</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/></param>
<returns>A new created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IDefaultRegistration`1"/> with the given parameters</returns>
<typeparam name="T">The <see cref="T:System.Type"/> to register</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1"/></param>
<returns>A new created <see cref="T:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1"/> with the given parameters</returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationFactory.Register``3">
<summary>
@ -762,6 +856,31 @@
<typeparam name="TFactory">The abstract typed factory to register</typeparam>
<returns>A new created <see cref="T:LightweightIocContainer.Interfaces.Registrations.ITypedFactoryRegistration`1"/> with the given parameters</returns>
</member>
<member name="T:LightweightIocContainer.Registrations.SingleTypeRegistration`1">
<summary>
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/> to register either only an interface or only a <see cref="T:System.Type"/>
</summary>
<typeparam name="T">The <see cref="T:System.Type"/> of the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></typeparam>
</member>
<member name="M:LightweightIocContainer.Registrations.SingleTypeRegistration`1.#ctor(System.Type,LightweightIocContainer.Lifestyle)">
<summary>
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/> to register either only an interface or only a <see cref="T:System.Type"/>
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the interface or <see cref="T:System.Type"/></param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> of the <see cref="T:LightweightIocContainer.Registrations.RegistrationBase`1"/></param>
</member>
<member name="P:LightweightIocContainer.Registrations.SingleTypeRegistration`1.FactoryMethod">
<summary>
<see cref="T:System.Func`2"/> that is invoked instead of creating an instance of this <see cref="T:System.Type"/> the default way
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.SingleTypeRegistration`1.WithFactoryMethod(System.Func{LightweightIocContainer.Interfaces.IIocContainer,`0})">
<summary>
Pass a <see cref="T:System.Func`2"/> that will be invoked instead of creating an instance of this <see cref="T:System.Type"/> the default way
</summary>
<param name="factoryMethod">The <see cref="T:System.Func`2"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase`1"/></returns>
</member>
<member name="T:LightweightIocContainer.Registrations.TypedFactoryRegistration`1">
<summary>
The registration that is used to register an abstract typed factory
@ -799,13 +918,13 @@
</member>
<member name="T:LightweightIocContainer.Registrations.UnitTestCallbackRegistration`1">
<summary>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
</summary>
<typeparam name="TInterface"></typeparam>
</member>
<member name="M:LightweightIocContainer.Registrations.UnitTestCallbackRegistration`1.#ctor(System.Type,LightweightIocContainer.ResolveCallback{`0})">
<summary>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
A special <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> that allows to set a <see cref="T:LightweightIocContainer.ResolveCallback`1"/> as a callback that is called on <see cref="M:LightweightIocContainer.Interfaces.IIocContainer.Resolve``1"/>
</summary>
<param name="interfaceType">The <see cref="T:System.Type"/> of the interface</param>
<param name="unitTestResolveCallback">The <see cref="T:LightweightIocContainer.ResolveCallback`1"/> that is set as a callback</param>

@ -1,71 +1,34 @@
// Author: simon.gockner
// Created: 2019-05-20
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations
{
/// <summary>
/// The default registration that is used to register a <see cref="Type"/> for the Interface it implements
/// The <see cref="DefaultRegistration{TInterface}"/> to register a <see cref="Type"/> for the Interface it implements
/// </summary>
/// <typeparam name="TInterface">The registered Interface</typeparam>
public class DefaultRegistration<TInterface> : IDefaultRegistration<TInterface>
/// <typeparam name="TInterface">The <see cref="Type"/> of the interface</typeparam>
public class DefaultRegistration<TInterface> : RegistrationBase<TInterface>, IDefaultRegistration<TInterface>
{
/// <summary>
/// The default registration that is used to register a <see cref="Type"/> for the Interface it implements
/// The <see cref="DefaultRegistration{TInterface}"/> to register a <see cref="Type"/> for the Interface it implements
/// </summary>
/// <param name="interfaceType">The <see cref="Type"/> of the Interface</param>
/// <param name="implementationType">The <see cref="Type"/> of the Implementation</param>
/// <param name="lifestyle">The <see cref="LightweightIocContainer.Lifestyle"/> of the registration</param>
/// <param name="interfaceType">The <see cref="Type"/> of the interface</param>
/// <param name="implementationType">The <see cref="Type"/> of the implementation</param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> of the <see cref="RegistrationBase{TInterface}"/></param>
public DefaultRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle)
: base(interfaceType, lifestyle)
{
InterfaceType = interfaceType;
ImplementationType = implementationType;
Lifestyle = lifestyle;
Name = $"{InterfaceType.Name}, {ImplementationType.Name}, Lifestyle: {Lifestyle.ToString()}";
}
/// <summary>
/// The name of the <see cref="DefaultRegistration{TInterface}"/>
/// </summary>
public string Name { get; }
/// <summary>
/// The <see cref="Type"/> of the Interface that is registered with this <see cref="DefaultRegistration{TInterface}"/>
/// </summary>
public Type InterfaceType { get; }
/// <summary>
/// The <see cref="Type"/> that implements the <see cref="InterfaceType"/> that is registered with this <see cref="DefaultRegistration{TInterface}"/>
/// The <see cref="Type"/> that implements the <see cref="RegistrationBase{TInterface}.InterfaceType"/> that is registered with this <see cref="RegistrationBase{TInterface}"/>
/// </summary>
public Type ImplementationType { get; }
/// <summary>
/// The <see cref="LightweightIocContainer.Lifestyle"/> of Instances that are created with this <see cref="DefaultRegistration{TInterface}"/>
/// </summary>
public Lifestyle Lifestyle { get; }
/// <summary>
/// This <see cref="Action{T}"/> is invoked when an instance of this type is created.
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="OnCreate"/></para>
/// </summary>
public Action<TInterface> OnCreateAction { get; private set; }
/// <summary>
/// Pass an <see cref="Action{T}"/> that will be invoked when an instance of this <see cref="Type"/> is created
/// </summary>
/// <param name="action">The <see cref="Action{T}"/></param>
/// <returns>The current instance of this <see cref="IDefaultRegistration{TInterface}"/></returns>
public IDefaultRegistration<TInterface> OnCreate(Action<TInterface> action)
{
OnCreateAction = action;
return this;
}
}
}

@ -0,0 +1,119 @@
// Author: simon.gockner
// Created: 2019-05-20
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using System.Linq;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations
{
/// <summary>
/// The <see cref="RegistrationBase{TInterface}"/> that is used to register an Interface
/// </summary>
/// <typeparam name="TInterface">The registered Interface</typeparam>
public abstract class RegistrationBase<TInterface> : IRegistrationBase<TInterface>
{
/// <summary>
/// The <see cref="RegistrationBase{TInterface}"/> that is used to register an Interface
/// </summary>
/// <param name="interfaceType">The <see cref="Type"/> of the Interface</param>
/// <param name="lifestyle">The <see cref="LightweightIocContainer.Lifestyle"/> of the registration</param>
protected RegistrationBase(Type interfaceType, Lifestyle lifestyle)
{
InterfaceType = interfaceType;
Lifestyle = lifestyle;
}
/// <summary>
/// The name of the <see cref="RegistrationBase{TInterface}"/>
/// </summary>
public string Name { get; protected set; }
/// <summary>
/// The <see cref="Type"/> of the Interface that is registered with this <see cref="RegistrationBase{TInterface}"/>
/// </summary>
public Type InterfaceType { get; }
/// <summary>
/// The <see cref="LightweightIocContainer.Lifestyle"/> of Instances that are created with this <see cref="RegistrationBase{TInterface}"/>
/// </summary>
public Lifestyle Lifestyle { get; }
/// <summary>
/// This <see cref="Action{T}"/> is invoked when an instance of this type is created.
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="OnCreate"/></para>
/// </summary>
public Action<TInterface> OnCreateAction { get; private set; }
/// <summary>
/// Pass an <see cref="Action{T}"/> that will be invoked when an instance of this <see cref="Type"/> is created
/// </summary>
/// <param name="action">The <see cref="Action{T}"/></param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
public IRegistrationBase<TInterface> OnCreate(Action<TInterface> action)
{
OnCreateAction = action;
return this;
}
/// <summary>
/// An <see cref="Array"/> of parameters that are used to <see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Can be set in the <see cref="IIocInstaller"/> by calling <see cref="WithParameters(object[])"/></para>
/// </summary>
public object[] Parameters { get; private set; }
/// <summary>
/// Pass parameters that will be used to<see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving</para>
/// </summary>
/// <param name="parameters">The parameters</param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
/// <exception cref="InvalidRegistrationException"><see cref="Parameters"/> are already set or no parameters given</exception>
public IRegistrationBase<TInterface> WithParameters(params object[] parameters)
{
if (Parameters != null)
throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType}).");
if (parameters == null || !parameters.Any())
throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType}).");
Parameters = parameters;
return this;
}
/// <summary>
/// Pass parameters that will be used to<see cref="IIocContainer.Resolve{T}()"/> an instance of this <see cref="IRegistration.InterfaceType"/>
/// <para>Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving</para>
/// </summary>
/// <param name="parameters">The parameters with their position</param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
/// <exception cref="InvalidRegistrationException"><see cref="Parameters"/> are already set or no parameters given</exception>
public IRegistrationBase<TInterface> WithParameters(params (int index, object parameter)[] parameters)
{
if (Parameters != null)
throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType}).");
if (parameters == null || !parameters.Any())
throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType}).");
var lastIndex = parameters.Max(p => p.index);
Parameters = new object[lastIndex + 1];
for (int i = 0; i < Parameters.Length; i++)
{
if (parameters.Any(p => p.index == i))
Parameters[i] = parameters.First(p => p.index == i).parameter;
else
Parameters[i] = new InternalResolvePlaceholder();
}
return this;
}
}
}

@ -3,7 +3,6 @@
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
@ -11,7 +10,7 @@ using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations
{
/// <summary>
/// A factory to register interfaces and factories in an <see cref="IIocInstaller"/> and create the needed <see cref="IRegistrationBase"/>s
/// A factory to register interfaces and factories in an <see cref="IIocInstaller"/> and create the needed <see cref="IRegistration"/>s
/// </summary>
internal class RegistrationFactory
{
@ -35,17 +34,14 @@ namespace LightweightIocContainer.Registrations
}
/// <summary>
/// Register a <see cref="Type"/> without an interface and create a <see cref="IDefaultRegistration{TInterface}"/>
/// Register a <see cref="Type"/> without an interface and create a <see cref="ISingleTypeRegistration{TInterface}"/>
/// </summary>
/// <typeparam name="TImplementation">The <see cref="Type"/> to register</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IDefaultRegistration{TInterface}"/></param>
/// <returns>A new created <see cref="IDefaultRegistration{TInterface}"/> with the given parameters</returns>
public IDefaultRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle)
/// <typeparam name="T">The <see cref="Type"/> to register</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="ISingleTypeRegistration{TInterface}"/></param>
/// <returns>A new created <see cref="ISingleTypeRegistration{TInterface}"/> with the given parameters</returns>
public ISingleTypeRegistration<T> Register<T>(Lifestyle lifestyle)
{
if (typeof(TImplementation).IsInterface)
throw new InvalidRegistrationException("Can't register an interface without its implementation type.");
return Register<TImplementation, TImplementation>(lifestyle);
return new SingleTypeRegistration<T>(typeof(T), lifestyle);
}
/// <summary>
@ -70,6 +66,7 @@ namespace LightweightIocContainer.Registrations
return new TypedFactoryRegistration<TFactory>(typeof(TFactory), _iocContainer);
}
[Obsolete("RegisterUnitTestCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public IUnitTestCallbackRegistration<TInterface> RegisterUnitTestCallback<TInterface>(ResolveCallback<TInterface> unitTestResolveCallback)
{
return new UnitTestCallbackRegistration<TInterface>(typeof(TInterface), unitTestResolveCallback);

@ -0,0 +1,44 @@
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations
{
/// <summary>
/// The <see cref="IRegistrationBase{TInterface}"/> to register either only an interface or only a <see cref="Type"/>
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the <see cref="IRegistrationBase{TInterface}"/></typeparam>
public class SingleTypeRegistration<T> : RegistrationBase<T>, ISingleTypeRegistration<T>
{
/// <summary>
/// The <see cref="IRegistrationBase{TInterface}"/> to register either only an interface or only a <see cref="Type"/>
/// </summary>
/// <param name="interfaceType">The <see cref="Type"/> of the interface or <see cref="Type"/></param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> of the <see cref="RegistrationBase{TInterface}"/></param>
public SingleTypeRegistration(Type interfaceType, Lifestyle lifestyle)
: base(interfaceType, lifestyle)
{
Name = $"{InterfaceType.Name}, Lifestyle: {Lifestyle.ToString()}";
}
/// <summary>
/// <see cref="Func{T,TResult}"/> that is invoked instead of creating an instance of this <see cref="Type"/> the default way
/// </summary>
public Func<IIocContainer, T> FactoryMethod { get; private set; }
/// <summary>
/// Pass a <see cref="Func{T,TResult}"/> that will be invoked instead of creating an instance of this <see cref="Type"/> the default way
/// </summary>
/// <param name="factoryMethod">The <see cref="Func{T,TResult}"/></param>
/// <returns>The current instance of this <see cref="IRegistrationBase{TInterface}"/></returns>
public ISingleTypeRegistration<T> WithFactoryMethod(Func<IIocContainer, T> factoryMethod)
{
FactoryMethod = factoryMethod;
return this;
}
}
}

@ -9,13 +9,14 @@ using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations
{
/// <summary>
/// A special <see cref="IRegistrationBase"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// A special <see cref="IRegistration"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// </summary>
/// <typeparam name="TInterface"></typeparam>
[Obsolete("UnitTestCallbackRegistration is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public class UnitTestCallbackRegistration<TInterface> : IUnitTestCallbackRegistration<TInterface>
{
/// <summary>
/// A special <see cref="IRegistrationBase"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// A special <see cref="IRegistration"/> that allows to set a <see cref="ResolveCallback{T}"/> as a callback that is called on <see cref="IIocContainer.Resolve{T}()"/>
/// </summary>
/// <param name="interfaceType">The <see cref="Type"/> of the interface</param>
/// <param name="unitTestResolveCallback">The <see cref="ResolveCallback{T}"/> that is set as a callback</param>

@ -25,7 +25,7 @@ namespace Test.LightweightIocContainer
{
public void Install(IIocContainer container)
{
container.Register<Mock<IRegistrationBase>>();
container.Register<Mock<IRegistration>>();
}
}
@ -54,7 +54,7 @@ namespace Test.LightweightIocContainer
AssemblyInstaller assemblyInstaller = new AssemblyInstaller(assemblyMock.Object);
assemblyInstaller.Install(iocContainerMock.Object);
iocContainerMock.Verify(ioc => ioc.Register<It.IsSubtype<Mock<IRegistrationBase>>>(It.IsAny<Lifestyle>()), Times.Once);
iocContainerMock.Verify(ioc => ioc.Register<It.IsSubtype<Mock<IRegistration>>>(It.IsAny<Lifestyle>()), Times.Once);
}
[Test]

@ -1,47 +0,0 @@
// Author: Gockner, Simon
// Created: 2019-06-06
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
using LightweightIocContainer.Registrations;
using Moq;
using NUnit.Framework;
namespace Test.LightweightIocContainer
{
[TestFixture]
public class DefaultRegistrationTest
{
#region TestClasses
private interface ITest
{
void DoSomething();
}
private class Test : ITest
{
public void DoSomething()
{
throw new Exception();
}
}
#endregion
[Test]
public void TestOnCreate()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
IDefaultRegistration<ITest> testRegistration = registrationFactory.Register<ITest, Test>(Lifestyle.Transient).OnCreate(t => t.DoSomething());
ITest test = new Test();
Assert.Throws<Exception>(() => testRegistration.OnCreateAction(test));
}
}
}

@ -0,0 +1,169 @@
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Interfaces;
using NUnit.Framework;
namespace Test.LightweightIocContainer
{
[TestFixture]
// ReSharper disable MemberHidesStaticFromOuterClass
public class IocContainerParameterRegistrationTest
{
#region TestClasses
[UsedImplicitly]
public interface IA
{
IB B { get; }
IC C { get; }
}
[UsedImplicitly]
public interface IB
{
}
[UsedImplicitly]
public interface IC
{
}
[UsedImplicitly]
public interface ID
{
IA A { get; }
IA A2 { get; }
IB B { get; }
IC C { get; }
}
[UsedImplicitly]
private class A : IA
{
public A(IB b, IC c)
{
B = b;
C = c;
}
public IB B { get; }
public IC C { get; }
}
[UsedImplicitly]
private class B : IB
{
public B(IC c)
{
}
}
[UsedImplicitly]
private class C : IC
{
}
[UsedImplicitly]
private class D : ID
{
public D(IA a, IA a2, IB b, IC c)
{
A = a;
A2 = a2;
B = b;
C = c;
}
public IA A { get; }
public IA A2 { get; }
public IB B { get; }
public IC C { get; }
}
#endregion TestClasses
private IIocContainer _iocContainer;
[SetUp]
public void SetUp()
{
_iocContainer = new IocContainer();
}
[TearDown]
public void TearDown()
{
_iocContainer.Dispose();
}
[Test]
public void TestResolveOnlyRegistrationParameters()
{
IC c = new C();
IB b = new B(c);
_iocContainer.Register<IA, A>().WithParameters(b, c);
IA a = _iocContainer.Resolve<IA>();
Assert.AreEqual(b, a.B);
Assert.AreEqual(c, a.C);
}
[Test]
public void TestResolveRegistrationAndResolveParameters()
{
IC c = new C();
IB b = new B(c);
_iocContainer.Register<IA, A>().WithParameters(b);
IA a = _iocContainer.Resolve<IA>(c);
Assert.AreEqual(b, a.B);
Assert.AreEqual(c, a.C);
}
[Test]
public void TestResolveRegistrationAndResolveParametersMixedOrder()
{
IC c = new C();
IB b = new B(c);
IA a = new A(b, c);
IA a2 = new A(b, c);
_iocContainer.Register<ID, D>().WithParameters((0, a), (2, b), (3, c));
ID d = _iocContainer.Resolve<ID>(a2);
Assert.AreEqual(a, d.A);
Assert.AreEqual(a2, d.A2);
Assert.AreEqual(b, d.B);
Assert.AreEqual(c, d.C);
}
[Test]
public void TestResolveRegistrationParametersAndResolvedParameters()
{
IC c = new C();
IB b = new B(c);
IA a = new A(b, c);
IA a2 = new A(b, c);
_iocContainer.Register<ID, D>().WithParameters(a2);
_iocContainer.Register<IB, B>();
_iocContainer.Register<IC, C>();
ID d = _iocContainer.Resolve<ID>(a);
Assert.AreEqual(a, d.A2);
Assert.AreEqual(a2, d.A);
}
}
}

@ -1,3 +1,4 @@
using System;
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Exceptions;
@ -43,6 +44,11 @@ namespace Test.LightweightIocContainer
void ClearMultitonInstance();
}
private interface IFoo
{
}
private class Test : ITest
{
@ -60,6 +66,11 @@ namespace Test.LightweightIocContainer
{
}
public TestConstructor(IFoo foo, string name)
{
}
}
[UsedImplicitly]
@ -83,6 +94,12 @@ namespace Test.LightweightIocContainer
}
}
[UsedImplicitly]
private class Foo : IFoo
{
}
public class MultitonScope
{
@ -166,12 +183,6 @@ namespace Test.LightweightIocContainer
Assert.AreEqual(typeof(ITest), exception.Type);
}
[Test]
public void TestRegisterInterfaceWithoutImplementation()
{
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register<ITest>());
}
[Test]
public void TestRegisterFactoryWithoutCreate()
{
@ -185,6 +196,7 @@ namespace Test.LightweightIocContainer
}
[Test]
[Obsolete("RegisterUnitTestCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public void TestRegisterUnitTestCallback()
{
Assert.DoesNotThrow(() => _iocContainer.RegisterUnitTestCallback<ITest>(delegate {return new Test(); }));
@ -217,6 +229,13 @@ namespace Test.LightweightIocContainer
Assert.IsInstanceOf<Test>(resolvedTest);
}
[Test]
public void TestResolveInterfaceWithoutImplementation()
{
_iocContainer.Register<ITest>();
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Resolve<ITest>());
}
[Test]
public void TestResolveWithParams()
{
@ -435,6 +454,7 @@ namespace Test.LightweightIocContainer
}
[Test]
[Obsolete("RegisterUnitTestCallback is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public void TestResolveUnitTestCallbackRegistration()
{
ITest callbackTest = new Test();
@ -445,6 +465,17 @@ namespace Test.LightweightIocContainer
Assert.AreEqual(callbackTest, test);
}
[Test]
public void TestResolveSingleTypeRegistrationWithFactoryMethod()
{
_iocContainer.Register<IFoo, Foo>();
_iocContainer.Register<ITest>().WithFactoryMethod(c => new TestConstructor(c.Resolve<IFoo>(), "someName"));
ITest test = _iocContainer.Resolve<ITest>();
Assert.NotNull(test);
}
[Test]
public void TestIsTypeRegistered()
{

@ -0,0 +1,119 @@
// Author: Gockner, Simon
// Created: 2019-06-06
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
using LightweightIocContainer.Registrations;
using Moq;
using NUnit.Framework;
namespace Test.LightweightIocContainer
{
[TestFixture]
public class RegistrationBaseTest
{
#region TestClasses
private interface ITest
{
void DoSomething();
}
private interface IFoo
{
}
private interface IBar
{
}
private class Test : ITest
{
public void DoSomething()
{
throw new Exception();
}
}
[UsedImplicitly]
private class Foo : IFoo
{
public Foo(IBar bar, ITest test)
{
}
}
private class Bar : IBar
{
}
#endregion
[Test]
public void TestOnCreate()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
IRegistrationBase<ITest> testRegistration = registrationFactory.Register<ITest, Test>(Lifestyle.Transient).OnCreate(t => t.DoSomething());
ITest test = new Test();
Assert.Throws<Exception>(() => testRegistration.OnCreateAction(test));
}
[Test]
public void TestWithParameters()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
IBar bar = new Bar();
ITest test = new Test();
IRegistrationBase<IFoo> testRegistration = registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters(bar, test);
Assert.AreEqual(bar, testRegistration.Parameters[0]);
Assert.AreEqual(test, testRegistration.Parameters[1]);
}
[Test]
public void TestWithParametersDifferentOrder()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
IBar bar = new Bar();
ITest test = new Test();
IRegistrationBase<IFoo> testRegistration = registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters((0, bar), (3, test), (2, "SomeString"));
Assert.AreEqual(bar, testRegistration.Parameters[0]);
Assert.IsInstanceOf<InternalResolvePlaceholder>(testRegistration.Parameters[1]);
Assert.AreEqual("SomeString", testRegistration.Parameters[2]);
Assert.AreEqual(test, testRegistration.Parameters[3]);
}
[Test]
public void TestWithParametersCalledTwice()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
Assert.Throws<InvalidRegistrationException>(() => registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters(new Bar()).WithParameters(new Test()));
Assert.Throws<InvalidRegistrationException>(() => registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters((0, new Bar())).WithParameters((1, new Test())));
}
[Test]
public void TestWithParametersNoParametersGiven()
{
RegistrationFactory registrationFactory = new RegistrationFactory(new Mock<IIocContainer>().Object);
Assert.Throws<InvalidRegistrationException>(() => registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters((object[])null));
Assert.Throws<InvalidRegistrationException>(() => registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters(((int index, object parameter)[])null));
}
}
}

@ -0,0 +1,61 @@
// Author: Gockner, Simon
// Created: 2019-11-22
// Copyright(c) 2019 SimonG. All Rights Reserved.
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
using LightweightIocContainer.Registrations;
using Moq;
using NUnit.Framework;
namespace Test.LightweightIocContainer
{
[TestFixture]
// ReSharper disable MemberHidesStaticFromOuterClass
public class SingleTypeRegistrationTest
{
private interface IFoo
{
IBar Bar { get; }
}
private interface IBar
{
}
[UsedImplicitly]
private class Foo : IFoo
{
public Foo(IBar bar)
{
Bar = bar;
}
public IBar Bar { get; }
}
[UsedImplicitly]
private class Bar : IBar
{
}
[Test]
public void TestSingleTypeRegistrationWithFactoryMethod()
{
IBar bar = new Bar();
Mock<IIocContainer> iocContainerMock = new Mock<IIocContainer>();
iocContainerMock.Setup(c => c.Resolve<IBar>()).Returns(bar);
RegistrationFactory registrationFactory = new RegistrationFactory(iocContainerMock.Object);
ISingleTypeRegistration<IFoo> registration = registrationFactory.Register<IFoo>(Lifestyle.Transient).WithFactoryMethod(c => new Foo(c.Resolve<IBar>()));
IFoo foo = registration.FactoryMethod(iocContainerMock.Object);
Assert.AreEqual(bar, foo.Bar);
}
}
}

@ -2,6 +2,7 @@
// Created: 2019-10-15
// Copyright(c) 2019 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
@ -12,6 +13,7 @@ using NUnit.Framework;
namespace Test.LightweightIocContainer
{
[TestFixture]
[Obsolete("UnitTestCallbackRegistration is deprecated, use `WithFactoryMethod()` from ISingleTypeRegistration instead.")]
public class UnitTestCallbackRegistrationTest
{
private interface ITest

Loading…
Cancel
Save