- completely rework registration:

- creation of registrations is done in registrationCollector now
  - installers don't get container anymore, get registrationCollector
  - allow validation
  - introduce dispose strategies (#55)
pull/57/head
Simon G 4 years ago
parent 73355269e0
commit 3acd6adfea
  1. 29
      LightweightIocContainer/DisposeStrategy.cs
  2. 12
      LightweightIocContainer/EnumerableExtension.cs
  3. 25
      LightweightIocContainer/Exceptions/InvalidDisposeStrategyException.cs
  4. 7
      LightweightIocContainer/Installers/AssemblyInstaller.cs
  5. 91
      LightweightIocContainer/Interfaces/IIocContainer.cs
  6. 4
      LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs
  7. 28
      LightweightIocContainer/Interfaces/Registrations/Fluent/IWithDisposeStrategy.cs
  8. 16
      LightweightIocContainer/Interfaces/Registrations/IInternalValidationProvider.cs
  9. 2
      LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs
  10. 104
      LightweightIocContainer/Interfaces/Registrations/IRegistrationCollector.cs
  11. 207
      LightweightIocContainer/IocContainer.cs
  12. 534
      LightweightIocContainer/LightweightIocContainer.xml
  13. 2
      LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs
  14. 10
      LightweightIocContainer/Registrations/MultipleRegistration.cs
  15. 2
      LightweightIocContainer/Registrations/MultitonRegistration.cs
  16. 17
      LightweightIocContainer/Registrations/OpenGenericRegistration.cs
  17. 78
      LightweightIocContainer/Registrations/RegistrationBase.cs
  18. 188
      LightweightIocContainer/Registrations/RegistrationCollector.cs
  19. 2
      LightweightIocContainer/Registrations/SingleTypeRegistration.cs
  20. 7
      LightweightIocContainer/Registrations/TypedRegistration.cs
  21. 8
      Test.LightweightIocContainer/AssemblyInstallerTest.cs
  22. 91
      Test.LightweightIocContainer/DisposeStrategyTest.cs
  23. 26
      Test.LightweightIocContainer/EnumerableExtensionTest.cs
  24. 30
      Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs
  25. 12
      Test.LightweightIocContainer/IocContainerInterfaceSegregationTest.cs
  26. 12
      Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs
  27. 18
      Test.LightweightIocContainer/IocContainerRecursionTest.cs
  28. 67
      Test.LightweightIocContainer/IocContainerTest.cs
  29. 6
      Test.LightweightIocContainer/IocValidatorTest.cs
  30. 10
      Test.LightweightIocContainer/MultiLayerResolveTest.cs
  31. 6
      Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs
  32. 4
      Test.LightweightIocContainer/OnCreateTest.cs
  33. 8
      Test.LightweightIocContainer/OpenGenericRegistrationTest.cs
  34. 4
      Test.LightweightIocContainer/RegistrationBaseTest.cs
  35. 6
      Test.LightweightIocContainer/SingleTypeRegistrationTest.cs

@ -0,0 +1,29 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer;
/// <summary>
/// The dispose strategy that is used for a singleton or multiton that implements <see cref="IDisposable"/> and is created by the <see cref="IocContainer"/>
/// </summary>
public enum DisposeStrategy
{
/// <summary>
/// No dispose strategy
/// <remarks>Invalid for singletons or multitons that implement <see cref="IDisposable"/></remarks>
/// </summary>
None,
/// <summary>
/// The application is responsible for correctly disposing the instance. Nothing is done by the <see cref="IocContainer"/>
/// </summary>
Application,
/// <summary>
/// The <see cref="IocContainer"/> is responsible for disposing the instance when itself is disposed
/// </summary>
Container
}

@ -50,5 +50,17 @@ namespace LightweightIocContainer
return new TGiven();
}
}
/// <summary>
/// Executes an <see cref="Action{T}"/> for each item in an <see cref="IEnumerable{T}"/>
/// </summary>
/// <param name="enumerable">The <see cref="IEnumerable{T}"/></param>
/// <param name="action">The <see cref="Action{T}"/></param>
/// <typeparam name="T">The <see cref="Type"/> of the items in the <see cref="IEnumerable{T}"/></typeparam>
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (T item in enumerable)
action(item);
}
}
}

@ -0,0 +1,25 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Exceptions;
/// <summary>
/// Invalid <see cref="DisposeStrategy"/> is used
/// </summary>
public class InvalidDisposeStrategyException : IocContainerException
{
/// <summary>
/// Invalid <see cref="DisposeStrategy"/> is used
/// </summary>
/// <param name="disposeStrategy">The <see cref="DisposeStrategy"/></param>
/// <param name="type">The <see cref="Type"/></param>
/// <param name="lifestyle">The <see cref="Lifestyle"/></param>
public InvalidDisposeStrategyException(DisposeStrategy disposeStrategy, Type type, Lifestyle lifestyle)
: base($"Dispose strategy {disposeStrategy} is invalid for the type {type} and lifestyle {lifestyle}.")
{
}
}

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Reflection;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Installers
{
@ -41,11 +42,11 @@ namespace LightweightIocContainer.Installers
/// <summary>
/// Install the found <see cref="IIocInstaller"/>s in the given <see cref="IIocContainer"/>
/// </summary>
/// <param name="container">The current <see cref="IIocContainer"/></param>
public void Install(IIocContainer container)
/// <param name="registration">The <see cref="IRegistrationCollector"/> where <see cref="IRegistration"/>s are added</param>
public void Install(IRegistrationCollector registration)
{
foreach (IIocInstaller installer in Installers)
installer.Install(container);
installer.Install(registration);
}
}
}

@ -20,97 +20,6 @@ namespace LightweightIocContainer.Interfaces
/// <returns>An instance of the current <see cref="IIocContainer"/></returns>
IIocContainer Install(params IIocInstaller[] installers);
/// <summary>
/// Register an Interface with a Type that implements it
/// </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="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
ITypedRegistration<TInterface, TImplementation> Register<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface;
/// <summary>
/// Register an open generic Interface with an open generic Type that implements it
/// </summary>
/// <param name="tInterface">The open generic Interface to register</param>
/// <param name="tImplementation">The open generic Type that implements the interface</param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
IOpenGenericRegistration RegisterOpenGenerics(Type tInterface, Type tImplementation, Lifestyle lifestyle = Lifestyle.Transient);
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TImplementation> Register<TInterface1, TInterface2, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface2, TInterface1;
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> Register<TInterface1, TInterface2, TInterface3, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface3, TInterface2, TInterface1;
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TInterface4">A fourth interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> Register<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1;
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TInterface4">A fourth interface to register</typeparam>
/// <typeparam name="TInterface5">A fifth interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4,TInterface5}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> Register<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1;
/// <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="IRegistration"/></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
/// </summary>
/// <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="IRegistration"/></returns>
IMultitonRegistration<TInterface, TImplementation> RegisterMultiton<TInterface, TImplementation, TScope>() where TImplementation : TInterface;
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them as a multiton
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second 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="IRegistration"/></returns>
IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> RegisterMultiton<TInterface1, TInterface2, TImplementation, TScope>() where TImplementation : TInterface1, TInterface2;
/// <summary>
/// Clear the multiton instances of the given <see cref="Type"/> from the registered multitons list
/// </summary>

@ -14,7 +14,7 @@ namespace LightweightIocContainer.Interfaces.Installers
/// <summary>
/// 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);
/// <param name="registration">The <see cref="IRegistrationCollector"/> where <see cref="IRegistration"/>s are added</param>
void Install(IRegistrationCollector registration);
}
}

@ -0,0 +1,28 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Interfaces.Registrations.Fluent;
/// <summary>
/// Provides a <see cref="LightweightIocContainer.DisposeStrategy"/> to an <see cref="IRegistration"/>
/// </summary>
public interface IWithDisposeStrategy
{
/// <summary>
/// Add a <see cref="DisposeStrategy"/> for the <see cref="IRegistrationBase"/>
/// </summary>
/// <param name="disposeStrategy">The <see cref="DisposeStrategy"/></param>
/// <returns>The current instance of this <see cref="IRegistrationBase"/></returns>
IRegistrationBase WithDisposeStrategy(DisposeStrategy disposeStrategy);
}
internal interface IWithDisposeStrategyInternal : IWithDisposeStrategy
{
/// <summary>
/// The <see cref="LightweightIocContainer.DisposeStrategy"/> of singletons/multitons that implement <see cref="IDisposable"/> and are created with this <see cref="IRegistration"/>
/// </summary>
DisposeStrategy DisposeStrategy { get; }
}

@ -0,0 +1,16 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
namespace LightweightIocContainer.Interfaces.Registrations;
/// <summary>
/// Provides an internal <see cref="Validate"/> method to an <see cref="IRegistrationBase"/>
/// </summary>
internal interface IInternalValidationProvider
{
/// <summary>
/// Validate this <see cref="IRegistrationBase"/>
/// </summary>
void Validate();
}

@ -9,7 +9,7 @@ namespace LightweightIocContainer.Interfaces.Registrations
/// <summary>
/// The <see cref="IRegistrationBase"/> that is used to register an Interface and extends the <see cref="IRegistration"/> with fluent options
/// </summary>
public interface IRegistrationBase : IRegistration, IWithFactory, IWithParameters
public interface IRegistrationBase : IRegistration, IWithFactory, IWithParameters, IWithDisposeStrategy
{
}

@ -0,0 +1,104 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
namespace LightweightIocContainer.Interfaces.Registrations;
/// <summary>
/// Creates and collects the <see cref="IRegistration"/>s
/// </summary>
public interface IRegistrationCollector
{
/// <summary>
/// Add an Interface with a Type that implements it
/// </summary>
/// <typeparam name="TInterface">The Interface to add</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
ITypedRegistration<TInterface, TImplementation> Add<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface;
/// <summary>
/// Add an open generic Interface with an open generic Type that implements it
/// </summary>
/// <param name="tInterface">The open generic Interface to add</param>
/// <param name="tImplementation">The open generic Type that implements the interface</param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
IOpenGenericRegistration AddOpenGenerics(Type tInterface, Type tImplementation, Lifestyle lifestyle = Lifestyle.Transient);
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TImplementation> Add<TInterface1, TInterface2, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface2, TInterface1;
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> Add<TInterface1, TInterface2, TInterface3, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface3, TInterface2, TInterface1;
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TInterface4">A fourth interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> Add<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1;
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TInterface4">A fourth interface to add</typeparam>
/// <typeparam name="TInterface5">A fifth interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4,TInterface5}"/></returns>
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> Add<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1;
/// <summary>
/// Add a <see cref="Type"/> without an interface
/// </summary>
/// <typeparam name="TImplementation">The <see cref="Type"/> to add</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
ISingleTypeRegistration<TImplementation> Add<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient);
/// <summary>
/// Add an Interface with a Type that implements it as a multiton
/// </summary>
/// <typeparam name="TInterface">The Interface to add</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="IRegistration"/></returns>
IMultitonRegistration<TInterface, TImplementation> AddMultiton<TInterface, TImplementation, TScope>() where TImplementation : TInterface;
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them as a multiton
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</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="IRegistration"/></returns>
IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> AddMultiton<TInterface1, TInterface2, TImplementation, TScope>() where TImplementation : TInterface1, TInterface2;
}

@ -47,162 +47,26 @@ namespace LightweightIocContainer
public IIocContainer Install(params IIocInstaller[] installers)
{
foreach (IIocInstaller installer in installers)
installer.Install(this);
return this;
}
/// <summary>
/// Register an Interface with a Type that implements it
/// </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="IRegistrationBase"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public ITypedRegistration<TInterface, TImplementation> Register<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface
{
ITypedRegistration<TInterface, TImplementation> registration = _registrationFactory.Register<TInterface, TImplementation>(lifestyle);
Register(registration);
return registration;
}
/// <summary>
/// Register an open generic Interface with an open generic Type that implements it
/// </summary>
/// <param name="tInterface">The open generic Interface to register</param>
/// <param name="tImplementation">The open generic Type that implements the interface</param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IOpenGenericRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
/// <exception cref="InvalidRegistrationException">Function can only be used to register open generic types</exception>
/// <exception cref="InvalidRegistrationException">Can't register a multiton with open generic registration</exception>
public IOpenGenericRegistration RegisterOpenGenerics(Type tInterface, Type tImplementation, Lifestyle lifestyle = Lifestyle.Transient)
{
if (!tInterface.ContainsGenericParameters)
throw new InvalidRegistrationException("This function can only be used to register open generic types.");
RegistrationCollector registrationCollector = new(_registrationFactory);
installer.Install(registrationCollector);
if (lifestyle == Lifestyle.Multiton)
throw new InvalidRegistrationException("Can't register a multiton with open generic registration."); //TODO: Is there any need for a possibility to register multitons with open generics?
IOpenGenericRegistration registration = _registrationFactory.Register(tInterface, tImplementation, lifestyle);
Register(registration);
return registration;
registrationCollector.Registrations.ForEach(Register);
}
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TImplementation> Register<TInterface1, TInterface2, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> Register<TInterface1, TInterface2, TInterface3, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TInterface4">A fourth interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> Register<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second interface to register</typeparam>
/// <typeparam name="TInterface3">A third interface to register</typeparam>
/// <typeparam name="TInterface4">A fourth interface to register</typeparam>
/// <typeparam name="TInterface5">A fifth interface to register</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistrationBase"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4,TInterface5}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> Register<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <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="IRegistrationBase"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public ISingleTypeRegistration<TImplementation> Register<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient)
{
ISingleTypeRegistration<TImplementation> registration = _registrationFactory.Register<TImplementation>(lifestyle);
Register(registration);
return registration;
}
/// <summary>
/// Register an Interface with a Type that implements it as a multiton
/// </summary>
/// <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="IRegistration"/></returns>
public IMultitonRegistration<TInterface, TImplementation> RegisterMultiton<TInterface, TImplementation, TScope>() where TImplementation : TInterface
{
IMultitonRegistration<TInterface, TImplementation> registration = _registrationFactory.RegisterMultiton<TInterface, TImplementation, TScope>();
Register(registration);
return registration;
return this;
}
/// <summary>
/// Register multiple interfaces for a <see cref="Type"/> that implements them as a multiton
/// Register an <see cref="IRegistration"/> at this <see cref="IocContainer"/>
/// </summary>
/// <typeparam name="TInterface1">The base interface to register</typeparam>
/// <typeparam name="TInterface2">A second 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="IRegistration"/></returns>
public IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> RegisterMultiton<TInterface1, TInterface2, TImplementation, TScope>() where TImplementation : TInterface1, TInterface2
/// <param name="addRegistration">The <see cref="Func{T, TResult}"/> that creates an <see cref="IRegistration"/></param>
public void Register(Func<IRegistrationCollector, IRegistration> addRegistration)
{
IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> registration = _registrationFactory.RegisterMultiton<TInterface1, TInterface2, TImplementation, TScope>();
Register(registration);
RegistrationCollector registrationCollector = new(_registrationFactory);
addRegistration(registrationCollector);
return registration;
registrationCollector.Registrations.ForEach(Register);
}
/// <summary>
@ -224,29 +88,16 @@ namespace LightweightIocContainer
/// <exception cref="MultipleRegistrationException">The <see cref="Type"/> is already registered in this <see cref="IocContainer"/></exception>
private void Register(IRegistration registration)
{
//if type is already registered
//if type is already registered //fixMe: Remove and check if already registered registration is the same
if (Registrations.Any(r => r.InterfaceType == registration.InterfaceType))
throw new MultipleRegistrationException(registration.InterfaceType);
//don't allow lifestyle.multiton without iMultitonRegistration
if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and not IMultitonRegistration)
throw new InvalidRegistrationException("Can't register a type as Lifestyle.Multiton without a scope (Registration is not of type IMultitonRegistration).");
if (registration is IInternalValidationProvider validationProvider)
validationProvider.Validate();
Registrations.Add(registration);
}
/// <summary>
/// Register all <see cref="IMultipleRegistration{TInterface1,TImplementation}.Registrations"/> from an <see cref="IMultipleRegistration{TInterface1,TImplementation}"/>
/// </summary>
/// <typeparam name="TInterface1">The <see cref="Type"/> of the first registered interface</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> of the registered implementation</typeparam>
/// <param name="multipleRegistration">The <see cref="IMultipleRegistration{TInterface1,TImplementation}"/></param>
private void Register<TInterface1, TImplementation>(IMultipleRegistration<TInterface1, TImplementation> multipleRegistration) where TImplementation : TInterface1
{
foreach (IRegistration registration in multipleRegistration.Registrations)
Register(registration);
}
/// <summary>
/// Gets an instance of the given <see cref="Type"/>
/// </summary>
@ -685,9 +536,15 @@ namespace LightweightIocContainer
/// </summary>
/// <typeparam name="T">The given <see cref="Type"/></typeparam>
/// <returns>The <see cref="IRegistration"/> for the given <see cref="Type"/></returns>
private IRegistration? FindRegistration<T>()
private IRegistration? FindRegistration<T>() => FindRegistration(typeof(T));
/// <summary>
/// Find the <see cref="IRegistration"/> for the given <see cref="Type"/>
/// </summary>
/// <param name="type">The given <see cref="Type"/></param>
/// <returns>The <see cref="IRegistration"/> for the given <see cref="Type"/></returns>
private IRegistration? FindRegistration(Type type)
{
Type type = typeof(T);
IRegistration? registration = Registrations.FirstOrDefault(r => r.InterfaceType == type);
if (registration != null)
return registration;
@ -784,20 +641,18 @@ namespace LightweightIocContainer
/// </summary>
public void Dispose()
{
Registrations.Clear();
_singletons.Where(s => FindRegistration(s.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
.Select(s => s.instance)
.OfType<IDisposable>()
.ForEach(d => d.Dispose());
foreach (var singleton in _singletons)
{
if (singleton.instance is IDisposable disposable)
disposable.Dispose();
}
foreach (var multitonInstance in _multitons.SelectMany(multiton => multiton.instances))
{
if (multitonInstance.Value is IDisposable disposable)
disposable.Dispose();
}
_multitons.Where(m => FindRegistration(m.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container})
.SelectMany(m => m.instances)
.Select(i => i.Value)
.OfType<IDisposable>()
.ForEach(d => d.Dispose());
Registrations.Clear();
_singletons.Clear();
_multitons.Clear();
}

@ -28,6 +28,27 @@
<returns>A new instance of the given <see cref="T:System.Type"/></returns>
<exception cref="T:System.InvalidOperationException">The given type could not be created</exception>
</member>
<member name="T:LightweightIocContainer.DisposeStrategy">
<summary>
The dispose strategy that is used for a singleton or multiton that implements <see cref="T:System.IDisposable"/> and is created by the <see cref="T:LightweightIocContainer.IocContainer"/>
</summary>
</member>
<member name="F:LightweightIocContainer.DisposeStrategy.None">
<summary>
No dispose strategy
<remarks>Invalid for singletons or multitons that implement <see cref="T:System.IDisposable"/></remarks>
</summary>
</member>
<member name="F:LightweightIocContainer.DisposeStrategy.Application">
<summary>
The application is responsible for correctly disposing the instance. Nothing is done by the <see cref="T:LightweightIocContainer.IocContainer"/>
</summary>
</member>
<member name="F:LightweightIocContainer.DisposeStrategy.Container">
<summary>
The <see cref="T:LightweightIocContainer.IocContainer"/> is responsible for disposing the instance when itself is disposed
</summary>
</member>
<member name="M:LightweightIocContainer.EnumerableExtension.FirstOrGiven``2(System.Collections.Generic.IEnumerable{``0})">
<summary>
Returns the first element of a <see cref="T:System.Collections.Generic.IEnumerable`1"/>, or a new instance of a given <see cref="T:System.Type"/> if the <see cref="T:System.Collections.Generic.IEnumerable`1"/> contains no elements
@ -57,6 +78,14 @@
<param name="predicate">A function to test each element for a condition</param>
<returns>The first element of the <see cref="T:System.Collections.Generic.IEnumerable`1"/> or a new instance of the given <see cref="T:System.Type"/> when no element is found</returns>
</member>
<member name="M:LightweightIocContainer.EnumerableExtension.ForEach``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0})">
<summary>
Executes an <see cref="T:System.Action`1"/> for each item in an <see cref="T:System.Collections.Generic.IEnumerable`1"/>
</summary>
<param name="enumerable">The <see cref="T:System.Collections.Generic.IEnumerable`1"/></param>
<param name="action">The <see cref="T:System.Action`1"/></param>
<typeparam name="T">The <see cref="T:System.Type"/> of the items in the <see cref="T:System.Collections.Generic.IEnumerable`1"/></typeparam>
</member>
<member name="T:LightweightIocContainer.Exceptions.CircularDependencyException">
<summary>
A circular dependency was detected during <see cref="M:LightweightIocContainer.IocContainer.Resolve``1"/>
@ -140,6 +169,19 @@
</summary>
<param name="message">The exception message</param>
</member>
<member name="T:LightweightIocContainer.Exceptions.InvalidDisposeStrategyException">
<summary>
Invalid <see cref="T:LightweightIocContainer.DisposeStrategy"/> is used
</summary>
</member>
<member name="M:LightweightIocContainer.Exceptions.InvalidDisposeStrategyException.#ctor(LightweightIocContainer.DisposeStrategy,System.Type,LightweightIocContainer.Lifestyle)">
<summary>
Invalid <see cref="T:LightweightIocContainer.DisposeStrategy"/> is used
</summary>
<param name="disposeStrategy">The <see cref="T:LightweightIocContainer.DisposeStrategy"/></param>
<param name="type">The <see cref="T:System.Type"/></param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/></param>
</member>
<member name="T:LightweightIocContainer.Exceptions.InvalidFactoryRegistrationException">
<summary>
The registration of a Factory is not valid
@ -373,11 +415,11 @@
The <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/>s of the Assembly that this <see cref="T:LightweightIocContainer.Installers.AssemblyInstaller"/> is installing
</summary>
</member>
<member name="M:LightweightIocContainer.Installers.AssemblyInstaller.Install(LightweightIocContainer.Interfaces.IIocContainer)">
<member name="M:LightweightIocContainer.Installers.AssemblyInstaller.Install(LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector)">
<summary>
Install the found <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/>s in the given <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/>
</summary>
<param name="container">The current <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/></param>
<param name="registration">The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector"/> where <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s are added</param>
</member>
<member name="T:LightweightIocContainer.Installers.FromAssembly">
<summary>
@ -430,97 +472,6 @@
<param name="installers">The given <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/>s</param>
<returns>An instance of the current <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``2(LightweightIocContainer.Lifestyle)">
<summary>
Register an Interface with a Type that implements it
</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.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.RegisterOpenGenerics(System.Type,System.Type,LightweightIocContainer.Lifestyle)">
<summary>
Register an open generic Interface with an open generic Type that implements it
</summary>
<param name="tInterface">The open generic Interface to register</param>
<param name="tImplementation">The open generic Type that implements the interface</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``3(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``4(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`3"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``5(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TInterface4">A fourth interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`4"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.Register``6(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TInterface4">A fourth interface to register</typeparam>
<typeparam name="TInterface5">A fifth interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`5"/></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.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.RegisterMultiton``3">
<summary>
Register an Interface with a Type that implements it as a multiton
</summary>
<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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.RegisterMultiton``4">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them as a multiton
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second 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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.IIocContainer.ClearMultitonInstances``1">
<summary>
Clear the multiton instances of the given <see cref="T:System.Type"/> from the registered multitons list
@ -549,11 +500,11 @@
The base class for <see cref="T:LightweightIocContainer.Interfaces.IIocContainer"/> installers
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Installers.IIocInstaller.Install(LightweightIocContainer.Interfaces.IIocContainer)">
<member name="M:LightweightIocContainer.Interfaces.Installers.IIocInstaller.Install(LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector)">
<summary>
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>
<param name="registration">The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector"/> where <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s are added</param>
</member>
<member name="T:LightweightIocContainer.Interfaces.IResolver">
<summary>
@ -600,6 +551,23 @@
<param name="action">The <see cref="T:System.Action`1"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.ITypedRegistration`2"/></returns>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithDisposeStrategy">
<summary>
Provides a <see cref="T:LightweightIocContainer.DisposeStrategy"/> to an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithDisposeStrategy.WithDisposeStrategy(LightweightIocContainer.DisposeStrategy)">
<summary>
Add a <see cref="T:LightweightIocContainer.DisposeStrategy"/> for the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
</summary>
<param name="disposeStrategy">The <see cref="T:LightweightIocContainer.DisposeStrategy"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
</member>
<member name="P:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithDisposeStrategyInternal.DisposeStrategy">
<summary>
The <see cref="T:LightweightIocContainer.DisposeStrategy"/> of singletons/multitons that implement <see cref="T:System.IDisposable"/> and are created with this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithFactory">
<summary>
Provides a <see cref="M:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithFactory.WithFactory``1"/> method to an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
@ -654,6 +622,16 @@
<para>Can be set in the <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> by calling <see cref="M:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithParameters.WithParameters(System.Object[])"/></para>
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IInternalValidationProvider">
<summary>
Provides an internal <see cref="M:LightweightIocContainer.Interfaces.Registrations.IInternalValidationProvider.Validate"/> method to an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IInternalValidationProvider.Validate">
<summary>
Validate this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.ILifestyleProvider">
<summary>
Provides a <see cref="T:LightweightIocContainer.Lifestyle"/> to an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>
@ -759,6 +737,102 @@
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/> that is used to register an Interface and extends the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> with fluent options
</summary>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector">
<summary>
Creates and collects the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s
</summary>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``2(LightweightIocContainer.Lifestyle)">
<summary>
Add an Interface with a Type that implements it
</summary>
<typeparam name="TInterface">The Interface to add</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.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.AddOpenGenerics(System.Type,System.Type,LightweightIocContainer.Lifestyle)">
<summary>
Add an open generic Interface with an open generic Type that implements it
</summary>
<param name="tInterface">The open generic Interface to add</param>
<param name="tImplementation">The open generic Type that implements the interface</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``3(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``4(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`3"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``5(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TInterface4">A fourth interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`4"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``6(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TInterface4">A fourth interface to add</typeparam>
<typeparam name="TInterface5">A fifth interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`5"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.Add``1(LightweightIocContainer.Lifestyle)">
<summary>
Add a <see cref="T:System.Type"/> without an interface
</summary>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> to add</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.AddMultiton``3">
<summary>
Add an Interface with a Type that implements it as a multiton
</summary>
<typeparam name="TInterface">The Interface to add</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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector.AddMultiton``4">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them as a multiton
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</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.IRegistration"/></returns>
</member>
<member name="T:LightweightIocContainer.Interfaces.Registrations.ISingleTypeRegistration`1">
<summary>
The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> to register either only an interface or only a <see cref="T:System.Type"/>
@ -820,98 +894,11 @@
<param name="installers">The given <see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/>s</param>
<returns>An instance of the current <see cref="T:LightweightIocContainer.IocContainer"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``2(LightweightIocContainer.Lifestyle)">
<summary>
Register an Interface with a Type that implements it
</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.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterOpenGenerics(System.Type,System.Type,LightweightIocContainer.Lifestyle)">
<member name="M:LightweightIocContainer.IocContainer.Register(System.Func{LightweightIocContainer.Interfaces.Registrations.IRegistrationCollector,LightweightIocContainer.Interfaces.Registrations.IRegistration})">
<summary>
Register an open generic Interface with an open generic Type that implements it
Register an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> at this <see cref="T:LightweightIocContainer.IocContainer"/>
</summary>
<param name="tInterface">The open generic Interface to register</param>
<param name="tImplementation">The open generic Type that implements the interface</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IOpenGenericRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException">Function can only be used to register open generic types</exception>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException">Can't register a multiton with open generic registration</exception>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``3(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``4(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`3"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``5(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TInterface4">A fourth interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`4"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.Register``6(LightweightIocContainer.Lifestyle)">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second interface to register</typeparam>
<typeparam name="TInterface3">A third interface to register</typeparam>
<typeparam name="TInterface4">A fourth interface to register</typeparam>
<typeparam name="TInterface5">A fifth interface to register</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`5"/></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.IRegistrationBase"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterMultiton``3">
<summary>
Register an Interface with a Type that implements it as a multiton
</summary>
<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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterMultiton``4">
<summary>
Register multiple interfaces for a <see cref="T:System.Type"/> that implements them as a multiton
</summary>
<typeparam name="TInterface1">The base interface to register</typeparam>
<typeparam name="TInterface2">A second 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.IRegistration"/></returns>
<param name="addRegistration">The <see cref="T:System.Func`2"/> that creates an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
</member>
<member name="M:LightweightIocContainer.IocContainer.RegisterFactory``1(LightweightIocContainer.Interfaces.Factories.ITypedFactory{``0})">
<summary>
@ -927,14 +914,6 @@
<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.Register``2(LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration{``0,``1})">
<summary>
Register all <see cref="P:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2.Registrations"/> from an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/>
</summary>
<typeparam name="TInterface1">The <see cref="T:System.Type"/> of the first registered interface</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> of the registered implementation</typeparam>
<param name="multipleRegistration">The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></param>
</member>
<member name="M:LightweightIocContainer.IocContainer.Resolve``1">
<summary>
Gets an instance of the given <see cref="T:System.Type"/>
@ -1117,6 +1096,13 @@
<typeparam name="T">The given <see cref="T:System.Type"/></typeparam>
<returns>The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> for the given <see cref="T:System.Type"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.FindRegistration(System.Type)">
<summary>
Find the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> for the given <see cref="T:System.Type"/>
</summary>
<param name="type">The given <see cref="T:System.Type"/></param>
<returns>The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/> for the given <see cref="T:System.Type"/></returns>
</member>
<member name="M:LightweightIocContainer.IocContainer.TryGetSortedConstructors(System.Type)">
<summary>
Try to get the sorted constructors for the given <see cref="T:System.Type"/>
@ -1384,6 +1370,11 @@
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.IOpenGenericRegistration"/>
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.OpenGenericRegistration.Validate">
<summary>
Validate this <see cref="T:LightweightIocContainer.Registrations.OpenGenericRegistration"/>
</summary>
</member>
<member name="T:LightweightIocContainer.Registrations.RegistrationBase">
<summary>
The <see cref="T:LightweightIocContainer.Registrations.RegistrationBase"/> that is used to register an Interface
@ -1407,6 +1398,11 @@
The <see cref="T:LightweightIocContainer.Lifestyle"/> of Instances that are created with this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.RegistrationBase.DisposeStrategy">
<summary>
The <see cref="T:LightweightIocContainer.DisposeStrategy"/> of singletons/multitons that implement <see cref="T:System.IDisposable"/> and are created with this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase"/>
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.RegistrationBase.Parameters">
<summary>
An <see cref="T:System.Array"/> of parameters that are used to <see cref="M:LightweightIocContainer.IocContainer.Resolve``1"/> an instance of this <see cref="P:LightweightIocContainer.Interfaces.Registrations.IRegistration.InterfaceType"/>
@ -1451,6 +1447,153 @@
<typeparam name="TFactoryImplementation">The type of the implementation for the custom factory</typeparam>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.WithDisposeStrategy(LightweightIocContainer.DisposeStrategy)">
<summary>
Add a <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.DisposeStrategy"/> for the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistrationBase"/>
</summary>
<param name="disposeStrategy">The <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.DisposeStrategy"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.Validate">
<summary>
Validate this <see cref="T:LightweightIocContainer.Registrations.RegistrationBase"/>
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.ValidateMultiton">
<summary>
Validate that no registration that isn't derived from <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultitonRegistration"/> has <see cref="F:LightweightIocContainer.Lifestyle.Multiton"/>
</summary>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException"></exception>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.ValidateFactory">
<summary>
Validate the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.Factory"/>
</summary>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidFactoryRegistrationException">No create method that can create the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.InterfaceType"/></exception>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.ValidateDisposeStrategy">
<summary>
Validate the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.DisposeStrategy"/> for the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.InterfaceType"/> and <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.Lifestyle"/>
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationBase.ValidateDisposeStrategy(System.Type)">
<summary>
Validate the <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.DisposeStrategy"/> for the given <see cref="T:System.Type"/> and <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.Lifestyle"/>
</summary>
<param name="type">The given <see cref="T:System.Type"/></param>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidDisposeStrategyException">Dispose strategy is invalid for this <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.InterfaceType"/> and <see cref="P:LightweightIocContainer.Registrations.RegistrationBase.Lifestyle"/></exception>
</member>
<member name="T:LightweightIocContainer.Registrations.RegistrationCollector">
<summary>
Creates and collects the <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s
</summary>
</member>
<member name="P:LightweightIocContainer.Registrations.RegistrationCollector.Registrations">
<summary>
The collected <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/>s
</summary>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``2(LightweightIocContainer.Lifestyle)">
<summary>
Add an Interface with a Type that implements it
</summary>
<typeparam name="TInterface">The Interface to add</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.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.AddOpenGenerics(System.Type,System.Type,LightweightIocContainer.Lifestyle)">
<summary>
Add an open generic Interface with an open generic Type that implements it
</summary>
<param name="tInterface">The open generic Interface to add</param>
<param name="tImplementation">The open generic Type that implements the interface</param>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException">Function can only be used to register open generic types</exception>
<exception cref="T:LightweightIocContainer.Exceptions.InvalidRegistrationException">Can't register a multiton with open generic registration</exception>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``3(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``4(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`3"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``5(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TInterface4">A fourth interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`4"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``6(LightweightIocContainer.Lifestyle)">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</typeparam>
<typeparam name="TInterface3">A third interface to add</typeparam>
<typeparam name="TInterface4">A fourth interface to add</typeparam>
<typeparam name="TInterface5">A fifth interface to add</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> that implements both interfaces</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`5"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Add``1(LightweightIocContainer.Lifestyle)">
<summary>
Add a <see cref="T:System.Type"/> without an interface
</summary>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> to add</typeparam>
<param name="lifestyle">The <see cref="T:LightweightIocContainer.Lifestyle"/> for this <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></param>
<returns>The created <see cref="T:LightweightIocContainer.Interfaces.Registrations.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.AddMultiton``3">
<summary>
Add an Interface with a Type that implements it as a multiton
</summary>
<typeparam name="TInterface">The Interface to add</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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.AddMultiton``4">
<summary>
Add multiple interfaces for a <see cref="T:System.Type"/> that implements them as a multiton
</summary>
<typeparam name="TInterface1">The base interface to add</typeparam>
<typeparam name="TInterface2">A second interface to add</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.IRegistration"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.RegistrationCollector.Register``2(LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration{``0,``1})">
<summary>
Register all <see cref="P:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2.Registrations"/> from an <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/>
</summary>
<typeparam name="TInterface1">The <see cref="T:System.Type"/> of the first registered interface</typeparam>
<typeparam name="TImplementation">The <see cref="T:System.Type"/> of the registered implementation</typeparam>
<param name="multipleRegistration">The <see cref="T:LightweightIocContainer.Interfaces.Registrations.IMultipleRegistration`2"/></param>
</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.IRegistration"/>s
@ -1640,6 +1783,11 @@
<param name="action">The <see cref="T:System.Action`1"/></param>
<returns>The current instance of this <see cref="T:LightweightIocContainer.Interfaces.Registrations.ITypedRegistration`2"/></returns>
</member>
<member name="M:LightweightIocContainer.Registrations.TypedRegistration`2.ValidateDisposeStrategy">
<summary>
Validate the <see cref="T:LightweightIocContainer.DisposeStrategy"/> for the <see cref="P:LightweightIocContainer.Registrations.TypedRegistration`2.ImplementationType"/> and <see cref="T:LightweightIocContainer.Lifestyle"/>
</summary>
</member>
<member name="T:LightweightIocContainer.ResolvePlaceholders.IInternalToBeResolvedPlaceholder">
<summary>
An internal placeholder that is used to hold types that need to be resolved during the resolving process

@ -15,7 +15,7 @@ namespace LightweightIocContainer.Registrations
/// <typeparam name="TInterface1">The first interface</typeparam>
/// <typeparam name="TInterface2">The second interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public class MultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> : MultitonRegistration<TInterface1, TImplementation>, IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> where TImplementation : TInterface1, TInterface2
internal class MultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> : MultitonRegistration<TInterface1, TImplementation>, IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> where TImplementation : TInterface1, TInterface2
{
/// <summary>
/// An <see cref="IRegistrationBase"/> to register multiple interfaces for on implementation type that implements them as a multiton

@ -14,7 +14,7 @@ namespace LightweightIocContainer.Registrations
/// </summary>
/// <typeparam name="TInterface1">The first interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public abstract class MultipleRegistration<TInterface1, TImplementation> : TypedRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TImplementation> where TImplementation : TInterface1
internal abstract class MultipleRegistration<TInterface1, TImplementation> : TypedRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TImplementation> where TImplementation : TInterface1
{
/// <summary>
/// The base class for every <see cref="IMultipleRegistration{TInterface1,TInterface2}"/> to register multiple interfaces
@ -39,7 +39,7 @@ namespace LightweightIocContainer.Registrations
/// <typeparam name="TInterface1">The first interface</typeparam>
/// <typeparam name="TInterface2">The second interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public class MultipleRegistration<TInterface1, TInterface2, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TImplementation> where TImplementation : TInterface1, TInterface2
internal class MultipleRegistration<TInterface1, TInterface2, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TImplementation> where TImplementation : TInterface1, TInterface2
{
/// <summary>
/// An <see cref="IRegistration"/> to register multiple interfaces for on implementation type
@ -85,7 +85,7 @@ namespace LightweightIocContainer.Registrations
/// <typeparam name="TInterface2">The second interface</typeparam>
/// <typeparam name="TInterface3">The third interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public class MultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> where TImplementation : TInterface3, TInterface2, TInterface1
internal class MultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> where TImplementation : TInterface3, TInterface2, TInterface1
{
/// <summary>
/// An <see cref="IRegistration"/> to register multiple interfaces for on implementation type
@ -136,7 +136,7 @@ namespace LightweightIocContainer.Registrations
/// <typeparam name="TInterface3">The third interface</typeparam>
/// <typeparam name="TInterface4">The fourth interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public class MultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1
internal class MultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1
{
/// <summary>
/// An <see cref="IRegistration"/> to register multiple interfaces for on implementation type
@ -192,7 +192,7 @@ namespace LightweightIocContainer.Registrations
/// <typeparam name="TInterface4">The fourth interface</typeparam>
/// <typeparam name="TInterface5">The fifth interface</typeparam>
/// <typeparam name="TImplementation">The implementation</typeparam>
public class MultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1
internal class MultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> : MultipleRegistration<TInterface1, TImplementation>, IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1
{
/// <summary>
/// An <see cref="IRegistration"/> to register multiple interfaces for on implementation type

@ -13,7 +13,7 @@ namespace LightweightIocContainer.Registrations
/// </summary>
/// <typeparam name="TInterface">The registered interface</typeparam>
/// <typeparam name="TImplementation">The registered implementation</typeparam>
public class MultitonRegistration<TInterface, TImplementation> : TypedRegistration<TInterface, TImplementation>, IMultitonRegistration<TInterface, TImplementation> where TImplementation : TInterface
internal class MultitonRegistration<TInterface, TImplementation> : TypedRegistration<TInterface, TImplementation>, IMultitonRegistration<TInterface, TImplementation> where TImplementation : TInterface
{
/// <summary>
/// The registration that is used to register a multiton

@ -3,6 +3,7 @@
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Registrations;
@ -11,7 +12,7 @@ namespace LightweightIocContainer.Registrations
/// <summary>
/// <see cref="IRegistration"/> for open generic types
/// </summary>
public class OpenGenericRegistration : RegistrationBase, IOpenGenericRegistration
internal class OpenGenericRegistration : RegistrationBase, IOpenGenericRegistration
{
/// <summary>
/// <see cref="IRegistration"/> for open generic types
@ -28,5 +29,19 @@ namespace LightweightIocContainer.Registrations
/// The <see cref="Type"/> that implements the <see cref="IRegistration.InterfaceType"/> that is registered with this <see cref="IOpenGenericRegistration"/>
/// </summary>
public Type ImplementationType { get; }
/// <summary>
/// Validate this <see cref="OpenGenericRegistration"/>
/// </summary>
public override void Validate()
{
if (!InterfaceType.ContainsGenericParameters)
throw new InvalidRegistrationException("This function can only be used to register open generic types.");
if (Lifestyle == Lifestyle.Multiton)
throw new InvalidRegistrationException("Can't register a multiton with open generic registration."); //TODO: Is there any need to register multitons with open generics?
base.Validate();
}
}
}

@ -17,7 +17,7 @@ namespace LightweightIocContainer.Registrations
/// <summary>
/// The <see cref="RegistrationBase"/> that is used to register an Interface
/// </summary>
public abstract class RegistrationBase : IRegistrationBase, IWithFactoryInternal, IWithParametersInternal, ILifestyleProvider
internal abstract class RegistrationBase : IRegistrationBase, IWithFactoryInternal, IWithParametersInternal, ILifestyleProvider, IWithDisposeStrategyInternal, IInternalValidationProvider
{
private readonly IocContainer _container;
@ -44,6 +44,11 @@ namespace LightweightIocContainer.Registrations
/// </summary>
public Lifestyle Lifestyle { get; }
/// <summary>
/// The <see cref="LightweightIocContainer.DisposeStrategy"/> of singletons/multitons that implement <see cref="IDisposable"/> and are created with this <see cref="RegistrationBase"/>
/// </summary>
public DisposeStrategy DisposeStrategy { get; private set; }
/// <summary>
/// An <see cref="Array"/> of parameters that are used to <see cref="IocContainer.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>
@ -113,7 +118,6 @@ namespace LightweightIocContainer.Registrations
TypedFactory<TFactory> factory = new(_container);
Factory = factory;
ValidateFactory();
_container.RegisterFactory(factory);
return this;
@ -128,17 +132,81 @@ namespace LightweightIocContainer.Registrations
public IRegistrationBase WithFactory<TFactoryInterface, TFactoryImplementation>() where TFactoryImplementation : TFactoryInterface
{
Factory = new CustomTypedFactory<TFactoryInterface>();
ValidateFactory();
_container.Register(r => r.Add<TFactoryInterface, TFactoryImplementation>());
_container.Register<TFactoryInterface, TFactoryImplementation>();
return this;
}
/// <summary>
/// Add a <see cref="DisposeStrategy"/> for the <see cref="IRegistrationBase"/>
/// </summary>
/// <param name="disposeStrategy">The <see cref="DisposeStrategy"/></param>
/// <returns>The current instance of this <see cref="RegistrationBase"/></returns>
public IRegistrationBase WithDisposeStrategy(DisposeStrategy disposeStrategy)
{
DisposeStrategy = disposeStrategy;
return this;
}
/// <summary>
/// Validate this <see cref="RegistrationBase"/>
/// </summary>
public virtual void Validate()
{
ValidateMultiton();
ValidateFactory();
ValidateDisposeStrategy();
}
/// <summary>
/// Validate that no registration that isn't derived from <see cref="IMultitonRegistration"/> has <see cref="LightweightIocContainer.Lifestyle.Multiton"/>
/// </summary>
/// <exception cref="InvalidRegistrationException"></exception>
private void ValidateMultiton()
{
//don't allow lifestyle.multiton without iMultitonRegistration
if (Lifestyle == Lifestyle.Multiton && this is not IMultitonRegistration)
throw new InvalidRegistrationException("Can't register a type as Lifestyle.Multiton without a scope (Registration is not of type IMultitonRegistration).");
}
/// <summary>
/// Validate the <see cref="Factory"/>
/// </summary>
/// <exception cref="InvalidFactoryRegistrationException">No create method that can create the <see cref="InterfaceType"/></exception>
private void ValidateFactory()
{
if (Factory?.CreateMethods.Any(c => c.ReturnType == InterfaceType) != true)
if (Factory == null)
return;
if (Factory.CreateMethods.Any(c => c.ReturnType == InterfaceType) != true)
throw new InvalidFactoryRegistrationException($"No create method that can create {InterfaceType}.");
}
/// <summary>
/// Validate the <see cref="DisposeStrategy"/> for the <see cref="InterfaceType"/> and <see cref="Lifestyle"/>
/// </summary>
protected virtual void ValidateDisposeStrategy() => ValidateDisposeStrategy(InterfaceType);
/// <summary>
/// Validate the <see cref="DisposeStrategy"/> for the given <see cref="Type"/> and <see cref="Lifestyle"/>
/// </summary>
/// <param name="type">The given <see cref="Type"/></param>
/// <exception cref="InvalidDisposeStrategyException">Dispose strategy is invalid for this <see cref="InterfaceType"/> and <see cref="Lifestyle"/></exception>
protected void ValidateDisposeStrategy(Type type)
{
if (Lifestyle == Lifestyle.Transient)
{
if (DisposeStrategy != DisposeStrategy.None)
throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle);
}
else
{
if (!type.IsAssignableTo(typeof(IDisposable)))
return;
if (DisposeStrategy == DisposeStrategy.None)
throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle);
}
}
}
}

@ -0,0 +1,188 @@
// Author: Gockner, Simon
// Created: 2021-12-15
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces.Registrations;
namespace LightweightIocContainer.Registrations;
/// <summary>
/// Creates and collects the <see cref="IRegistration"/>s
/// </summary>
public class RegistrationCollector : IRegistrationCollector
{
private readonly RegistrationFactory _registrationFactory;
internal RegistrationCollector(RegistrationFactory registrationFactory)
{
_registrationFactory = registrationFactory;
Registrations = new List<IRegistration>();
}
/// <summary>
/// The collected <see cref="IRegistration"/>s
/// </summary>
internal List<IRegistration> Registrations { get; }
/// <summary>
/// Add an Interface with a Type that implements it
/// </summary>
/// <typeparam name="TInterface">The Interface to add</typeparam>
/// <typeparam name="TImplementation">The Type that implements the interface</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public ITypedRegistration<TInterface, TImplementation> Add<TInterface, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface
{
ITypedRegistration<TInterface, TImplementation> registration = _registrationFactory.Register<TInterface, TImplementation>(lifestyle);
Registrations.Add(registration);
return registration;
}
/// <summary>
/// Add an open generic Interface with an open generic Type that implements it
/// </summary>
/// <param name="tInterface">The open generic Interface to add</param>
/// <param name="tImplementation">The open generic Type that implements the interface</param>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
/// <exception cref="InvalidRegistrationException">Function can only be used to register open generic types</exception>
/// <exception cref="InvalidRegistrationException">Can't register a multiton with open generic registration</exception>
public IOpenGenericRegistration AddOpenGenerics(Type tInterface, Type tImplementation, Lifestyle lifestyle = Lifestyle.Transient)
{
IOpenGenericRegistration registration = _registrationFactory.Register(tInterface, tImplementation, lifestyle);
Registrations.Add(registration);
return registration;
}
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TImplementation> Add<TInterface1, TInterface2, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> Add<TInterface1, TInterface2, TInterface3, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TInterface4">A fourth interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> Add<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TInterface4, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</typeparam>
/// <typeparam name="TInterface3">A third interface to add</typeparam>
/// <typeparam name="TInterface4">A fourth interface to add</typeparam>
/// <typeparam name="TInterface5">A fifth interface to add</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> that implements both interfaces</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IMultipleRegistration{TInterface1,TInterface2,TInterface3,TInterface4,TInterface5}"/></returns>
public IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> Add<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1
{
IMultipleRegistration<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation> multipleRegistration = _registrationFactory.Register<TInterface1, TInterface2, TInterface3, TInterface4, TInterface5, TImplementation>(lifestyle);
Register(multipleRegistration);
return multipleRegistration;
}
/// <summary>
/// Add a <see cref="Type"/> without an interface
/// </summary>
/// <typeparam name="TImplementation">The <see cref="Type"/> to add</typeparam>
/// <param name="lifestyle">The <see cref="Lifestyle"/> for this <see cref="IRegistration"/></param>
/// <returns>The created <see cref="IRegistration"/></returns>
public ISingleTypeRegistration<TImplementation> Add<TImplementation>(Lifestyle lifestyle = Lifestyle.Transient)
{
ISingleTypeRegistration<TImplementation> registration = _registrationFactory.Register<TImplementation>(lifestyle);
Registrations.Add(registration);
return registration;
}
/// <summary>
/// Add an Interface with a Type that implements it as a multiton
/// </summary>
/// <typeparam name="TInterface">The Interface to add</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="IRegistration"/></returns>
public IMultitonRegistration<TInterface, TImplementation> AddMultiton<TInterface, TImplementation, TScope>() where TImplementation : TInterface
{
IMultitonRegistration<TInterface, TImplementation> registration = _registrationFactory.RegisterMultiton<TInterface, TImplementation, TScope>();
Registrations.Add(registration);
return registration;
}
/// <summary>
/// Add multiple interfaces for a <see cref="Type"/> that implements them as a multiton
/// </summary>
/// <typeparam name="TInterface1">The base interface to add</typeparam>
/// <typeparam name="TInterface2">A second interface to add</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="IRegistration"/></returns>
public IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> AddMultiton<TInterface1, TInterface2, TImplementation, TScope>() where TImplementation : TInterface1, TInterface2
{
IMultipleMultitonRegistration<TInterface1, TInterface2, TImplementation> registration = _registrationFactory.RegisterMultiton<TInterface1, TInterface2, TImplementation, TScope>();
Register(registration);
return registration;
}
/// <summary>
/// Register all <see cref="IMultipleRegistration{TInterface1,TImplementation}.Registrations"/> from an <see cref="IMultipleRegistration{TInterface1,TImplementation}"/>
/// </summary>
/// <typeparam name="TInterface1">The <see cref="Type"/> of the first registered interface</typeparam>
/// <typeparam name="TImplementation">The <see cref="Type"/> of the registered implementation</typeparam>
/// <param name="multipleRegistration">The <see cref="IMultipleRegistration{TInterface1,TImplementation}"/></param>
private void Register<TInterface1, TImplementation>(IMultipleRegistration<TInterface1, TImplementation> multipleRegistration) where TImplementation : TInterface1
{
foreach (IRegistration registration in multipleRegistration.Registrations)
Registrations.Add(registration);
}
}

@ -12,7 +12,7 @@ namespace LightweightIocContainer.Registrations
/// The <see cref="IRegistration"/> to register either only an interface or only a <see cref="Type"/>
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the <see cref="IRegistration"/></typeparam>
public class SingleTypeRegistration<T> : RegistrationBase, ISingleTypeRegistration<T>
internal class SingleTypeRegistration<T> : RegistrationBase, ISingleTypeRegistration<T>
{
/// <summary>
/// The <see cref="IRegistration"/> to register either only an interface or only a <see cref="Type"/>

@ -13,7 +13,7 @@ namespace LightweightIocContainer.Registrations
/// <summary>
/// A <see cref="IRegistrationBase"/> that implements a <see cref="Type"/>
/// </summary>
public class TypedRegistration<TInterface, TImplementation> : RegistrationBase, ITypedRegistration<TInterface, TImplementation> where TImplementation : TInterface
internal class TypedRegistration<TInterface, TImplementation> : RegistrationBase, ITypedRegistration<TInterface, TImplementation> where TImplementation : TInterface
{
/// <summary>
/// A <see cref="IRegistrationBase"/> that implements a <see cref="Type"/>
@ -53,5 +53,10 @@ namespace LightweightIocContainer.Registrations
OnCreateAction = a => action((TImplementation?) a);
return this;
}
/// <summary>
/// Validate the <see cref="DisposeStrategy"/> for the <see cref="ImplementationType"/> and <see cref="Lifestyle"/>
/// </summary>
protected override void ValidateDisposeStrategy() => ValidateDisposeStrategy(ImplementationType);
}
}

@ -22,7 +22,7 @@ namespace Test.LightweightIocContainer
[UsedImplicitly]
public class TestInstaller : IIocInstaller
{
public void Install(IIocContainer container) => container.Register<Mock<IRegistration>>();
public void Install(IRegistrationCollector registration) => registration.Add<Mock<IRegistration>>();
}
[UsedImplicitly]
@ -44,12 +44,12 @@ namespace Test.LightweightIocContainer
Mock<AssemblyWrapper> assemblyMock = new();
assemblyMock.Setup(a => a.GetTypes()).Returns(types.ToArray);
Mock<IIocContainer> iocContainerMock = new();
Mock<IRegistrationCollector> registrationCollectorMock = new();
AssemblyInstaller assemblyInstaller = new(assemblyMock.Object);
assemblyInstaller.Install(iocContainerMock.Object);
assemblyInstaller.Install(registrationCollectorMock.Object);
iocContainerMock.Verify(ioc => ioc.Register<It.IsSubtype<Mock<IRegistration>>>(It.IsAny<Lifestyle>()), Times.Once);
registrationCollectorMock.Verify(r => r.Add<It.IsSubtype<Mock<IRegistration>>>(It.IsAny<Lifestyle>()), Times.Once);
}
[Test]

@ -0,0 +1,91 @@
// Author: Gockner, Simon
// Created: 2021-12-16
// Copyright(c) 2021 SimonG. All Rights Reserved.
using System;
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Exceptions;
using NUnit.Framework;
namespace Test.LightweightIocContainer;
[TestFixture]
public class DisposeStrategyTest
{
[UsedImplicitly]
public interface ITest : IDisposable
{
}
private class Test : ITest
{
public void Dispose() => throw new Exception();
}
[Test]
public void TestValidContainerDisposeStrategySingleton()
{
IocContainer iocContainer = new();
iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Singleton).WithDisposeStrategy(DisposeStrategy.Container));
iocContainer.Resolve<ITest>();
Assert.Throws<Exception>(() => iocContainer.Dispose());
}
[Test]
public void TestValidContainerDisposeStrategyMultiton()
{
IocContainer iocContainer = new();
iocContainer.Register(r => r.AddMultiton<ITest, Test, int>().WithDisposeStrategy(DisposeStrategy.Container));
iocContainer.Resolve<ITest>(1);
Assert.Throws<Exception>(() => iocContainer.Dispose());
}
[Test]
public void TestValidAppDisposeStrategySingleton()
{
IocContainer iocContainer = new();
iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Singleton).WithDisposeStrategy(DisposeStrategy.Application));
iocContainer.Resolve<ITest>();
Assert.DoesNotThrow(() => iocContainer.Dispose());
}
[Test]
public void TestValidAppDisposeStrategyMultiton()
{
IocContainer iocContainer = new();
iocContainer.Register(r => r.AddMultiton<ITest, Test, int>().WithDisposeStrategy(DisposeStrategy.Application));
iocContainer.Resolve<ITest>(1);
Assert.DoesNotThrow(() => iocContainer.Dispose());
}
[Test]
public void TestInvalidDisposeStrategySingleton()
{
IocContainer iocContainer = new();
Assert.Throws<InvalidDisposeStrategyException>(() => iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Singleton)));
}
[Test]
public void TestInvalidDisposeStrategyMultiton()
{
IocContainer iocContainer = new();
Assert.Throws<InvalidDisposeStrategyException>(() => iocContainer.Register(r => r.AddMultiton<ITest, Test, int>()));
}
[Test]
public void TestInvalidDisposeStrategyTransient()
{
IocContainer iocContainer = new();
Assert.Throws<InvalidDisposeStrategyException>(() => iocContainer.Register(r => r.Add<ITest, Test>().WithDisposeStrategy(DisposeStrategy.Container)));
}
}

@ -4,7 +4,9 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using LightweightIocContainer;
using Moq;
using NUnit.Framework;
namespace Test.LightweightIocContainer
@ -22,6 +24,12 @@ namespace Test.LightweightIocContainer
}
[UsedImplicitly]
public interface ITest
{
void DoSomething();
}
[Test]
[SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")]
@ -72,5 +80,23 @@ namespace Test.LightweightIocContainer
Assert.IsNotInstanceOf<Given>(listObject);
Assert.AreEqual(2, listObject.Index);
}
[Test]
public void TestForEach()
{
Mock<ITest> test1 = new();
Mock<ITest> test2 = new();
Mock<ITest> test3 = new();
Mock<ITest> test4 = new();
IEnumerable<ITest> enumerable = new[] { test1.Object, test2.Object, test3.Object, test4.Object };
enumerable.ForEach(t => t.DoSomething());
test1.Verify(t => t.DoSomething(), Times.Once);
test2.Verify(t => t.DoSomething(), Times.Once);
test3.Verify(t => t.DoSomething(), Times.Once);
test4.Verify(t => t.DoSomething(), Times.Once);
}
}
}

@ -100,7 +100,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestFluentFactoryRegistration()
{
_iocContainer.Register<ITest, Test>().WithFactory<ITestFactory>();
_iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactory>());
ITestFactory factory = _iocContainer.Resolve<ITestFactory>();
ITest test = _iocContainer.Resolve<ITest>();
@ -112,7 +112,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestFluentFactoryRegistration_CustomFactory()
{
_iocContainer.Register<ITest, Test>().WithFactory<ITestFactory, TestFactory>();
_iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactory, TestFactory>());
ITestFactory factory = _iocContainer.Resolve<ITestFactory>();
ITest test = _iocContainer.Resolve<ITest>();
@ -122,15 +122,15 @@ namespace Test.LightweightIocContainer
}
[Test]
public void TestRegisterFactoryWithoutCreate() => Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register<ITest, Test>().WithFactory<ITestFactoryNoCreate>());
public void TestRegisterFactoryWithoutCreate() => Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactoryNoCreate>()));
[Test]
public void TestRegisterFactoryClearMultitonsNonGeneric() => Assert.Throws<IllegalAbstractMethodCreationException>(() => _iocContainer.Register<ITest, Test>().WithFactory<ITestFactoryNonGenericClear>());
public void TestRegisterFactoryClearMultitonsNonGeneric() => Assert.Throws<IllegalAbstractMethodCreationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactoryNonGenericClear>()));
[Test]
public void TestResolveFromFactory()
{
_iocContainer.Register<ITest, Test>().WithFactory<ITestFactory>();
_iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactory>());
ITestFactory testFactory = _iocContainer.Resolve<ITestFactory>();
ITest createdTest = testFactory.Create();
@ -141,8 +141,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveFromFactoryWithParams()
{
_iocContainer.Register<ITest, TestConstructor>().WithFactory<ITestFactory>();
_iocContainer.Register<Test, Test>(); //this registration is abnormal and should only be used in unit tests
_iocContainer.Register(r => r.Add<ITest, TestConstructor>().WithFactory<ITestFactory>());
_iocContainer.Register(r => r.Add<Test, Test>()); //this registration is abnormal and should only be used in unit tests
ITestFactory testFactory = _iocContainer.Resolve<ITestFactory>();
ITest createdTest = testFactory.Create("Test");
@ -153,8 +153,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveFromFactoryWithDefaultParamCreate()
{
_iocContainer.Register<ITest, TestConstructor>().WithFactory<ITestFactory>();
_iocContainer.Register<Test, Test>(); //this registration is abnormal and should only be used in unit tests
_iocContainer.Register(r => r.Add<ITest, TestConstructor>().WithFactory<ITestFactory>());
_iocContainer.Register(r => r.Add<Test, Test>()); //this registration is abnormal and should only be used in unit tests
ITestFactory testFactory = _iocContainer.Resolve<ITestFactory>();
ITest createdTest = testFactory.CreateTest();
@ -165,8 +165,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveFromFactoryWithDefaultParamCtor()
{
_iocContainer.Register<ITest, TestConstructor>().WithFactory<ITestFactory>();
_iocContainer.Register<Test, Test>(); //this registration is abnormal and should only be used in unit tests
_iocContainer.Register(r => r.Add<ITest, TestConstructor>().WithFactory<ITestFactory>());
_iocContainer.Register(r => r.Add<Test, Test>()); //this registration is abnormal and should only be used in unit tests
ITestFactory testFactory = _iocContainer.Resolve<ITestFactory>();
ITest createdTest = testFactory.Create();
@ -177,7 +177,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveFromFactoryWithByte()
{
_iocContainer.Register<ITest, TestByte>().WithFactory<ITestFactory>();
_iocContainer.Register(r => r.Add<ITest, TestByte>().WithFactory<ITestFactory>());
ITestFactory testFactory = _iocContainer.Resolve<ITestFactory>();
ITest createdTest = testFactory.Create(1);
@ -188,7 +188,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveMultitonFromFactory()
{
_iocContainer.RegisterMultiton<ITest, Test, MultitonScope>().WithFactory<ITestFactory>();
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>().WithFactory<ITestFactory>());
MultitonScope scope1 = new();
MultitonScope scope2 = new();
@ -207,7 +207,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveMultitonFromFactoryClearInstances()
{
_iocContainer.RegisterMultiton<ITest, Test, MultitonScope>().WithFactory<ITestFactory>();
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>().WithFactory<ITestFactory>());
MultitonScope scope1 = new();
MultitonScope scope2 = new();
@ -234,6 +234,6 @@ namespace Test.LightweightIocContainer
[Test]
public void TestInvalidCreateMethodReturnType() =>
Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register<ITest, Test>().WithFactory<ITestFactoryWrongReturn>());
Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactoryWrongReturn>()));
}
}

@ -54,7 +54,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegistrationOnCreate2()
{
_container.Register<IBar, IFoo, Foo>().OnCreate(foo => foo.ThrowFoo());
_container.Register(r => r.Add<IBar, IFoo, Foo>().OnCreate(foo => foo.ThrowFoo()));
Exception fooException = Assert.Throws<Exception>(() => _container.Resolve<IFoo>());
Assert.AreEqual("Foo", fooException?.Message);
@ -66,7 +66,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegistrationOnCreate3()
{
_container.Register<IBar, IFoo, IAnotherFoo, Foo>().OnCreate(foo => foo.ThrowFoo());
_container.Register(r => r.Add<IBar, IFoo, IAnotherFoo, Foo>().OnCreate(foo => foo.ThrowFoo()));
Exception fooException = Assert.Throws<Exception>(() => _container.Resolve<IFoo>());
Assert.AreEqual("Foo", fooException?.Message);
@ -81,7 +81,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegistrationOnCreate4()
{
_container.Register<IBar, IFoo, IAnotherFoo, IAnotherBar, Foo>().OnCreate(foo => foo.ThrowFoo());
_container.Register(r => r.Add<IBar, IFoo, IAnotherFoo, IAnotherBar, Foo>().OnCreate(foo => foo.ThrowFoo()));
Exception fooException = Assert.Throws<Exception>(() => _container.Resolve<IFoo>());
Assert.AreEqual("Foo", fooException?.Message);
@ -99,7 +99,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegistrationOnCreate5()
{
_container.Register<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>().OnCreate(foo => foo.ThrowFoo());
_container.Register(r => r.Add<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>().OnCreate(foo => foo.ThrowFoo()));
Exception fooException = Assert.Throws<Exception>(() => _container.Resolve<IFoo>());
Assert.AreEqual("Foo", fooException?.Message);
@ -120,7 +120,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveTransient()
{
_container.Register<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>();
_container.Register(r => r.Add<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>());
IFoo foo = _container.Resolve<IFoo>();
IBar bar = _container.Resolve<IBar>();
IAnotherFoo anotherFoo = _container.Resolve<IAnotherFoo>();
@ -137,7 +137,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveSingleton()
{
_container.Register<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>(Lifestyle.Singleton);
_container.Register(r => r.Add<IBar, IFoo, IAnotherFoo, IAnotherBar, IAnotherOne, Foo>(Lifestyle.Singleton));
IFoo foo = _container.Resolve<IFoo>();
IBar bar = _container.Resolve<IBar>();
IAnotherFoo anotherFoo = _container.Resolve<IAnotherFoo>();

@ -101,7 +101,7 @@ namespace Test.LightweightIocContainer
IC c = new C();
IB b = new B(c);
_iocContainer.Register<IA, A>().WithParameters(b, c);
_iocContainer.Register(r => r.Add<IA, A>().WithParameters(b, c));
IA a = _iocContainer.Resolve<IA>();
Assert.AreEqual(b, a.B);
@ -114,7 +114,7 @@ namespace Test.LightweightIocContainer
IC c = new C();
IB b = new B(c);
_iocContainer.Register<IA, A>().WithParameters(b);
_iocContainer.Register(r => r.Add<IA, A>().WithParameters(b));
IA a = _iocContainer.Resolve<IA>(c);
Assert.AreEqual(b, a.B);
@ -129,7 +129,7 @@ namespace Test.LightweightIocContainer
IA a = new A(b, c);
IA a2 = new A(b, c);
_iocContainer.Register<ID, D>().WithParameters((0, a), (2, b), (3, c));
_iocContainer.Register(r => r.Add<ID, D>().WithParameters((0, a), (2, b), (3, c)));
ID d = _iocContainer.Resolve<ID>(a2);
Assert.AreEqual(a, d.A);
@ -146,9 +146,9 @@ namespace Test.LightweightIocContainer
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>();
_iocContainer.Register(r => r.Add<ID, D>().WithParameters(a2));
_iocContainer.Register(r => r.Add<IB, B>());
_iocContainer.Register(r => r.Add<IC, C>());
ID d = _iocContainer.Resolve<ID>(a);

@ -110,8 +110,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestCircularDependencies()
{
_iocContainer.Register<IFoo, Foo>();
_iocContainer.Register<IBar, Bar>();
_iocContainer.Register(r => r.Add<IFoo, Foo>());
_iocContainer.Register(r => r.Add<IBar, Bar>());
NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<IFoo>());
ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.InnerExceptions[0];
@ -145,9 +145,9 @@ namespace Test.LightweightIocContainer
[Test]
public void TestNonCircularDependencies()
{
_iocContainer.Register<IA, A>();
_iocContainer.Register<IB, B>();
_iocContainer.Register<IC, C>();
_iocContainer.Register(r => r.Add<IA, A>());
_iocContainer.Register(r => r.Add<IB, B>());
_iocContainer.Register(r => r.Add<IC, C>());
IA a = _iocContainer.Resolve<IA>();
Assert.IsNotNull(a);
@ -156,8 +156,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRecursionWithParam()
{
_iocContainer.Register<IFoo, Foo>();
_iocContainer.Register<IBar, Bar>();
_iocContainer.Register(r => r.Add<IFoo, Foo>());
_iocContainer.Register(r => r.Add<IBar, Bar>());
Assert.DoesNotThrow(() => _iocContainer.Resolve<IFoo>(new Mock<IBar>().Object));
Assert.DoesNotThrow(() => _iocContainer.Resolve<IBar>(new Mock<IFoo>().Object));
@ -166,8 +166,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestNonCircularCrossDependencies()
{
_iocContainer.Register<IA, ATwoCtor>();
_iocContainer.Register<IB, BTwoCtor>();
_iocContainer.Register(r => r.Add<IA, ATwoCtor>());
_iocContainer.Register(r => r.Add<IB, BTwoCtor>());
Assert.DoesNotThrow(() => _iocContainer.Resolve<IA>());
Assert.DoesNotThrow(() => _iocContainer.Resolve<IB>());

@ -3,6 +3,7 @@ using LightweightIocContainer;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
using Moq;
using NUnit.Framework;
@ -111,7 +112,7 @@ namespace Test.LightweightIocContainer
Mock<IIocInstaller> installerMock = new();
IIocContainer returnedContainer = _iocContainer.Install(installerMock.Object);
installerMock.Verify(m => m.Install(It.IsAny<IIocContainer>()), Times.Once);
installerMock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
Assert.AreEqual(_iocContainer, returnedContainer);
}
@ -125,30 +126,30 @@ namespace Test.LightweightIocContainer
IIocContainer returnedContainer = _iocContainer.Install(installer1Mock.Object, installer2Mock.Object, installer3Mock.Object);
installer1Mock.Verify(m => m.Install(It.IsAny<IIocContainer>()), Times.Once);
installer2Mock.Verify(m => m.Install(It.IsAny<IIocContainer>()), Times.Once);
installer3Mock.Verify(m => m.Install(It.IsAny<IIocContainer>()), Times.Once);
installer1Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
installer2Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
installer3Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
Assert.AreEqual(_iocContainer, returnedContainer);
}
[Test]
public void TestRegister() => Assert.DoesNotThrow(() => _iocContainer.Register<ITest, Test>());
public void TestRegister() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<ITest, Test>()));
[Test]
public void TestRegisterTypeWithoutInterface() => Assert.DoesNotThrow(() => _iocContainer.Register<Test>());
public void TestRegisterTypeWithoutInterface() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<Test>()));
[Test]
public void TestRegisterMultiton() => Assert.DoesNotThrow(() => _iocContainer.RegisterMultiton<ITest, Test, MultitonScope>());
public void TestRegisterMultiton() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>()));
[Test]
public void TestInvalidMultitonRegistration() => Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register<ITest, Test>(Lifestyle.Multiton));
public void TestInvalidMultitonRegistration() => Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Multiton)));
[Test]
public void TestRegisterMultiple()
{
_iocContainer.Register<ITest, Test>();
MultipleRegistrationException exception = Assert.Throws<MultipleRegistrationException>(() => _iocContainer.Register<ITest, TestConstructor>());
_iocContainer.Register(r => r.Add<ITest, Test>());
MultipleRegistrationException exception = Assert.Throws<MultipleRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, TestConstructor>()));
Assert.AreEqual(typeof(ITest), exception?.Type);
}
@ -162,7 +163,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolve()
{
_iocContainer.Register<ITest, Test>();
_iocContainer.Register(r => r.Add<ITest, Test>());
ITest resolvedTest = _iocContainer.Resolve<ITest>();
@ -172,7 +173,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveWithoutInterface()
{
_iocContainer.Register<Test>();
_iocContainer.Register(r => r.Add<Test>());
Test resolvedTest = _iocContainer.Resolve<Test>();
@ -182,14 +183,14 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveInterfaceWithoutImplementation()
{
_iocContainer.Register<ITest>();
_iocContainer.Register(r => r.Add<ITest>());
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Resolve<ITest>());
}
[Test]
public void TestResolveImplementationRegisteredWithInterface()
{
_iocContainer.Register<ITest, Test>();
_iocContainer.Register(r => r.Add<ITest, Test>());
Test resolvedTest = _iocContainer.Resolve<Test>();
@ -199,7 +200,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveWithParams()
{
_iocContainer.Register<ITest, TestConstructor>();
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
ITest resolvedTest = _iocContainer.Resolve<ITest>("Test", new Test());
@ -209,8 +210,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveWithMissingParam()
{
_iocContainer.Register<ITest, TestConstructor>();
_iocContainer.Register<Test, Test>(); //this registration is abnormal and should only be used in unit tests
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
_iocContainer.Register(r => r.Add<Test, Test>()); //this registration is abnormal and should only be used in unit tests
ITest resolvedTest = _iocContainer.Resolve<ITest>("Test");
@ -220,7 +221,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveSingleton()
{
_iocContainer.Register<ITest, Test>(Lifestyle.Singleton);
_iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Singleton));
ITest resolvedTest = _iocContainer.Resolve<ITest>();
ITest secondResolvedTest = _iocContainer.Resolve<ITest>();
@ -231,7 +232,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveMultiton()
{
_iocContainer.RegisterMultiton<ITest, Test, MultitonScope>();
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
MultitonScope scope1 = new();
MultitonScope scope2 = new();
@ -248,7 +249,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveMultitonNoArgs()
{
_iocContainer.RegisterMultiton<ITest, Test, MultitonScope>();
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
MultitonResolveException exception = Assert.Throws<MultitonResolveException>(() => _iocContainer.Resolve<ITest>());
Assert.AreEqual(typeof(ITest), exception?.Type);
@ -257,7 +258,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveMultitonWrongArgs()
{
_iocContainer.RegisterMultiton<ITest, Test, MultitonScope>();
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
MultitonResolveException exception = Assert.Throws<MultitonResolveException>(() => _iocContainer.Resolve<ITest>(new object()));
Assert.AreEqual(typeof(ITest), exception?.Type);
@ -266,7 +267,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveTransient()
{
_iocContainer.Register<ITest, Test>();
_iocContainer.Register(r => r.Add<ITest, Test>());
ITest resolvedTest = _iocContainer.Resolve<ITest>();
ITest secondResolvedTest = _iocContainer.Resolve<ITest>();
@ -277,7 +278,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveNoMatchingConstructor()
{
_iocContainer.Register<ITest, TestConstructor>();
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
NoMatchingConstructorFoundException exception = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<ITest>());
Assert.AreEqual(typeof(TestConstructor), exception?.Type);
}
@ -285,14 +286,14 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveNoMatchingConstructorNotThrownWrongly()
{
_iocContainer.Register<ITest, TestMultipleConstructors>();
_iocContainer.Register(r => r.Add<ITest, TestMultipleConstructors>());
Assert.DoesNotThrow(() => _iocContainer.Resolve<ITest>("Name"));
}
[Test]
public void TestResolvePrivateConstructor()
{
_iocContainer.Register<ITest, TestPrivateConstructor>();
_iocContainer.Register(r => r.Add<ITest, TestPrivateConstructor>());
NoPublicConstructorFoundException exception = Assert.Throws<NoPublicConstructorFoundException>(() => _iocContainer.Resolve<ITest>());
Assert.AreEqual(typeof(TestPrivateConstructor), exception?.Type);
}
@ -300,8 +301,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveSingleTypeRegistrationWithFactoryMethod()
{
_iocContainer.Register<IFoo, Foo>();
_iocContainer.Register<ITest>().WithFactoryMethod(c => new TestConstructor(c.Resolve<IFoo>(), "someName"));
_iocContainer.Register(r => r.Add<IFoo, Foo>());
_iocContainer.Register(r => r.Add<ITest>().WithFactoryMethod(c => new TestConstructor(c.Resolve<IFoo>(), "someName")));
ITest test = _iocContainer.Resolve<ITest>();
@ -311,8 +312,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveParameterIsRegisteredWithParameters()
{
_iocContainer.Register<ITest, TestConstructor>();
_iocContainer.Register<IFoo, FooConstructor>().WithParameters("TestString");
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
_iocContainer.Register(r => r.Add<IFoo, FooConstructor>().WithParameters("TestString"));
ITest test = _iocContainer.Resolve<ITest>("testName");
@ -322,8 +323,8 @@ namespace Test.LightweightIocContainer
[Test]
public void TestResolveParameterWithParameterThatIsAlreadyExistingSingleton()
{
_iocContainer.Register<ITest, TestWithFoo>();
_iocContainer.Register<IFoo, FooConstructor>(Lifestyle.Singleton).WithParameters("TestString");
_iocContainer.Register(r => r.Add<ITest, TestWithFoo>());
_iocContainer.Register(r => r.Add<IFoo, FooConstructor>(Lifestyle.Singleton).WithParameters("TestString"));
IFoo foo = _iocContainer.Resolve<IFoo>();
ITest test = _iocContainer.Resolve<ITest>("testName");
@ -337,10 +338,10 @@ namespace Test.LightweightIocContainer
{
Assert.False(_iocContainer.IsTypeRegistered<ITest>());
_iocContainer.Register<ITest, Test>();
_iocContainer.Register(r => r.Add<ITest, Test>());
Assert.True(_iocContainer.IsTypeRegistered<ITest>());
_iocContainer.Register<Test>();
_iocContainer.Register(r => r.Add<Test>());
Assert.True(_iocContainer.IsTypeRegistered<Test>());
}
}

@ -6,8 +6,8 @@ using System;
using JetBrains.Annotations;
using LightweightIocContainer;
using LightweightIocContainer.Exceptions;
using LightweightIocContainer.Interfaces;
using LightweightIocContainer.Interfaces.Installers;
using LightweightIocContainer.Interfaces.Registrations;
using LightweightIocContainer.Validation;
using Moq;
using NUnit.Framework;
@ -47,12 +47,12 @@ namespace Test.LightweightIocContainer
private class TestInstaller : IIocInstaller
{
public void Install(IIocContainer container) => container.Register<ITest, Test>().WithFactory<ITestFactory>();
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<ITestFactory>();
}
private class InvalidTestInstaller : IIocInstaller
{
public void Install(IIocContainer container) => container.Register<ITest, Test>().WithFactory<IInvalidFactory>();
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<IInvalidFactory>();
}
[Test]

@ -64,8 +64,8 @@ public class MultiLayerResolveTest
public void TestResolveFactoryAsCtorParameter()
{
IocContainer container = new();
container.Register<IA, A>().WithFactory<IAFactory>();
container.Register<IB, B>().WithFactory<IBFactory>();
container.Register(r => r.Add<IA, A>().WithFactory<IAFactory>());
container.Register(r => r.Add<IB, B>().WithFactory<IBFactory>());
IA a = container.Resolve<IA>();
Assert.IsInstanceOf<A>(a);
@ -75,9 +75,9 @@ public class MultiLayerResolveTest
public void TestResolveSingleTypeRegistrationAsCtorParameter()
{
IocContainer container = new();
container.Register<IA, A>();
container.Register<IB, B>().WithFactory<IBFactory>();
container.Register<C>().WithFactoryMethod(_ => new C("test"));
container.Register(r => r.Add<IA, A>());
container.Register(r => r.Add<IB, B>().WithFactory<IBFactory>());
container.Register(r => r.Add<C>().WithFactoryMethod(_ => new C("test")));
IB b = container.Resolve<IB>();
Assert.IsInstanceOf<B>(b);

@ -48,7 +48,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegisterAndResolveMultipleMultitonRegistration()
{
_iocContainer.RegisterMultiton<IProvider, ITest, Test, MultitonScope>();
_iocContainer.Register(r => r.AddMultiton<IProvider, ITest, Test, MultitonScope>());
MultitonScope scope = new();
@ -64,7 +64,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegisterAndResolveMultipleMultitonRegistrationWithDifferentScope()
{
_iocContainer.RegisterMultiton<IProvider, ITest, Test, MultitonScope>();
_iocContainer.Register(r => r.AddMultiton<IProvider, ITest, Test, MultitonScope>());
MultitonScope scope = new();
MultitonScope differentScope = new();
@ -82,7 +82,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestMultipleMultitonRegistrationOnCreate()
{
_iocContainer.RegisterMultiton<IProvider, ITest, Test, MultitonScope>().OnCreate(t => t.DoSomething(1));
_iocContainer.Register(r => r.AddMultiton<IProvider, ITest, Test, MultitonScope>().OnCreate(t => t.DoSomething(1)));
MultitonScope scope = new();

@ -31,9 +31,9 @@ namespace Test.LightweightIocContainer
RegistrationFactory registrationFactory = new(new Mock<IocContainer>().Object);
ITypedRegistration<ITest, Test> testRegistration = registrationFactory.Register<ITest, Test>(Lifestyle.Transient).OnCreate(t => t.DoSomething());
Test test = new Test();
Test test = new();
Assert.Throws<Exception>(() => testRegistration.OnCreateAction(test));
Assert.Throws<Exception>(() => testRegistration.OnCreateAction!(test));
}
}
}

@ -37,7 +37,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegisterOpenGenericType()
{
_iocContainer.RegisterOpenGenerics(typeof(ITest<>), typeof(Test<>));
_iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>)));
ITest<int> test = _iocContainer.Resolve<ITest<int>>();
Assert.NotNull(test);
@ -46,7 +46,7 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegisterOpenGenericTypeAsSingleton()
{
_iocContainer.RegisterOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Singleton);
_iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Singleton));
ITest<int> test = _iocContainer.Resolve<ITest<int>>();
Assert.NotNull(test);
@ -60,10 +60,10 @@ namespace Test.LightweightIocContainer
[Test]
public void TestRegisterOpenGenericTypeAsMultitonThrowsException() =>
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.RegisterOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Multiton));
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Multiton)));
[Test]
public void TestRegisterNonOpenGenericTypeWithOpenGenericsFunctionThrowsException() =>
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.RegisterOpenGenerics(typeof(int), typeof(int)));
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(int), typeof(int))));
}
}

@ -60,7 +60,7 @@ namespace Test.LightweightIocContainer
RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters(bar, test);
Assert.AreEqual(bar, testRegistration.Parameters[0]);
Assert.AreEqual(bar, testRegistration.Parameters![0]);
Assert.AreEqual(test, testRegistration.Parameters[1]);
}
@ -74,7 +74,7 @@ namespace Test.LightweightIocContainer
RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register<IFoo, Foo>(Lifestyle.Transient).WithParameters((0, bar), (3, test), (2, "SomeString"));
Assert.AreEqual(bar, testRegistration.Parameters[0]);
Assert.AreEqual(bar, testRegistration.Parameters![0]);
Assert.IsInstanceOf<InternalResolvePlaceholder>(testRegistration.Parameters[1]);
Assert.AreEqual("SomeString", testRegistration.Parameters[2]);
Assert.AreEqual(test, testRegistration.Parameters[3]);

@ -50,17 +50,17 @@ namespace Test.LightweightIocContainer
RegistrationFactory registrationFactory = new(iocContainerMock.Object);
ISingleTypeRegistration<IFoo> registration = registrationFactory.Register<IFoo>(Lifestyle.Transient).WithFactoryMethod(c => new Foo(c.Resolve<IBar>()));
IFoo foo = registration.FactoryMethod(iocContainerMock.Object);
IFoo foo = registration.FactoryMethod!(iocContainerMock.Object);
Assert.AreEqual(bar, foo.Bar);
}
[Test]
public void TestSingleTypeRegistrationResolveSingleton()
{
IocContainer container = new IocContainer();
IocContainer container = new();
IBar bar = new Bar();
container.Register<IFoo>(Lifestyle.Singleton).WithFactoryMethod(_ => new Foo(bar));
container.Register(r => r.Add<IFoo>(Lifestyle.Singleton).WithFactoryMethod(_ => new Foo(bar)));
IFoo foo = container.Resolve<IFoo>();

Loading…
Cancel
Save