diff --git a/LightweightIocContainer/ActionExtension.cs b/LightweightIocContainer/ActionExtension.cs index 10dd279..db5a6e6 100644 --- a/LightweightIocContainer/ActionExtension.cs +++ b/LightweightIocContainer/ActionExtension.cs @@ -4,23 +4,22 @@ using System; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +internal static class ActionExtension { - internal static class ActionExtension + /// + /// Convert an to an of an inherited + /// + /// The of the to convert to, has to be implemented by + /// The of the given , has to implement + /// The given to convert + /// An converted from the given + public static Action? Convert(this Action? action) where T1 : T2 { - /// - /// Convert an to an of an inherited - /// - /// The of the to convert to, has to be implemented by - /// The of the given , has to implement - /// The given to convert - /// An converted from the given - public static Action? Convert(this Action? action) where T1 : T2 - { - if (action == null) - return null; + if (action == null) + return null; - return t => action(t); - } + return t => action(t); } } \ No newline at end of file diff --git a/LightweightIocContainer/EnumerableExtension.cs b/LightweightIocContainer/EnumerableExtension.cs index 16ec33e..8906fa8 100644 --- a/LightweightIocContainer/EnumerableExtension.cs +++ b/LightweightIocContainer/EnumerableExtension.cs @@ -6,61 +6,60 @@ using System; using System.Collections.Generic; using System.Linq; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +internal static class EnumerableExtension { - internal static class EnumerableExtension - { - /// - /// Returns the first element of a , or a new instance of a given if the contains no elements - /// - /// The source of the - /// The given to return if the contains no elements - /// The given - /// The first element of the , or a new instance of a given if the contains no elements - public static TSource FirstOrGiven(this IEnumerable source) where TGiven : TSource, new() => - source.TryGetFirst(null); + /// + /// Returns the first element of a , or a new instance of a given if the contains no elements + /// + /// The source of the + /// The given to return if the contains no elements + /// The given + /// The first element of the , or a new instance of a given if the contains no elements + public static TSource FirstOrGiven(this IEnumerable source) where TGiven : TSource, new() => + source.TryGetFirst(null); - /// - /// Returns the first element of a that satisfies a condition, or a new instance of a given if no such element is found - /// - /// The source of the - /// The given to return if the contains no element that satisfies the given condition - /// The given - /// A function to test each element for a condition - /// The first element of the that satisfies a condition, or a new instance of the given if no such element is found - public static TSource FirstOrGiven(this IEnumerable source, Func predicate) where TGiven : TSource, new() => - source.TryGetFirst(predicate); + /// + /// Returns the first element of a that satisfies a condition, or a new instance of a given if no such element is found + /// + /// The source of the + /// The given to return if the contains no element that satisfies the given condition + /// The given + /// A function to test each element for a condition + /// The first element of the that satisfies a condition, or a new instance of the given if no such element is found + public static TSource FirstOrGiven(this IEnumerable source, Func predicate) where TGiven : TSource, new() => + source.TryGetFirst(predicate); - /// - /// Tries to get the first element of the given or creates a new element of a given when no element is found - /// - /// The source of the - /// The given to create a new element when no fitting element is found - /// The given - /// A function to test each element for a condition - /// The first element of the or a new instance of the given when no element is found - private static TSource TryGetFirst(this IEnumerable source, Func? predicate) where TGiven : TSource, new() + /// + /// Tries to get the first element of the given or creates a new element of a given when no element is found + /// + /// The source of the + /// The given to create a new element when no fitting element is found + /// The given + /// A function to test each element for a condition + /// The first element of the or a new instance of the given when no element is found + private static TSource TryGetFirst(this IEnumerable source, Func? predicate) where TGiven : TSource, new() + { + try { - try - { - return predicate == null ? source.First() : source.First(predicate); - } - catch (Exception) - { - return new TGiven(); - } + return predicate == null ? source.First() : source.First(predicate); } - - /// - /// Executes an for each item in an - /// - /// The - /// The - /// The of the items in the - public static void ForEach(this IEnumerable enumerable, Action action) + catch (Exception) { - foreach (T item in enumerable) - action(item); + return new TGiven(); } } + + /// + /// Executes an for each item in an + /// + /// The + /// The + /// The of the items in the + public static void ForEach(this IEnumerable enumerable, Action action) + { + foreach (T item in enumerable) + action(item); + } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/CircularDependencyException.cs b/LightweightIocContainer/Exceptions/CircularDependencyException.cs index 6d9f064..f205462 100644 --- a/LightweightIocContainer/Exceptions/CircularDependencyException.cs +++ b/LightweightIocContainer/Exceptions/CircularDependencyException.cs @@ -7,55 +7,54 @@ using System.Collections.Generic; using System.Linq; using System.Text; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// A circular dependency was detected during +/// +internal class CircularDependencyException : IocContainerException { /// /// A circular dependency was detected during /// - internal class CircularDependencyException : IocContainerException + /// The currently resolving + /// The resolve stack at the time the was thrown + public CircularDependencyException(Type resolvingType, List resolveStack) { - /// - /// A circular dependency was detected during - /// - /// The currently resolving - /// The resolve stack at the time the was thrown - public CircularDependencyException(Type resolvingType, List resolveStack) - { - ResolvingType = resolvingType; - ResolveStack = resolveStack; - } + ResolvingType = resolvingType; + ResolveStack = resolveStack; + } - /// - /// The currently resolving - /// - public Type ResolvingType { get; } + /// + /// The currently resolving + /// + public Type ResolvingType { get; } - /// - /// The resolve stack at the time the was thrown - /// - public List ResolveStack { get; } + /// + /// The resolve stack at the time the was thrown + /// + public List ResolveStack { get; } - /// - /// The exception message - /// - public override string Message + /// + /// The exception message + /// + public override string Message + { + get { - get - { - StringBuilder message = new($"Circular dependency has been detected when trying to resolve `{ResolvingType}`.\n"); - if (!ResolveStack.Any()) - return message.ToString(); + StringBuilder message = new($"Circular dependency has been detected when trying to resolve `{ResolvingType}`.\n"); + if (!ResolveStack.Any()) + return message.ToString(); - message.Append("Resolve stack that resulted in the circular dependency:\n"); - message.Append($"\t`{ResolvingType}` resolved as dependency of\n"); + message.Append("Resolve stack that resulted in the circular dependency:\n"); + message.Append($"\t`{ResolvingType}` resolved as dependency of\n"); - for (int i = ResolveStack.Count - 1; i >= 1 ; i--) - message.Append($"\t`{ResolveStack[i]}` resolved as dependency of\n"); + for (int i = ResolveStack.Count - 1; i >= 1 ; i--) + message.Append($"\t`{ResolveStack[i]}` resolved as dependency of\n"); - message.Append($"\t`{ResolveStack[0]}` which is the root type being resolved."); - return message.ToString(); - } + message.Append($"\t`{ResolveStack[0]}` which is the root type being resolved."); + return message.ToString(); } } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/ConstructorNotMatchingException.cs b/LightweightIocContainer/Exceptions/ConstructorNotMatchingException.cs index ef01735..a8fde2d 100644 --- a/LightweightIocContainer/Exceptions/ConstructorNotMatchingException.cs +++ b/LightweightIocContainer/Exceptions/ConstructorNotMatchingException.cs @@ -5,25 +5,24 @@ using System; using System.Reflection; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The constructor does not match the given or resolvable arguments +/// +internal class ConstructorNotMatchingException : IocContainerException { /// /// The constructor does not match the given or resolvable arguments /// - internal class ConstructorNotMatchingException : IocContainerException - { - /// - /// The constructor does not match the given or resolvable arguments - /// - /// The constructor that does not match - /// The inner exception - public ConstructorNotMatchingException(ConstructorInfo constructor, Exception exception) - : base($"Constructor {constructor} does not match the given or resolvable arguments.", exception) => - Constructor = constructor; + /// The constructor that does not match + /// The inner exception + public ConstructorNotMatchingException(ConstructorInfo constructor, Exception exception) + : base($"Constructor {constructor} does not match the given or resolvable arguments.", exception) => + Constructor = constructor; - /// - /// The constructor that does not match - /// - public ConstructorInfo Constructor { get; } - } + /// + /// The constructor that does not match + /// + public ConstructorInfo Constructor { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/GenericMethodNotFoundException.cs b/LightweightIocContainer/Exceptions/GenericMethodNotFoundException.cs index 8346587..de445ed 100644 --- a/LightweightIocContainer/Exceptions/GenericMethodNotFoundException.cs +++ b/LightweightIocContainer/Exceptions/GenericMethodNotFoundException.cs @@ -4,21 +4,20 @@ using System; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// Could not find generic method +/// +internal class GenericMethodNotFoundException : Exception { /// /// Could not find generic method /// - internal class GenericMethodNotFoundException : Exception + /// The name of the generic method + public GenericMethodNotFoundException(string functionName) + : base($"Could not find function {functionName}") { - /// - /// Could not find generic method - /// - /// The name of the generic method - public GenericMethodNotFoundException(string functionName) - : base($"Could not find function {functionName}") - { - } } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs b/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs index fbafcb7..105f1fd 100644 --- a/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs +++ b/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs @@ -4,25 +4,24 @@ using System.Reflection; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The creation of the abstract method is illegal in its current state +/// +internal class IllegalAbstractMethodCreationException : IocContainerException { /// /// The creation of the abstract method is illegal in its current state /// - internal class IllegalAbstractMethodCreationException : IocContainerException - { - /// - /// The creation of the abstract method is illegal in its current state - /// - /// The exception message - /// The method that is illegal to create - public IllegalAbstractMethodCreationException(string message, MethodInfo method) - : base(message) => - Method = method; + /// The exception message + /// The method that is illegal to create + public IllegalAbstractMethodCreationException(string message, MethodInfo method) + : base(message) => + Method = method; - /// - /// The Method whose creation is illegal - /// - public MethodInfo Method { get; } - } + /// + /// The Method whose creation is illegal + /// + public MethodInfo Method { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/InternalResolveException.cs b/LightweightIocContainer/Exceptions/InternalResolveException.cs index ecfe4e4..06a605e 100644 --- a/LightweightIocContainer/Exceptions/InternalResolveException.cs +++ b/LightweightIocContainer/Exceptions/InternalResolveException.cs @@ -4,21 +4,20 @@ using LightweightIocContainer.Interfaces; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// An internal Error happened while the tried to resolve an instance +/// +internal class InternalResolveException : IocContainerException { /// /// An internal Error happened while the tried to resolve an instance /// - internal class InternalResolveException : IocContainerException + /// The exception message + public InternalResolveException(string message) + : base(message) { - /// - /// An internal Error happened while the tried to resolve an instance - /// - /// The exception message - public InternalResolveException(string message) - : base(message) - { - } } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/InvalidFactoryRegistrationException.cs b/LightweightIocContainer/Exceptions/InvalidFactoryRegistrationException.cs index a34bbd5..ca73d51 100644 --- a/LightweightIocContainer/Exceptions/InvalidFactoryRegistrationException.cs +++ b/LightweightIocContainer/Exceptions/InvalidFactoryRegistrationException.cs @@ -2,21 +2,20 @@ // Created: 2019-05-20 // Copyright(c) 2019 SimonG. All Rights Reserved. -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The registration of a Factory is not valid +/// +internal class InvalidFactoryRegistrationException : InvalidRegistrationException { /// /// The registration of a Factory is not valid /// - internal class InvalidFactoryRegistrationException : InvalidRegistrationException + /// The exception message + public InvalidFactoryRegistrationException(string message) + : base(message) { - /// - /// The registration of a Factory is not valid - /// - /// The exception message - public InvalidFactoryRegistrationException(string message) - : base(message) - { - } } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/InvalidRegistrationException.cs b/LightweightIocContainer/Exceptions/InvalidRegistrationException.cs index 11753bc..5a7db53 100644 --- a/LightweightIocContainer/Exceptions/InvalidRegistrationException.cs +++ b/LightweightIocContainer/Exceptions/InvalidRegistrationException.cs @@ -2,21 +2,20 @@ // Created: 2019-05-20 // Copyright(c) 2019 SimonG. All Rights Reserved. -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The registration is not valid +/// +internal class InvalidRegistrationException : IocContainerException { /// /// The registration is not valid /// - internal class InvalidRegistrationException : IocContainerException + /// The exception message + public InvalidRegistrationException(string message) + : base(message) { - /// - /// The registration is not valid - /// - /// The exception message - public InvalidRegistrationException(string message) - : base(message) - { - } } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/IocContainerException.cs b/LightweightIocContainer/Exceptions/IocContainerException.cs index c021abb..8ed1d21 100644 --- a/LightweightIocContainer/Exceptions/IocContainerException.cs +++ b/LightweightIocContainer/Exceptions/IocContainerException.cs @@ -5,38 +5,37 @@ using System; using System.Collections.Generic; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// A base for the +/// +public abstract class IocContainerException : Exception { /// /// A base for the /// - public abstract class IocContainerException : Exception - { - /// - /// A base for the - /// - protected IocContainerException() => InnerExceptions = new List(); + protected IocContainerException() => InnerExceptions = new List(); - /// - /// A base for the - /// - /// The message of the - protected IocContainerException(string message) - : base(message) => - InnerExceptions = new List(); + /// + /// A base for the + /// + /// The message of the + protected IocContainerException(string message) + : base(message) => + InnerExceptions = new List(); - /// - /// A base for the - /// - /// The message of the - /// The inner - protected IocContainerException(string message, Exception innerException) - : base(message, innerException) => - InnerExceptions = new List {innerException}; + /// + /// A base for the + /// + /// The message of the + /// The inner + protected IocContainerException(string message, Exception innerException) + : base(message, innerException) => + InnerExceptions = new List {innerException}; - /// - /// The inner exceptions of the - /// - public List InnerExceptions { get; protected init; } - } + /// + /// The inner exceptions of the + /// + public List InnerExceptions { get; protected init; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs b/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs index d64a728..f1bb289 100644 --- a/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs +++ b/LightweightIocContainer/Exceptions/MultipleRegistrationException.cs @@ -5,24 +5,23 @@ using System; using LightweightIocContainer.Interfaces; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The is already registered differently in this +/// +internal class MultipleRegistrationException : IocContainerException { /// /// The is already registered differently in this /// - internal class MultipleRegistrationException : IocContainerException - { - /// - /// The is already registered differently in this - /// - /// The that is already registered in this - public MultipleRegistrationException(Type type) - : base($"Type {type.Name} is already registered differently in this IocContainer.") => - Type = type; + /// The that is already registered in this + public MultipleRegistrationException(Type type) + : base($"Type {type.Name} is already registered differently in this IocContainer.") => + Type = type; - /// - /// The registered - /// - public Type Type { get; } - } + /// + /// The registered + /// + public Type Type { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/MultitonResolveException.cs b/LightweightIocContainer/Exceptions/MultitonResolveException.cs index b7034a0..aeb514e 100644 --- a/LightweightIocContainer/Exceptions/MultitonResolveException.cs +++ b/LightweightIocContainer/Exceptions/MultitonResolveException.cs @@ -4,25 +4,24 @@ using System; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// An error happened while trying to resolve a multiton +/// +internal class MultitonResolveException : InternalResolveException { /// /// An error happened while trying to resolve a multiton /// - internal class MultitonResolveException : InternalResolveException - { - /// - /// An error happened while trying to resolve a multiton - /// - /// The exception message - /// The of the multiton that's responsible for the exception - public MultitonResolveException(string message, Type type) - : base(message) => - Type = type; + /// The exception message + /// The of the multiton that's responsible for the exception + public MultitonResolveException(string message, Type type) + : base(message) => + Type = type; - /// - /// The of the multiton that's responsible for the exception - /// - public Type Type { get; } - } + /// + /// The of the multiton that's responsible for the exception + /// + public Type Type { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/NoMatchingConstructorFoundException.cs b/LightweightIocContainer/Exceptions/NoMatchingConstructorFoundException.cs index b49ff68..c38a002 100644 --- a/LightweightIocContainer/Exceptions/NoMatchingConstructorFoundException.cs +++ b/LightweightIocContainer/Exceptions/NoMatchingConstructorFoundException.cs @@ -5,34 +5,33 @@ using System; using System.Collections.Generic; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// No matching constructor was found for the given or resolvable arguments +/// +internal class NoMatchingConstructorFoundException : IocContainerException { /// /// No matching constructor was found for the given or resolvable arguments /// - internal class NoMatchingConstructorFoundException : IocContainerException + /// The with no matching constructor + public NoMatchingConstructorFoundException(Type type) + : base($"No matching constructor for {type} found.") { - /// - /// No matching constructor was found for the given or resolvable arguments - /// - /// The with no matching constructor - public NoMatchingConstructorFoundException(Type type) - : base($"No matching constructor for {type} found.") - { - Type = type; - InnerExceptions = new List(); - } + Type = type; + InnerExceptions = new List(); + } - /// - /// The with no matching constructor - /// - public Type Type { get; } + /// + /// The with no matching constructor + /// + public Type Type { get; } - /// - /// Add an inner exception to the - /// - /// The - public void AddInnerException(ConstructorNotMatchingException exception) => InnerExceptions.Add(exception); - } + /// + /// Add an inner exception to the + /// + /// The + public void AddInnerException(ConstructorNotMatchingException exception) => InnerExceptions.Add(exception); } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/NoPublicConstructorFoundException.cs b/LightweightIocContainer/Exceptions/NoPublicConstructorFoundException.cs index 932b020..ec32547 100644 --- a/LightweightIocContainer/Exceptions/NoPublicConstructorFoundException.cs +++ b/LightweightIocContainer/Exceptions/NoPublicConstructorFoundException.cs @@ -4,24 +4,23 @@ using System; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// No public constructor can be found for a +/// +internal class NoPublicConstructorFoundException : IocContainerException { /// /// No public constructor can be found for a /// - internal class NoPublicConstructorFoundException : IocContainerException - { - /// - /// No public constructor can be found for a - /// - /// The with no public constructor - public NoPublicConstructorFoundException(Type type) - : base($"No public constructor for {type} found.") => - Type = type; + /// The with no public constructor + public NoPublicConstructorFoundException(Type type) + : base($"No public constructor for {type} found.") => + Type = type; - /// - /// The with no public constructor - /// - public Type Type { get; } - } + /// + /// The with no public constructor + /// + public Type Type { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/TypeNotRegisteredException.cs b/LightweightIocContainer/Exceptions/TypeNotRegisteredException.cs index 11056b7..a477d23 100644 --- a/LightweightIocContainer/Exceptions/TypeNotRegisteredException.cs +++ b/LightweightIocContainer/Exceptions/TypeNotRegisteredException.cs @@ -5,24 +5,23 @@ using System; using LightweightIocContainer.Interfaces; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// The is not registered in this +/// +internal class TypeNotRegisteredException : IocContainerException { /// /// The is not registered in this /// - internal class TypeNotRegisteredException : IocContainerException - { - /// - /// The is not registered in this - /// - /// The unregistered - public TypeNotRegisteredException(Type type) - : base($"Type {type.Name} is not registered in this IocContainer.") => - Type = type; + /// The unregistered + public TypeNotRegisteredException(Type type) + : base($"Type {type.Name} is not registered in this IocContainer.") => + Type = type; - /// - /// The unregistered - /// - public Type Type { get; } - } + /// + /// The unregistered + /// + public Type Type { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Exceptions/UnknownRegistrationException.cs b/LightweightIocContainer/Exceptions/UnknownRegistrationException.cs index cc1a290..8ae5809 100644 --- a/LightweightIocContainer/Exceptions/UnknownRegistrationException.cs +++ b/LightweightIocContainer/Exceptions/UnknownRegistrationException.cs @@ -4,21 +4,20 @@ using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Exceptions +namespace LightweightIocContainer.Exceptions; + +/// +/// An unknown was used +/// +internal class UnknownRegistrationException : IocContainerException { /// /// An unknown was used /// - internal class UnknownRegistrationException : IocContainerException + /// The exception message + public UnknownRegistrationException(string message) + : base(message) { - /// - /// An unknown was used - /// - /// The exception message - public UnknownRegistrationException(string message) - : base(message) - { - } } } \ No newline at end of file diff --git a/LightweightIocContainer/Factories/CustomTypedFactory.cs b/LightweightIocContainer/Factories/CustomTypedFactory.cs index 67fa08c..e13a4d3 100644 --- a/LightweightIocContainer/Factories/CustomTypedFactory.cs +++ b/LightweightIocContainer/Factories/CustomTypedFactory.cs @@ -4,13 +4,12 @@ using LightweightIocContainer.Interfaces.Factories; -namespace LightweightIocContainer.Factories +namespace LightweightIocContainer.Factories; + +/// +/// implementation for custom implemented factories +/// +public class CustomTypedFactory : TypedFactoryBase { - /// - /// implementation for custom implemented factories - /// - public class CustomTypedFactory : TypedFactoryBase - { - } } \ No newline at end of file diff --git a/LightweightIocContainer/Factories/TypedFactory.cs b/LightweightIocContainer/Factories/TypedFactory.cs index ddd0c16..b89c7ba 100644 --- a/LightweightIocContainer/Factories/TypedFactory.cs +++ b/LightweightIocContainer/Factories/TypedFactory.cs @@ -10,133 +10,132 @@ using LightweightIocContainer.Exceptions; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Factories; -namespace LightweightIocContainer.Factories +namespace LightweightIocContainer.Factories; + +/// +/// Class to help implement an abstract typed factory +/// +/// The type of the abstract factory +public class TypedFactory : TypedFactoryBase, ITypedFactory { + private const string CLEAR_MULTITON_INSTANCE_METHOD_NAME = "ClearMultitonInstance"; + /// - /// Class to help implement an abstract typed factory + /// The /// - /// The type of the abstract factory - public class TypedFactory : TypedFactoryBase, ITypedFactory - { - private const string CLEAR_MULTITON_INSTANCE_METHOD_NAME = "ClearMultitonInstance"; - - /// - /// The - /// - /// The current instance of the - public TypedFactory(IocContainer container) => Factory = CreateFactory(container); - - /// - /// The implemented abstract typed factory/> - /// - public TFactory Factory { get; set; } + /// The current instance of the + public TypedFactory(IocContainer container) => Factory = CreateFactory(container); + + /// + /// The implemented abstract typed factory/> + /// + public TFactory Factory { get; set; } - /// - /// Creates the factory from the given abstract factory type - /// - /// Factory registration is invalid - /// Creation of abstract methods are illegal in their current state - private TFactory CreateFactory(IocContainer container) - { - Type factoryType = typeof(TFactory); + /// + /// Creates the factory from the given abstract factory type + /// + /// Factory registration is invalid + /// Creation of abstract methods are illegal in their current state + private TFactory CreateFactory(IocContainer container) + { + Type factoryType = typeof(TFactory); - AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Factory"), AssemblyBuilderAccess.Run); - ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Factory"); - TypeBuilder typeBuilder = moduleBuilder.DefineType($"TypedFactory.{factoryType.Name}"); + AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Factory"), AssemblyBuilderAccess.Run); + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Factory"); + TypeBuilder typeBuilder = moduleBuilder.DefineType($"TypedFactory.{factoryType.Name}"); - typeBuilder.AddInterfaceImplementation(factoryType); + typeBuilder.AddInterfaceImplementation(factoryType); - //add `private readonly IIocContainer _container` field - FieldBuilder containerFieldBuilder = typeBuilder.DefineField("_container", typeof(IocContainer), FieldAttributes.Private | FieldAttributes.InitOnly); + //add `private readonly IIocContainer _container` field + FieldBuilder containerFieldBuilder = typeBuilder.DefineField("_container", typeof(IocContainer), FieldAttributes.Private | FieldAttributes.InitOnly); - //add ctor - ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] {typeof(IocContainer)}); - ILGenerator constructorGenerator = constructorBuilder.GetILGenerator(); - constructorGenerator.Emit(OpCodes.Ldarg_0); - constructorGenerator.Emit(OpCodes.Ldarg_1); - constructorGenerator.Emit(OpCodes.Stfld, containerFieldBuilder); //set `_container` field - constructorGenerator.Emit(OpCodes.Ret); + //add ctor + ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] {typeof(IocContainer)}); + ILGenerator constructorGenerator = constructorBuilder.GetILGenerator(); + constructorGenerator.Emit(OpCodes.Ldarg_0); + constructorGenerator.Emit(OpCodes.Ldarg_1); + constructorGenerator.Emit(OpCodes.Stfld, containerFieldBuilder); //set `_container` field + constructorGenerator.Emit(OpCodes.Ret); - foreach (MethodInfo createMethod in CreateMethods) - { - //create a method that looks like this - //public `createMethod.ReturnType` Create(`createMethod.GetParameters()`) - //{ - // return IIocContainer.Resolve(`createMethod.ReturnType`, params); - //} + foreach (MethodInfo createMethod in CreateMethods) + { + //create a method that looks like this + //public `createMethod.ReturnType` Create(`createMethod.GetParameters()`) + //{ + // return IIocContainer.Resolve(`createMethod.ReturnType`, params); + //} - ParameterInfo[] args = createMethod.GetParameters(); + ParameterInfo[] args = createMethod.GetParameters(); - MethodBuilder methodBuilder = typeBuilder.DefineMethod(createMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, - createMethod.ReturnType, (from arg in args select arg.ParameterType).ToArray()); - typeBuilder.DefineMethodOverride(methodBuilder, createMethod); + MethodBuilder methodBuilder = typeBuilder.DefineMethod(createMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, + createMethod.ReturnType, (from arg in args select arg.ParameterType).ToArray()); + typeBuilder.DefineMethodOverride(methodBuilder, createMethod); - ILGenerator generator = methodBuilder.GetILGenerator(); + ILGenerator generator = methodBuilder.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldfld, containerFieldBuilder); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldfld, containerFieldBuilder); - if (args.Any()) - { - generator.Emit(OpCodes.Ldc_I4_S, args.Length); - generator.Emit(OpCodes.Newarr, typeof(object)); - - for (int i = 0; i < args.Length; i++) - { - generator.Emit(OpCodes.Dup); - generator.Emit(OpCodes.Ldc_I4_S, i); - generator.Emit(OpCodes.Ldarg_S, i + 1); - generator.Emit(OpCodes.Box, args[i].ParameterType); //Boxing is only needed for simple datatypes, but for now it is not a problem to box everything - generator.Emit(OpCodes.Stelem_Ref); - } - } - else + if (args.Any()) + { + generator.Emit(OpCodes.Ldc_I4_S, args.Length); + generator.Emit(OpCodes.Newarr, typeof(object)); + + for (int i = 0; i < args.Length; i++) { - MethodInfo emptyArray = typeof(Array).GetMethod(nameof(Array.Empty))!.MakeGenericMethod(typeof(object)); - generator.EmitCall(OpCodes.Call, emptyArray, null); + generator.Emit(OpCodes.Dup); + generator.Emit(OpCodes.Ldc_I4_S, i); + generator.Emit(OpCodes.Ldarg_S, i + 1); + generator.Emit(OpCodes.Box, args[i].ParameterType); //Boxing is only needed for simple datatypes, but for now it is not a problem to box everything + generator.Emit(OpCodes.Stelem_Ref); } - - generator.EmitCall(OpCodes.Call, typeof(IocContainer).GetMethod(nameof(IocContainer.FactoryResolve), new[] { typeof(object[]) })!.MakeGenericMethod(createMethod.ReturnType), null); - generator.Emit(OpCodes.Castclass, createMethod.ReturnType); - generator.Emit(OpCodes.Ret); } - - //if factory contains a method to clear multiton instances - MethodInfo? multitonClearMethod = factoryType.GetMethods().FirstOrDefault(m => m.Name.Equals(CLEAR_MULTITON_INSTANCE_METHOD_NAME)); - if (multitonClearMethod != null) + else { - //create a method that looks like this - //public void ClearMultitonInstance() - //{ - // IIocContainer.ClearMultitonInstances(); - //} + MethodInfo emptyArray = typeof(Array).GetMethod(nameof(Array.Empty))!.MakeGenericMethod(typeof(object)); + generator.EmitCall(OpCodes.Call, emptyArray, null); + } - if (multitonClearMethod.IsGenericMethod) - { - Type? typeToClear = multitonClearMethod.GetGenericArguments().FirstOrDefault(); - if (typeToClear == null) - throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod); + generator.EmitCall(OpCodes.Call, typeof(IocContainer).GetMethod(nameof(IocContainer.FactoryResolve), new[] { typeof(object[]) })!.MakeGenericMethod(createMethod.ReturnType), null); + generator.Emit(OpCodes.Castclass, createMethod.ReturnType); + generator.Emit(OpCodes.Ret); + } - MethodBuilder multitonClearMethodBuilder = typeBuilder.DefineMethod(multitonClearMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, - multitonClearMethod.ReturnType, null); - multitonClearMethodBuilder.DefineGenericParameters(typeToClear.Name); + //if factory contains a method to clear multiton instances + MethodInfo? multitonClearMethod = factoryType.GetMethods().FirstOrDefault(m => m.Name.Equals(CLEAR_MULTITON_INSTANCE_METHOD_NAME)); + if (multitonClearMethod != null) + { + //create a method that looks like this + //public void ClearMultitonInstance() + //{ + // IIocContainer.ClearMultitonInstances(); + //} - typeBuilder.DefineMethodOverride(multitonClearMethodBuilder, multitonClearMethod); + if (multitonClearMethod.IsGenericMethod) + { + Type? typeToClear = multitonClearMethod.GetGenericArguments().FirstOrDefault(); + if (typeToClear == null) + throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod); - ILGenerator multitonClearGenerator = multitonClearMethodBuilder.GetILGenerator(); - multitonClearGenerator.Emit(OpCodes.Ldarg_0); - multitonClearGenerator.Emit(OpCodes.Ldfld, containerFieldBuilder); + MethodBuilder multitonClearMethodBuilder = typeBuilder.DefineMethod(multitonClearMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, + multitonClearMethod.ReturnType, null); + multitonClearMethodBuilder.DefineGenericParameters(typeToClear.Name); - multitonClearGenerator.EmitCall(OpCodes.Call, typeof(IocContainer).GetMethod(nameof(IocContainer.ClearMultitonInstances))!.MakeGenericMethod(typeToClear), null); - multitonClearGenerator.Emit(OpCodes.Ret); - } - else - { - throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod); - } - } + typeBuilder.DefineMethodOverride(multitonClearMethodBuilder, multitonClearMethod); + + ILGenerator multitonClearGenerator = multitonClearMethodBuilder.GetILGenerator(); + multitonClearGenerator.Emit(OpCodes.Ldarg_0); + multitonClearGenerator.Emit(OpCodes.Ldfld, containerFieldBuilder); - return Creator.CreateInstance(typeBuilder.CreateTypeInfo()!.AsType(), container); + multitonClearGenerator.EmitCall(OpCodes.Call, typeof(IocContainer).GetMethod(nameof(IocContainer.ClearMultitonInstances))!.MakeGenericMethod(typeToClear), null); + multitonClearGenerator.Emit(OpCodes.Ret); + } + else + { + throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod); + } } + + return Creator.CreateInstance(typeBuilder.CreateTypeInfo()!.AsType(), container); } } \ No newline at end of file diff --git a/LightweightIocContainer/Factories/TypedFactoryBase.cs b/LightweightIocContainer/Factories/TypedFactoryBase.cs index 73b77db..64a6bea 100644 --- a/LightweightIocContainer/Factories/TypedFactoryBase.cs +++ b/LightweightIocContainer/Factories/TypedFactoryBase.cs @@ -9,28 +9,27 @@ using System.Reflection; using LightweightIocContainer.Exceptions; using LightweightIocContainer.Interfaces.Factories; -namespace LightweightIocContainer.Factories +namespace LightweightIocContainer.Factories; + +/// +/// Base class for the +/// +public abstract class TypedFactoryBase : ITypedFactory { /// - /// Base class for the + /// The create methods of this /// - public abstract class TypedFactoryBase : ITypedFactory + public List CreateMethods { - /// - /// The create methods of this - /// - public List CreateMethods + get { - get - { - Type factoryType = typeof(TFactory); + Type factoryType = typeof(TFactory); - List createMethods = factoryType.GetMethods().Where(m => m.ReturnType != typeof(void)).ToList(); - if (!createMethods.Any()) - throw new InvalidFactoryRegistrationException($"Factory {factoryType.Name} has no create methods."); + List createMethods = factoryType.GetMethods().Where(m => m.ReturnType != typeof(void)).ToList(); + if (!createMethods.Any()) + throw new InvalidFactoryRegistrationException($"Factory {factoryType.Name} has no create methods."); - return createMethods; - } + return createMethods; } } } \ No newline at end of file diff --git a/LightweightIocContainer/GenericMethodCaller.cs b/LightweightIocContainer/GenericMethodCaller.cs index 41c1da2..7a42af0 100644 --- a/LightweightIocContainer/GenericMethodCaller.cs +++ b/LightweightIocContainer/GenericMethodCaller.cs @@ -6,53 +6,52 @@ using System; using System.Reflection; using LightweightIocContainer.Exceptions; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +/// +/// Helper class to call a generic method without generic type parameters +/// +internal static class GenericMethodCaller { /// - /// Helper class to call a generic method without generic type parameters + /// Call a generic method without generic type parameters /// - internal static class GenericMethodCaller + /// The caller of the method + /// The name of the method to call + /// The generic parameter as parameter + /// The to find the method + /// The parameters of the method + /// The result of invoking the method + /// Could not find the generic method + /// Any thrown after invoking the generic method + public static object? Call(object caller, string functionName, Type genericParameter, BindingFlags bindingFlags, params object?[] parameters) { - /// - /// Call a generic method without generic type parameters - /// - /// The caller of the method - /// The name of the method to call - /// The generic parameter as parameter - /// The to find the method - /// The parameters of the method - /// The result of invoking the method - /// Could not find the generic method - /// Any thrown after invoking the generic method - public static object? Call(object caller, string functionName, Type genericParameter, BindingFlags bindingFlags, params object?[] parameters) - { - MethodInfo? method = caller.GetType().GetMethod(functionName, bindingFlags); - MethodInfo? genericMethod = method?.MakeGenericMethod(genericParameter); + MethodInfo? method = caller.GetType().GetMethod(functionName, bindingFlags); + MethodInfo? genericMethod = method?.MakeGenericMethod(genericParameter); - if (genericMethod == null) - throw new GenericMethodNotFoundException(functionName); + if (genericMethod == null) + throw new GenericMethodNotFoundException(functionName); - try //exceptions thrown by methods called with invoke are wrapped into another exception, the exception thrown by the invoked method can be returned by `Exception.GetBaseException()` - { - return genericMethod.Invoke(caller, parameters); - } - catch (Exception ex) - { - throw ex.GetBaseException(); - } + try //exceptions thrown by methods called with invoke are wrapped into another exception, the exception thrown by the invoked method can be returned by `Exception.GetBaseException()` + { + return genericMethod.Invoke(caller, parameters); + } + catch (Exception ex) + { + throw ex.GetBaseException(); } - - /// - /// Call a private generic method without generic type parameters - /// - /// The caller of the method - /// The name of the method to call - /// The generic parameter as parameter - /// The parameters of the method - /// The result of invoking the method - /// Could not find the generic method - /// Any thrown after invoking the generic method - public static object? CallPrivate(object caller, string functionName, Type genericParameter, params object?[] parameters) => - Call(caller, functionName, genericParameter, BindingFlags.NonPublic | BindingFlags.Instance, parameters); } + + /// + /// Call a private generic method without generic type parameters + /// + /// The caller of the method + /// The name of the method to call + /// The generic parameter as parameter + /// The parameters of the method + /// The result of invoking the method + /// Could not find the generic method + /// Any thrown after invoking the generic method + public static object? CallPrivate(object caller, string functionName, Type genericParameter, params object?[] parameters) => + Call(caller, functionName, genericParameter, BindingFlags.NonPublic | BindingFlags.Instance, parameters); } \ No newline at end of file diff --git a/LightweightIocContainer/Installers/AssemblyInstaller.cs b/LightweightIocContainer/Installers/AssemblyInstaller.cs index 414daac..3e35273 100644 --- a/LightweightIocContainer/Installers/AssemblyInstaller.cs +++ b/LightweightIocContainer/Installers/AssemblyInstaller.cs @@ -9,44 +9,43 @@ using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Installers; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Installers +namespace LightweightIocContainer.Installers; + +/// +/// An that installs all s for its given +/// +public class AssemblyInstaller : IAssemblyInstaller { /// /// An that installs all s for its given /// - public class AssemblyInstaller : IAssemblyInstaller + /// The from where the s will be installed + public AssemblyInstaller(Assembly assembly) { - /// - /// An that installs all s for its given - /// - /// The from where the s will be installed - public AssemblyInstaller(Assembly assembly) - { - Installers = new List(); + Installers = new List(); - Type[] types = assembly.GetTypes(); - foreach (Type type in types) - { - if (!typeof(IIocInstaller).IsAssignableFrom(type) || type.IsNestedPrivate) - continue; + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (!typeof(IIocInstaller).IsAssignableFrom(type) || type.IsNestedPrivate) + continue; - Installers.Add(Creator.CreateInstance(type)); - } + Installers.Add(Creator.CreateInstance(type)); } + } - /// - /// The s of the Assembly that this is installing - /// - public List Installers { get; } + /// + /// The s of the Assembly that this is installing + /// + public List Installers { get; } - /// - /// Install the found s in the given - /// - /// The where s are added - public void Install(IRegistrationCollector registration) - { - foreach (IIocInstaller installer in Installers) - installer.Install(registration); - } + /// + /// Install the found s in the given + /// + /// The where s are added + public void Install(IRegistrationCollector registration) + { + foreach (IIocInstaller installer in Installers) + installer.Install(registration); } } \ No newline at end of file diff --git a/LightweightIocContainer/Installers/FromAssembly.cs b/LightweightIocContainer/Installers/FromAssembly.cs index c13f2dd..fcb868e 100644 --- a/LightweightIocContainer/Installers/FromAssembly.cs +++ b/LightweightIocContainer/Installers/FromAssembly.cs @@ -5,28 +5,27 @@ using System.Reflection; using LightweightIocContainer.Interfaces.Installers; -namespace LightweightIocContainer.Installers +namespace LightweightIocContainer.Installers; + +/// +/// Helper class that supplies methods to find the wanted +/// +public static class FromAssembly { /// - /// Helper class that supplies methods to find the wanted + /// Get an that installs from the calling the method /// - public static class FromAssembly + /// A new with the calling + public static IAssemblyInstaller This() { - /// - /// Get an that installs from the calling the method - /// - /// A new with the calling - public static IAssemblyInstaller This() - { - Assembly assembly = Assembly.GetCallingAssembly(); - return new AssemblyInstaller(assembly); - } - - /// - /// Get an that installs from the given - /// - /// The given - /// A new with the given - public static IAssemblyInstaller Instance(Assembly assembly) => new AssemblyInstaller(assembly); + Assembly assembly = Assembly.GetCallingAssembly(); + return new AssemblyInstaller(assembly); } + + /// + /// Get an that installs from the given + /// + /// The given + /// A new with the given + public static IAssemblyInstaller Instance(Assembly assembly) => new AssemblyInstaller(assembly); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Factories/ITypedFactory.cs b/LightweightIocContainer/Interfaces/Factories/ITypedFactory.cs index f053255..504abc1 100644 --- a/LightweightIocContainer/Interfaces/Factories/ITypedFactory.cs +++ b/LightweightIocContainer/Interfaces/Factories/ITypedFactory.cs @@ -5,28 +5,27 @@ using System.Collections.Generic; using System.Reflection; -namespace LightweightIocContainer.Interfaces.Factories +namespace LightweightIocContainer.Interfaces.Factories; + +/// +/// Non-generic +/// +public interface ITypedFactory { /// - /// Non-generic + /// The create methods of this /// - public interface ITypedFactory - { - /// - /// The create methods of this - /// - List CreateMethods { get; } - } + List CreateMethods { get; } +} +/// +/// Class to help implement an abstract typed factory +/// +/// The type of the abstract factory +public interface ITypedFactory : ITypedFactory +{ /// - /// Class to help implement an abstract typed factory + /// The implemented abstract typed factory /// - /// The type of the abstract factory - public interface ITypedFactory : ITypedFactory - { - /// - /// The implemented abstract typed factory - /// - TFactory Factory { get; set; } - } + TFactory Factory { get; set; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/IIocContainer.cs b/LightweightIocContainer/Interfaces/IIocContainer.cs index bb0a797..ead70ea 100644 --- a/LightweightIocContainer/Interfaces/IIocContainer.cs +++ b/LightweightIocContainer/Interfaces/IIocContainer.cs @@ -6,37 +6,36 @@ using System; using LightweightIocContainer.Interfaces.Installers; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Interfaces +namespace LightweightIocContainer.Interfaces; + +/// +/// The main container that carries all s +/// +public interface IIocContainer : IDisposable { /// - /// The main container that carries all s + /// Install the given installers for the current /// - public interface IIocContainer : IDisposable - { - /// - /// Install the given installers for the current - /// - /// The given s - /// An instance of the current - IIocContainer Install(params IIocInstaller[] installers); + /// The given s + /// An instance of the current + IIocContainer Install(params IIocInstaller[] installers); - /// - /// Register an at this - /// - /// The that creates an - public void Register(Func addRegistration); + /// + /// Register an at this + /// + /// The that creates an + public void Register(Func addRegistration); - /// - /// Clear the multiton instances of the given from the registered multitons list - /// - /// The to clear the multiton instances - void ClearMultitonInstances(); + /// + /// Clear the multiton instances of the given from the registered multitons list + /// + /// The to clear the multiton instances + void ClearMultitonInstances(); - /// - /// Is the given registered with this - /// - /// The given - /// True if the given is registered with this , false if not - bool IsTypeRegistered(); - } + /// + /// Is the given registered with this + /// + /// The given + /// True if the given is registered with this , false if not + bool IsTypeRegistered(); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/IIocResolver.cs b/LightweightIocContainer/Interfaces/IIocResolver.cs index 7d0475d..5705fa8 100644 --- a/LightweightIocContainer/Interfaces/IIocResolver.cs +++ b/LightweightIocContainer/Interfaces/IIocResolver.cs @@ -4,26 +4,25 @@ using System; -namespace LightweightIocContainer.Interfaces +namespace LightweightIocContainer.Interfaces; + +/// +/// Provides methods +/// +public interface IIocResolver : IDisposable { /// - /// Provides methods + /// Gets an instance of the given /// - public interface IIocResolver : IDisposable - { - /// - /// Gets an instance of the given - /// - /// The given - /// An instance of the given - T Resolve(); + /// The given + /// An instance of the given + T Resolve(); - /// - /// Gets an instance of the given - /// - /// The given - /// The constructor arguments - /// An instance of the given - T Resolve(params object[] arguments); - } + /// + /// Gets an instance of the given + /// + /// The given + /// The constructor arguments + /// An instance of the given + T Resolve(params object[] arguments); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Installers/IAssemblyInstaller.cs b/LightweightIocContainer/Interfaces/Installers/IAssemblyInstaller.cs index 7ff917d..d5a3630 100644 --- a/LightweightIocContainer/Interfaces/Installers/IAssemblyInstaller.cs +++ b/LightweightIocContainer/Interfaces/Installers/IAssemblyInstaller.cs @@ -5,16 +5,15 @@ using System.Collections.Generic; using System.Reflection; -namespace LightweightIocContainer.Interfaces.Installers +namespace LightweightIocContainer.Interfaces.Installers; + +/// +/// An that installs all s for its given +/// +public interface IAssemblyInstaller : IIocInstaller { /// - /// An that installs all s for its given + /// The s of the that this is installing /// - public interface IAssemblyInstaller : IIocInstaller - { - /// - /// The s of the that this is installing - /// - List Installers { get; } - } + List Installers { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs b/LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs index ae4f44c..5ec9075 100644 --- a/LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs +++ b/LightweightIocContainer/Interfaces/Installers/IIocInstaller.cs @@ -4,17 +4,16 @@ using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Interfaces.Installers +namespace LightweightIocContainer.Interfaces.Installers; + +/// +/// The base class for installers +/// +public interface IIocInstaller { /// - /// The base class for installers + /// Install the needed s in the given /// - public interface IIocInstaller - { - /// - /// Install the needed s in the given - /// - /// The where s are added - void Install(IRegistrationCollector registration); - } + /// The where s are added + void Install(IRegistrationCollector registration); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/Fluent/IOnCreate.cs b/LightweightIocContainer/Interfaces/Registrations/Fluent/IOnCreate.cs index 53507e3..5a36400 100644 --- a/LightweightIocContainer/Interfaces/Registrations/Fluent/IOnCreate.cs +++ b/LightweightIocContainer/Interfaces/Registrations/Fluent/IOnCreate.cs @@ -5,32 +5,31 @@ using System; using LightweightIocContainer.Interfaces.Installers; -namespace LightweightIocContainer.Interfaces.Registrations.Fluent +namespace LightweightIocContainer.Interfaces.Registrations.Fluent; + +/// +/// Provides an to the generic +/// +public interface IOnCreate { /// - /// Provides an to the generic + /// This is invoked when an instance of this type is created. + /// Can be set in the by calling /// - public interface IOnCreate - { - /// - /// This is invoked when an instance of this type is created. - /// Can be set in the by calling - /// - internal Action? OnCreateAction { get; } - } + internal Action? OnCreateAction { get; } +} +/// +/// Provides an method to an +/// +/// The registered interface +/// The registered implementation +public interface IOnCreate : IOnCreate where TImplementation : TInterface +{ /// - /// Provides an method to an + /// Pass an that will be invoked when an instance of this type is created /// - /// The registered interface - /// The registered implementation - public interface IOnCreate : IOnCreate where TImplementation : TInterface - { - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - ITypedRegistration OnCreate(Action action); - } + /// The + /// The current instance of this + ITypedRegistration OnCreate(Action action); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs index 4db540f..b06d491 100644 --- a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs +++ b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs @@ -4,34 +4,33 @@ using LightweightIocContainer.Interfaces.Factories; -namespace LightweightIocContainer.Interfaces.Registrations.Fluent +namespace LightweightIocContainer.Interfaces.Registrations.Fluent; + +/// +/// Provides a method to an +/// +public interface IWithFactory { /// - /// Provides a method to an + /// Register an abstract typed factory for the /// - public interface IWithFactory - { - /// - /// Register an abstract typed factory for the - /// - /// The type of the abstract typed factory - /// The current instance of this - IRegistrationBase WithFactory(); + /// The type of the abstract typed factory + /// The current instance of this + IRegistrationBase WithFactory(); - /// - /// Register a custom implemented factory for the - /// - /// The type of the interface for the custom factory - /// The type of the implementation for the custom factory - /// The current instance of this - IRegistrationBase WithFactory() where TFactoryImplementation : TFactoryInterface; - } + /// + /// Register a custom implemented factory for the + /// + /// The type of the interface for the custom factory + /// The type of the implementation for the custom factory + /// The current instance of this + IRegistrationBase WithFactory() where TFactoryImplementation : TFactoryInterface; +} - internal interface IWithFactoryInternal : IWithFactory - { - /// - /// The Factory added with the method - /// - ITypedFactory? Factory { get; } - } +internal interface IWithFactoryInternal : IWithFactory +{ + /// + /// The Factory added with the method + /// + ITypedFactory? Factory { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithParameters.cs b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithParameters.cs index 1822d5b..1d93dcf 100644 --- a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithParameters.cs +++ b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithParameters.cs @@ -6,38 +6,37 @@ using System; using LightweightIocContainer.Exceptions; using LightweightIocContainer.Interfaces.Installers; -namespace LightweightIocContainer.Interfaces.Registrations.Fluent +namespace LightweightIocContainer.Interfaces.Registrations.Fluent; + +/// +/// Provides a method to an +/// +public interface IWithParameters { /// - /// Provides a method to an + /// Pass parameters that will be used to an instance of this + /// Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving /// - public interface IWithParameters - { - /// - /// Pass parameters that will be used to an instance of this - /// Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving - /// - /// The parameters - /// The current instance of this - /// are already set or no parameters given - IRegistrationBase WithParameters(params object[] parameters); + /// The parameters + /// The current instance of this + /// are already set or no parameters given + IRegistrationBase WithParameters(params object[] parameters); - /// - /// Pass parameters that will be used to an instance of this - /// Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving - /// - /// The parameters with their position - /// The current instance of this - /// are already set or no parameters given - IRegistrationBase WithParameters(params (int index, object parameter)[] parameters); - } + /// + /// Pass parameters that will be used to an instance of this + /// Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving + /// + /// The parameters with their position + /// The current instance of this + /// are already set or no parameters given + IRegistrationBase WithParameters(params (int index, object parameter)[] parameters); +} - internal interface IWithParametersInternal : IWithParameters - { - /// - /// An of parameters that are used to an instance of this - /// Can be set in the by calling - /// - object[]? Parameters { get; } - } +internal interface IWithParametersInternal : IWithParameters +{ + /// + /// An of parameters that are used to an instance of this + /// Can be set in the by calling + /// + object[]? Parameters { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/ILifestyleProvider.cs b/LightweightIocContainer/Interfaces/Registrations/ILifestyleProvider.cs index 084849b..2089b86 100644 --- a/LightweightIocContainer/Interfaces/Registrations/ILifestyleProvider.cs +++ b/LightweightIocContainer/Interfaces/Registrations/ILifestyleProvider.cs @@ -2,16 +2,15 @@ // // Created: 2020-01-29 // // Copyright(c) 2020 SimonG. All Rights Reserved. -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// Provides a to an +/// +public interface ILifestyleProvider { /// - /// Provides a to an + /// The Lifestyle of Instances that are created with this /// - public interface ILifestyleProvider - { - /// - /// The Lifestyle of Instances that are created with this - /// - Lifestyle Lifestyle { get; } - } + Lifestyle Lifestyle { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs index 7869d02..e1cd99f 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs @@ -2,16 +2,15 @@ // Created: 2020-11-19 // Copyright(c) 2020 SimonG. All Rights Reserved. -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// An to register multiple interfaces for on implementation type that implements them as a multiton +/// +/// The first interface +/// The second interface +/// The implementation +public interface IMultipleMultitonRegistration : IMultitonRegistration, IMultipleRegistration where TImplementation : TInterface1, TInterface2 { - /// - /// An to register multiple interfaces for on implementation type that implements them as a multiton - /// - /// The first interface - /// The second interface - /// The implementation - public interface IMultipleMultitonRegistration : IMultitonRegistration, IMultipleRegistration where TImplementation : TInterface1, TInterface2 - { - } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultipleRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultipleRegistration.cs index 1f2aeec..de837af 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IMultipleRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IMultipleRegistration.cs @@ -4,68 +4,67 @@ using System.Collections.Generic; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// The base interface for every to register multiple interfaces +/// +/// The first interface +/// The implementation +public interface IMultipleRegistration : ITypedRegistration where TImplementation : TInterface1 { /// - /// The base interface for every to register multiple interfaces + /// A of s that are registered within this /// - /// The first interface - /// The implementation - public interface IMultipleRegistration : ITypedRegistration where TImplementation : TInterface1 - { - /// - /// A of s that are registered within this - /// - List Registrations { get; } - } + List Registrations { get; } +} - /// - /// An to register multiple interfaces for on implementation type - /// - /// The first interface - /// The second interface - /// The implementation - public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2 - { +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The implementation +public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2 +{ - } +} - /// - /// An to register multiple interfaces for on implementation type - /// - /// The first interface - /// The second interface - /// The third interface - /// The implementation - public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3 - { +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The implementation +public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3 +{ - } +} - /// - /// An to register multiple interfaces for on implementation type - /// - /// The first interface - /// The second interface - /// The third interface - /// The fourth interface - /// The implementation - public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4 - { +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The fourth interface +/// The implementation +public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4 +{ - } +} - /// - /// An to register multiple interfaces for on implementation type - /// - /// The first interface - /// The second interface - /// The third interface - /// The fourth interface - /// The fifth interface - /// The implementation - public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4, TInterface5 - { +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The fourth interface +/// The fifth interface +/// The implementation +public interface IMultipleRegistration : IMultipleRegistration where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4, TInterface5 +{ - } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs index 44c6650..8b0a3f9 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs @@ -4,26 +4,25 @@ using System; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// Non generic +/// +public interface IMultitonRegistration : ITypedRegistration { /// - /// Non generic + /// The of the multiton scope /// - public interface IMultitonRegistration : ITypedRegistration - { - /// - /// The of the multiton scope - /// - Type Scope { get; } - } + Type Scope { get; } +} - /// - /// The registration that is used to register a multiton - /// - /// The registered interface - /// The registered implementation - public interface IMultitonRegistration : IMultitonRegistration, ITypedRegistration where TImplementation : TInterface - { +/// +/// The registration that is used to register a multiton +/// +/// The registered interface +/// The registered implementation +public interface IMultitonRegistration : IMultitonRegistration, ITypedRegistration where TImplementation : TInterface +{ - } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IOpenGenericRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IOpenGenericRegistration.cs index 9428dba..2159675 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IOpenGenericRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IOpenGenericRegistration.cs @@ -2,13 +2,12 @@ // Created: 2020-09-18 // Copyright(c) 2020 SimonG. All Rights Reserved. -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// for open generic types +/// +public interface IOpenGenericRegistration : ITypedRegistration { - /// - /// for open generic types - /// - public interface IOpenGenericRegistration : ITypedRegistration - { - } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IRegistration.cs index 019c7fb..36a52d2 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IRegistration.cs @@ -4,16 +4,15 @@ using System; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// The base registration that is used to register an Interface +/// +public interface IRegistration { /// - /// The base registration that is used to register an Interface + /// The of the Interface that is registered with this /// - public interface IRegistration - { - /// - /// The of the Interface that is registered with this - /// - Type InterfaceType { get; } - } + Type InterfaceType { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs b/LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs index f5ca85b..598a530 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IRegistrationBase.cs @@ -4,13 +4,12 @@ using LightweightIocContainer.Interfaces.Registrations.Fluent; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// The that is used to register an Interface and extends the with fluent options +/// +public interface IRegistrationBase : IRegistration, IWithFactory, IWithParameters, IWithDisposeStrategy { - /// - /// The that is used to register an Interface and extends the with fluent options - /// - public interface IRegistrationBase : IRegistration, IWithFactory, IWithParameters, IWithDisposeStrategy - { - } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/ISingleTypeRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/ISingleTypeRegistration.cs index bfde8f8..d0dab97 100644 --- a/LightweightIocContainer/Interfaces/Registrations/ISingleTypeRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/ISingleTypeRegistration.cs @@ -4,24 +4,23 @@ using System; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// The to register either only an interface or only a +/// +/// The of the +public interface ISingleTypeRegistration : IRegistrationBase { /// - /// The to register either only an interface or only a + /// that is invoked instead of creating an instance of this the default way /// - /// The of the - public interface ISingleTypeRegistration : IRegistrationBase - { - /// - /// that is invoked instead of creating an instance of this the default way - /// - Func? FactoryMethod { get; } + Func? FactoryMethod { get; } - /// - /// Pass a that will be invoked instead of creating an instance of this the default way - /// - /// The - /// The current instance of this - ISingleTypeRegistration WithFactoryMethod(Func factoryMethod); - } + /// + /// Pass a that will be invoked instead of creating an instance of this the default way + /// + /// The + /// The current instance of this + ISingleTypeRegistration WithFactoryMethod(Func factoryMethod); } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/ITypedFactoryRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/ITypedFactoryRegistration.cs index 12c361e..49be000 100644 --- a/LightweightIocContainer/Interfaces/Registrations/ITypedFactoryRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/ITypedFactoryRegistration.cs @@ -4,17 +4,16 @@ using LightweightIocContainer.Interfaces.Factories; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// The registration that is used to register an abstract typed factory +/// +/// The type of the abstract typed factory +public interface ITypedFactoryRegistration : IRegistration { /// - /// The registration that is used to register an abstract typed factory + /// The class that contains the implemented abstract factory of this /// - /// The type of the abstract typed factory - public interface ITypedFactoryRegistration : IRegistration - { - /// - /// The class that contains the implemented abstract factory of this - /// - ITypedFactory Factory { get; } - } + ITypedFactory Factory { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/ITypedRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/ITypedRegistration.cs index ef67b9c..6071385 100644 --- a/LightweightIocContainer/Interfaces/Registrations/ITypedRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/ITypedRegistration.cs @@ -5,24 +5,23 @@ using System; using LightweightIocContainer.Interfaces.Registrations.Fluent; -namespace LightweightIocContainer.Interfaces.Registrations +namespace LightweightIocContainer.Interfaces.Registrations; + +/// +/// A base without generic interface and implementation +/// +public interface ITypedRegistration : IRegistrationBase { /// - /// A base without generic interface and implementation + /// The that implements the that is registered with this /// - public interface ITypedRegistration : IRegistrationBase - { - /// - /// The that implements the that is registered with this - /// - Type ImplementationType { get; } - } + Type ImplementationType { get; } +} - /// - /// A that implements a - /// - public interface ITypedRegistration : ITypedRegistration, IOnCreate where TImplementation : TInterface - { +/// +/// A that implements a +/// +public interface ITypedRegistration : ITypedRegistration, IOnCreate where TImplementation : TInterface +{ - } } \ No newline at end of file diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 7abeb2a..2869e2f 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -16,651 +16,650 @@ using LightweightIocContainer.Interfaces.Registrations.Fluent; using LightweightIocContainer.Registrations; using LightweightIocContainer.ResolvePlaceholders; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +/// +/// The main container that carries all the s and can resolve all the types you'll ever want +/// +public class IocContainer : IIocContainer, IIocResolver { + private readonly RegistrationFactory _registrationFactory; + + private readonly List<(Type type, object? instance)> _singletons = new(); + private readonly List<(Type type, Type scope, ConditionalWeakTable instances)> _multitons = new(); + /// /// The main container that carries all the s and can resolve all the types you'll ever want /// - public class IocContainer : IIocContainer, IIocResolver + public IocContainer() { - private readonly RegistrationFactory _registrationFactory; + _registrationFactory = new RegistrationFactory(this); + Registrations = new List(); + } - private readonly List<(Type type, object? instance)> _singletons = new(); - private readonly List<(Type type, Type scope, ConditionalWeakTable instances)> _multitons = new(); + internal List Registrations { get; } - /// - /// The main container that carries all the s and can resolve all the types you'll ever want - /// - public IocContainer() + /// + /// Install the given installers for the current + /// + /// The given s + /// An instance of the current + public IIocContainer Install(params IIocInstaller[] installers) + { + foreach (IIocInstaller installer in installers) { - _registrationFactory = new RegistrationFactory(this); - Registrations = new List(); + RegistrationCollector registrationCollector = new(_registrationFactory); + installer.Install(registrationCollector); + + registrationCollector.Registrations.ForEach(Register); } - internal List Registrations { get; } + return this; + } - /// - /// Install the given installers for the current - /// - /// The given s - /// An instance of the current - public IIocContainer Install(params IIocInstaller[] installers) - { - foreach (IIocInstaller installer in installers) - { - RegistrationCollector registrationCollector = new(_registrationFactory); - installer.Install(registrationCollector); - - registrationCollector.Registrations.ForEach(Register); - } + /// + /// Register an at this + /// + /// The that creates an + public void Register(Func addRegistration) + { + RegistrationCollector registrationCollector = new(_registrationFactory); + addRegistration(registrationCollector); + + registrationCollector.Registrations.ForEach(Register); + } - return this; - } + /// + /// Register an Interface as an abstract typed factory + /// + /// The abstract typed factory to register + /// The created + internal void RegisterFactory(ITypedFactory factory) + { + ITypedFactoryRegistration typedFactoryRegistration = _registrationFactory.RegisterFactory(factory); + if (!Registrations.Contains(typedFactoryRegistration)) + Registrations.Add(typedFactoryRegistration); + } - /// - /// Register an at this - /// - /// The that creates an - public void Register(Func addRegistration) - { - RegistrationCollector registrationCollector = new(_registrationFactory); - addRegistration(registrationCollector); + /// + /// Add the to the the + /// + /// The given + /// The is already registered in this + private void Register(IRegistration registration) + { + IRegistration? sameTypeRegistration = Registrations.FirstOrDefault(r => r.InterfaceType == registration.InterfaceType); + if (sameTypeRegistration != null && !registration.Equals(sameTypeRegistration)) //if type is already registered differently + throw new MultipleRegistrationException(registration.InterfaceType); + + if (registration is IInternalValidationProvider validationProvider) + validationProvider.Validate(); - registrationCollector.Registrations.ForEach(Register); - } + Registrations.Add(registration); + } - /// - /// Register an Interface as an abstract typed factory - /// - /// The abstract typed factory to register - /// The created - internal void RegisterFactory(ITypedFactory factory) - { - ITypedFactoryRegistration typedFactoryRegistration = _registrationFactory.RegisterFactory(factory); - if (!Registrations.Contains(typedFactoryRegistration)) - Registrations.Add(typedFactoryRegistration); - } + /// + /// Gets an instance of the given + /// + /// The given + /// An instance of the given + public virtual T Resolve() => ResolveInternal(null); - /// - /// Add the to the the - /// - /// The given - /// The is already registered in this - private void Register(IRegistration registration) - { - IRegistration? sameTypeRegistration = Registrations.FirstOrDefault(r => r.InterfaceType == registration.InterfaceType); - if (sameTypeRegistration != null && !registration.Equals(sameTypeRegistration)) //if type is already registered differently - throw new MultipleRegistrationException(registration.InterfaceType); + /// + /// Gets an instance of the given + /// + /// The given + /// The constructor arguments + /// An instance of the given + public T Resolve(params object[] arguments) => ResolveInternal(arguments); - if (registration is IInternalValidationProvider validationProvider) - validationProvider.Validate(); - - Registrations.Add(registration); - } + /// + /// Gets an instance of the given for a factory + /// + /// The given + /// The constructor arguments + /// An instance of the given + public T FactoryResolve(params object[] arguments) => ResolveInternal(arguments, null, true); - /// - /// Gets an instance of the given - /// - /// The given - /// An instance of the given - public virtual T Resolve() => ResolveInternal(null); - - /// - /// Gets an instance of the given - /// - /// The given - /// The constructor arguments - /// An instance of the given - public T Resolve(params object[] arguments) => ResolveInternal(arguments); - - /// - /// Gets an instance of the given for a factory - /// - /// The given - /// The constructor arguments - /// An instance of the given - public T FactoryResolve(params object[] arguments) => ResolveInternal(arguments, null, true); - - /// - /// Gets an instance of a given registered - /// - /// The registered - /// The constructor arguments - /// The current resolve stack - /// True if resolve is called from factory, false (default) if not - /// An instance of the given registered - private T ResolveInternal(object[]? arguments, List? resolveStack = null, bool isFactoryResolve = false) => ResolveInstance(TryResolve(arguments, resolveStack, isFactoryResolve)); - - /// - /// Tries to resolve the given with the given arguments - /// - /// The given arguments - /// The current resolve stack - /// True if resolve is called from factory, false (default) if not - /// The registered - /// An instance of the given registered , an if parameters need to be resolved or an if a factory method is used to create an instance - /// The given is not registered - /// A direct resolve with a registered factory is not allowed - /// An interface was registered without an implementation or factory method - /// Tried resolving a multiton without scope argument - /// No matching constructor for the given found - /// Getting resolve stack failed without exception - private object TryResolve(object?[]? arguments, List? resolveStack, bool isFactoryResolve = false) - { - IRegistration registration = FindRegistration() ?? throw new TypeNotRegisteredException(typeof(T)); + /// + /// Gets an instance of a given registered + /// + /// The registered + /// The constructor arguments + /// The current resolve stack + /// True if resolve is called from factory, false (default) if not + /// An instance of the given registered + private T ResolveInternal(object[]? arguments, List? resolveStack = null, bool isFactoryResolve = false) => ResolveInstance(TryResolve(arguments, resolveStack, isFactoryResolve)); - List internalResolveStack = resolveStack == null ? new List() : new List(resolveStack); - internalResolveStack = CheckForCircularDependencies(internalResolveStack); + /// + /// Tries to resolve the given with the given arguments + /// + /// The given arguments + /// The current resolve stack + /// True if resolve is called from factory, false (default) if not + /// The registered + /// An instance of the given registered , an if parameters need to be resolved or an if a factory method is used to create an instance + /// The given is not registered + /// A direct resolve with a registered factory is not allowed + /// An interface was registered without an implementation or factory method + /// Tried resolving a multiton without scope argument + /// No matching constructor for the given found + /// Getting resolve stack failed without exception + private object TryResolve(object?[]? arguments, List? resolveStack, bool isFactoryResolve = false) + { + IRegistration registration = FindRegistration() ?? throw new TypeNotRegisteredException(typeof(T)); - object? existingInstance = TryGetExistingInstance(registration, arguments); - if (existingInstance != null) - return existingInstance; + List internalResolveStack = resolveStack == null ? new List() : new List(resolveStack); + internalResolveStack = CheckForCircularDependencies(internalResolveStack); - switch (registration) - { - case IWithFactoryInternal { Factory: { } } when !isFactoryResolve: - throw new DirectResolveWithRegisteredFactoryNotAllowed(typeof(T)); - case ISingleTypeRegistration singleTypeRegistration when singleTypeRegistration.InterfaceType.IsInterface && singleTypeRegistration.FactoryMethod == null: - throw new InvalidRegistrationException($"Can't register an interface without its implementation type or without a factory method (Type: {singleTypeRegistration.InterfaceType})."); - case ISingleTypeRegistration { FactoryMethod: { } } singleTypeRegistration: - return new InternalFactoryMethodPlaceholder(singleTypeRegistration); - } + object? existingInstance = TryGetExistingInstance(registration, arguments); + if (existingInstance != null) + return existingInstance; - if (registration is IWithParametersInternal { Parameters: { } } registrationWithParameters) - arguments = UpdateArgumentsWithRegistrationParameters(registrationWithParameters, arguments); + switch (registration) + { + case IWithFactoryInternal { Factory: { } } when !isFactoryResolve: + throw new DirectResolveWithRegisteredFactoryNotAllowed(typeof(T)); + case ISingleTypeRegistration singleTypeRegistration when singleTypeRegistration.InterfaceType.IsInterface && singleTypeRegistration.FactoryMethod == null: + throw new InvalidRegistrationException($"Can't register an interface without its implementation type or without a factory method (Type: {singleTypeRegistration.InterfaceType})."); + case ISingleTypeRegistration { FactoryMethod: { } } singleTypeRegistration: + return new InternalFactoryMethodPlaceholder(singleTypeRegistration); + } - Type registeredType = GetType(registration); - (bool result, List? parametersToResolve, NoMatchingConstructorFoundException? exception) = - TryGetTypeResolveStack(registeredType, arguments, internalResolveStack); + if (registration is IWithParametersInternal { Parameters: { } } registrationWithParameters) + arguments = UpdateArgumentsWithRegistrationParameters(registrationWithParameters, arguments); - if (registration is IMultitonRegistration multitonRegistration) - { - if (arguments == null || !arguments.Any()) - throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); + Type registeredType = GetType(registration); + (bool result, List? parametersToResolve, NoMatchingConstructorFoundException? exception) = + TryGetTypeResolveStack(registeredType, arguments, internalResolveStack); - object multitonScopeArgument = TryGetMultitonScopeArgument(multitonRegistration, arguments); + if (registration is IMultitonRegistration multitonRegistration) + { + if (arguments == null || !arguments.Any()) + throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); - parametersToResolve ??= new List(); - parametersToResolve.Insert(0, multitonScopeArgument); //insert scope at first place, won't be passed to ctor when creating multiton - } + object multitonScopeArgument = TryGetMultitonScopeArgument(multitonRegistration, arguments); + + parametersToResolve ??= new List(); + parametersToResolve.Insert(0, multitonScopeArgument); //insert scope at first place, won't be passed to ctor when creating multiton + } - if (result) - return new InternalToBeResolvedPlaceholder(registeredType, registration, parametersToResolve); + if (result) + return new InternalToBeResolvedPlaceholder(registeredType, registration, parametersToResolve); - if (exception != null) - throw exception; + if (exception != null) + throw exception; - throw new InternalResolveException("Getting resolve stack failed without exception."); - } + throw new InternalResolveException("Getting resolve stack failed without exception."); + } - /// - /// Tries to resolve the given with the given arguments without generic arguments - /// - /// The registered - /// The given arguments - /// The current resolve stack - /// - /// An instance of the given registered , an if parameters need to be resolved or an if a factory method is used to create an instance - /// The given is not registered - /// A direct resolve with a registered factory is not allowed - /// An interface was registered without an implementation or factory method - /// Tried resolving a multiton without scope argument - /// No matching constructor for the given found - /// Getting resolve stack failed without exception - internal object? TryResolveNonGeneric(Type type, object?[]? arguments, List? resolveStack, bool isFactoryResolve = false) => - GenericMethodCaller.CallPrivate(this, nameof(TryResolve), type, arguments, resolveStack, isFactoryResolve); + /// + /// Tries to resolve the given with the given arguments without generic arguments + /// + /// The registered + /// The given arguments + /// The current resolve stack + /// + /// An instance of the given registered , an if parameters need to be resolved or an if a factory method is used to create an instance + /// The given is not registered + /// A direct resolve with a registered factory is not allowed + /// An interface was registered without an implementation or factory method + /// Tried resolving a multiton without scope argument + /// No matching constructor for the given found + /// Getting resolve stack failed without exception + internal object? TryResolveNonGeneric(Type type, object?[]? arguments, List? resolveStack, bool isFactoryResolve = false) => + GenericMethodCaller.CallPrivate(this, nameof(TryResolve), type, arguments, resolveStack, isFactoryResolve); - /// - /// Recursively resolve a with the given parameters for an - /// - /// The that includes the type and resolve stack - /// A recursively resolved instance of the given - private T ResolvePlaceholder(InternalToBeResolvedPlaceholder toBeResolvedPlaceholder) - { - object? existingInstance = TryGetExistingInstance(toBeResolvedPlaceholder.ResolvedRegistration, toBeResolvedPlaceholder.Parameters); - if (existingInstance is T instance) - return instance; + /// + /// Recursively resolve a with the given parameters for an + /// + /// The that includes the type and resolve stack + /// A recursively resolved instance of the given + private T ResolvePlaceholder(InternalToBeResolvedPlaceholder toBeResolvedPlaceholder) + { + object? existingInstance = TryGetExistingInstance(toBeResolvedPlaceholder.ResolvedRegistration, toBeResolvedPlaceholder.Parameters); + if (existingInstance is T instance) + return instance; - if (toBeResolvedPlaceholder.Parameters == null) - return CreateInstance(toBeResolvedPlaceholder.ResolvedRegistration, null); + if (toBeResolvedPlaceholder.Parameters == null) + return CreateInstance(toBeResolvedPlaceholder.ResolvedRegistration, null); - List parameters = new(); - foreach (object? parameter in toBeResolvedPlaceholder.Parameters) + List parameters = new(); + foreach (object? parameter in toBeResolvedPlaceholder.Parameters) + { + if (parameter != null) { - if (parameter != null) - { - Type type = parameter is IInternalToBeResolvedPlaceholder internalToBeResolvedPlaceholder ? - internalToBeResolvedPlaceholder.ResolvedType : parameter.GetType(); + Type type = parameter is IInternalToBeResolvedPlaceholder internalToBeResolvedPlaceholder ? + internalToBeResolvedPlaceholder.ResolvedType : parameter.GetType(); - parameters.Add(ResolveInstanceNonGeneric(type, parameter)); - } - else - parameters.Add(parameter); + parameters.Add(ResolveInstanceNonGeneric(type, parameter)); } - - return CreateInstance(toBeResolvedPlaceholder.ResolvedRegistration, parameters.ToArray()); + else + parameters.Add(parameter); } - /// - /// Resolve the given object instance - /// - /// The given resolved object - /// The of the returned instance - /// An instance of the given resolved object - /// Resolve returned wrong type - private T ResolveInstance(object resolvedObject) => - resolvedObject switch - { - T instance => instance, - InternalToBeResolvedPlaceholder toBeResolvedPlaceholder => ResolvePlaceholder(toBeResolvedPlaceholder), - InternalFactoryMethodPlaceholder factoryMethodPlaceholder => factoryMethodPlaceholder.FactoryMethod(this), - _ => throw new InternalResolveException("Resolve returned wrong type.") - }; - - /// - /// Resolve the given object instance without generic arguments - /// - /// The of the returned instance - /// - /// An instance of the given resolved object - /// Resolve returned wrong type - private object? ResolveInstanceNonGeneric(Type type, object resolveObject) => - GenericMethodCaller.CallPrivate(this, nameof(ResolveInstance), type, resolveObject); - - /// - /// Creates an instance of a given - /// - /// The given - /// The registration of the given - /// The constructor arguments - /// A newly created instance of the given - private T CreateInstance(IRegistration registration, object?[]? arguments) - { - T instance; - if (registration is IOpenGenericRegistration openGenericRegistration) - { - //create generic implementation type from generic arguments of T - Type genericImplementationType = openGenericRegistration.ImplementationType.MakeGenericType(typeof(T).GenericTypeArguments); - instance = Creator.CreateInstance(genericImplementationType, arguments); - } - else if (registration is ISingleTypeRegistration singleTypeRegistration) - instance = singleTypeRegistration.FactoryMethod == null ? Creator.CreateInstance(singleTypeRegistration.InterfaceType, arguments) : singleTypeRegistration.FactoryMethod(this); - else if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration) - instance = CreateMultitonInstance(multitonRegistration, arguments); - else if (registration is ITypedRegistration defaultRegistration) - instance = Creator.CreateInstance(defaultRegistration.ImplementationType, arguments); - else - throw new UnknownRegistrationException($"There is no registration of type {registration.GetType().Name}."); + return CreateInstance(toBeResolvedPlaceholder.ResolvedRegistration, parameters.ToArray()); + } - if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Singleton }) - _singletons.Add((GetType(registration), instance)); + /// + /// Resolve the given object instance + /// + /// The given resolved object + /// The of the returned instance + /// An instance of the given resolved object + /// Resolve returned wrong type + private T ResolveInstance(object resolvedObject) => + resolvedObject switch + { + T instance => instance, + InternalToBeResolvedPlaceholder toBeResolvedPlaceholder => ResolvePlaceholder(toBeResolvedPlaceholder), + InternalFactoryMethodPlaceholder factoryMethodPlaceholder => factoryMethodPlaceholder.FactoryMethod(this), + _ => throw new InternalResolveException("Resolve returned wrong type.") + }; - if (registration is IOnCreate onCreateRegistration) - onCreateRegistration.OnCreateAction?.Invoke(instance); //TODO: Allow async OnCreateAction? + /// + /// Resolve the given object instance without generic arguments + /// + /// The of the returned instance + /// + /// An instance of the given resolved object + /// Resolve returned wrong type + private object? ResolveInstanceNonGeneric(Type type, object resolveObject) => + GenericMethodCaller.CallPrivate(this, nameof(ResolveInstance), type, resolveObject); - return instance; + /// + /// Creates an instance of a given + /// + /// The given + /// The registration of the given + /// The constructor arguments + /// A newly created instance of the given + private T CreateInstance(IRegistration registration, object?[]? arguments) + { + T instance; + if (registration is IOpenGenericRegistration openGenericRegistration) + { + //create generic implementation type from generic arguments of T + Type genericImplementationType = openGenericRegistration.ImplementationType.MakeGenericType(typeof(T).GenericTypeArguments); + instance = Creator.CreateInstance(genericImplementationType, arguments); } + else if (registration is ISingleTypeRegistration singleTypeRegistration) + instance = singleTypeRegistration.FactoryMethod == null ? Creator.CreateInstance(singleTypeRegistration.InterfaceType, arguments) : singleTypeRegistration.FactoryMethod(this); + else if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration) + instance = CreateMultitonInstance(multitonRegistration, arguments); + else if (registration is ITypedRegistration defaultRegistration) + instance = Creator.CreateInstance(defaultRegistration.ImplementationType, arguments); + else + throw new UnknownRegistrationException($"There is no registration of type {registration.GetType().Name}."); + + if (registration is ILifestyleProvider { Lifestyle: Lifestyle.Singleton }) + _singletons.Add((GetType(registration), instance)); + + if (registration is IOnCreate onCreateRegistration) + onCreateRegistration.OnCreateAction?.Invoke(instance); //TODO: Allow async OnCreateAction? + + return instance; + } - /// - /// Try to get an already existing instance (factory, singleton, multiton) - /// - /// The given - /// The given arguments - /// The of the instance - /// An already existing instance if possible, null if not - private object? TryGetExistingInstance(IRegistration registration, IReadOnlyList? arguments) => - registration switch - { - ITypedFactoryRegistration typedFactoryRegistration => typedFactoryRegistration.Factory.Factory, - ILifestyleProvider { Lifestyle: Lifestyle.Singleton } => TryGetSingletonInstance(registration), - ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration => TryGetMultitonInstance(multitonRegistration, arguments), - _ => null - }; - - /// - /// Try to get an existing singleton instance for a given - /// - /// The - /// A singleton instance if existing for the given , null if not - private object? TryGetSingletonInstance(IRegistration registration) => - _singletons.FirstOrDefault(s => s.type == GetType(registration)).instance; //if a singleton instance exists return it - - /// - /// Try to get an existing multiton instance for a given - /// - /// The given - /// The given arguments - /// A multiton instance if existing for the given , null if not - /// Tried resolving a multiton without scope argument - private object? TryGetMultitonInstance(IMultitonRegistration registration, IReadOnlyList? arguments) + /// + /// Try to get an already existing instance (factory, singleton, multiton) + /// + /// The given + /// The given arguments + /// The of the instance + /// An already existing instance if possible, null if not + private object? TryGetExistingInstance(IRegistration registration, IReadOnlyList? arguments) => + registration switch { - if (arguments == null || !arguments.Any()) - throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); + ITypedFactoryRegistration typedFactoryRegistration => typedFactoryRegistration.Factory.Factory, + ILifestyleProvider { Lifestyle: Lifestyle.Singleton } => TryGetSingletonInstance(registration), + ILifestyleProvider { Lifestyle: Lifestyle.Multiton } and IMultitonRegistration multitonRegistration => TryGetMultitonInstance(multitonRegistration, arguments), + _ => null + }; + + /// + /// Try to get an existing singleton instance for a given + /// + /// The + /// A singleton instance if existing for the given , null if not + private object? TryGetSingletonInstance(IRegistration registration) => + _singletons.FirstOrDefault(s => s.type == GetType(registration)).instance; //if a singleton instance exists return it + + /// + /// Try to get an existing multiton instance for a given + /// + /// The given + /// The given arguments + /// A multiton instance if existing for the given , null if not + /// Tried resolving a multiton without scope argument + private object? TryGetMultitonInstance(IMultitonRegistration registration, IReadOnlyList? arguments) + { + if (arguments == null || !arguments.Any()) + throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); - object scopeArgument = TryGetMultitonScopeArgument(registration, arguments); + object scopeArgument = TryGetMultitonScopeArgument(registration, arguments); - //if a multiton for the given scope exists return it - var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well) - if (matchingMultitons == default) - return null; + //if a multiton for the given scope exists return it + var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well) + if (matchingMultitons == default) + return null; - return matchingMultitons.instances.TryGetValue(scopeArgument, out object? instance) && instance != null ? instance : null; - } + return matchingMultitons.instances.TryGetValue(scopeArgument, out object? instance) && instance != null ? instance : null; + } - /// - /// Try to get the multiton scope argument for a given - /// - /// The given - /// The given arguments - /// The multiton scope argument for the given - /// Tried resolving a multiton without correct scope argument - private object TryGetMultitonScopeArgument(IMultitonRegistration registration, IReadOnlyList arguments) - { - object? scopeArgument = arguments[0]; - if (scopeArgument?.GetType() != registration.Scope && !registration.Scope.IsInstanceOfType(scopeArgument)) - throw new MultitonResolveException($"Can not resolve multiton without the first argument being the scope (should be of type {registration.Scope}).", registration.InterfaceType); + /// + /// Try to get the multiton scope argument for a given + /// + /// The given + /// The given arguments + /// The multiton scope argument for the given + /// Tried resolving a multiton without correct scope argument + private object TryGetMultitonScopeArgument(IMultitonRegistration registration, IReadOnlyList arguments) + { + object? scopeArgument = arguments[0]; + if (scopeArgument?.GetType() != registration.Scope && !registration.Scope.IsInstanceOfType(scopeArgument)) + throw new MultitonResolveException($"Can not resolve multiton without the first argument being the scope (should be of type {registration.Scope}).", registration.InterfaceType); - return scopeArgument; - } + return scopeArgument; + } - /// - /// Gets or creates a multiton instance of a given - /// - /// The given - /// The registration of the given - /// The arguments to resolve - /// An existing or newly created multiton instance of the given - /// No arguments given - /// Scope argument not given - private T CreateMultitonInstance(IMultitonRegistration registration, object?[]? arguments) - { - if (arguments == null || !arguments.Any()) - throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); + /// + /// Gets or creates a multiton instance of a given + /// + /// The given + /// The registration of the given + /// The arguments to resolve + /// An existing or newly created multiton instance of the given + /// No arguments given + /// Scope argument not given + private T CreateMultitonInstance(IMultitonRegistration registration, object?[]? arguments) + { + if (arguments == null || !arguments.Any()) + throw new MultitonResolveException("Can not resolve multiton without arguments.", registration.InterfaceType); - object scopeArgument = TryGetMultitonScopeArgument(registration, arguments); + object scopeArgument = TryGetMultitonScopeArgument(registration, arguments); - //if a multiton for the given scope exists return it - var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well) - if (matchingMultitons != default) - { - T createdInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]); - matchingMultitons.instances.Add(scopeArgument, createdInstance); + //if a multiton for the given scope exists return it + var matchingMultitons = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope); //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well) + if (matchingMultitons != default) + { + T createdInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]); + matchingMultitons.instances.Add(scopeArgument, createdInstance); - return createdInstance; - } + return createdInstance; + } - T newInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]); - _multitons.Add((registration.ImplementationType, registration.Scope, new ConditionalWeakTable { { scopeArgument, newInstance } })); + T newInstance = Creator.CreateInstance(registration.ImplementationType, arguments[1..]); + _multitons.Add((registration.ImplementationType, registration.Scope, new ConditionalWeakTable { { scopeArgument, newInstance } })); - return newInstance; - } + return newInstance; + } - /// - /// Update the given arguments with the of the given - /// - /// The of the given - /// The constructor arguments - /// The argument list updated with the - private object?[]? UpdateArgumentsWithRegistrationParameters(IWithParametersInternal registration, object?[]? arguments) - { - if (registration.Parameters == null) - return arguments; + /// + /// Update the given arguments with the of the given + /// + /// The of the given + /// The constructor arguments + /// The argument list updated with the + private object?[]? UpdateArgumentsWithRegistrationParameters(IWithParametersInternal registration, object?[]? arguments) + { + if (registration.Parameters == null) + return arguments; - if (arguments != null && arguments.Any()) //if more arguments were passed to resolve - { - int argumentsSize = registration.Parameters.Length + arguments.Length; - object?[] newArguments = new object[argumentsSize]; + if (arguments != null && arguments.Any()) //if more arguments were passed to resolve + { + int argumentsSize = registration.Parameters.Length + arguments.Length; + object?[] newArguments = new object[argumentsSize]; - for (int i = 0; i < argumentsSize; i++) + for (int i = 0; i < argumentsSize; i++) + { + if (i < registration.Parameters.Length) //if `i` is bigger than the length of the parameters, take the given arguments { - if (i < registration.Parameters.Length) //if `i` is bigger than the length of the parameters, take the given arguments + object currentParameter = registration.Parameters[i]; + if (currentParameter is not InternalResolvePlaceholder) //use the parameter at the current index if it is not a placeholder { - object currentParameter = registration.Parameters[i]; - if (currentParameter is not InternalResolvePlaceholder) //use the parameter at the current index if it is not a placeholder - { - newArguments[i] = currentParameter; - continue; - } + newArguments[i] = currentParameter; + continue; } + } - object? firstArgument = arguments.FirstOrGiven(a => a is not InternalResolvePlaceholder); //find the first argument that is not a placeholder - if (firstArgument is InternalResolvePlaceholder) //no more arguments available - break; //there won't be any more arguments - - newArguments[i] = firstArgument; + object? firstArgument = arguments.FirstOrGiven(a => a is not InternalResolvePlaceholder); //find the first argument that is not a placeholder + if (firstArgument is InternalResolvePlaceholder) //no more arguments available + break; //there won't be any more arguments - int indexOfFirstArgument = Array.IndexOf(arguments, firstArgument); - arguments[indexOfFirstArgument] = new InternalResolvePlaceholder(); - } + newArguments[i] = firstArgument; - arguments = newArguments; + int indexOfFirstArgument = Array.IndexOf(arguments, firstArgument); + arguments[indexOfFirstArgument] = new InternalResolvePlaceholder(); } - else //no more arguments were passed to resolve -> only use parameters set during registration - arguments = registration.Parameters; - return arguments; + arguments = newArguments; } + else //no more arguments were passed to resolve -> only use parameters set during registration + arguments = registration.Parameters; - /// - /// Try to get the resolve stack for a given - /// - /// The given - /// The given arguments - /// The current resolve stack - /// - /// result: True if successful, false if not - /// parameters: The parameters needed to resolve the given - /// exception: A if no matching constructor was found - /// - private (bool result, List? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack(Type type, object?[]? arguments, List resolveStack) - { - NoMatchingConstructorFoundException? noMatchingConstructorFoundException = null; + return arguments; + } + + /// + /// Try to get the resolve stack for a given + /// + /// The given + /// The given arguments + /// The current resolve stack + /// + /// result: True if successful, false if not + /// parameters: The parameters needed to resolve the given + /// exception: A if no matching constructor was found + /// + private (bool result, List? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack(Type type, object?[]? arguments, List resolveStack) + { + NoMatchingConstructorFoundException? noMatchingConstructorFoundException = null; - //find best ctor - List sortedConstructors = TryGetSortedConstructors(type); - foreach (ConstructorInfo constructor in sortedConstructors) - { - (bool result, List? parameters, List? exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); - - if (result) - return (true, parameters, null); + //find best ctor + List sortedConstructors = TryGetSortedConstructors(type); + foreach (ConstructorInfo constructor in sortedConstructors) + { + (bool result, List? parameters, List? exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); + + if (result) + return (true, parameters, null); - noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type); - exceptions?.ForEach(e => noMatchingConstructorFoundException.AddInnerException(e)); - } - - return (false, null, noMatchingConstructorFoundException); + noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type); + exceptions?.ForEach(e => noMatchingConstructorFoundException.AddInnerException(e)); } - /// - /// Try to get the resolve stack for a given constructor - /// - /// The for the given constructor - /// The given arguments - /// The current resolve stack - /// - /// result: True if successful, false if not - /// parameters: The parameters needed to resolve the given - /// exception: A List of s if the constructor is not matching - /// - private (bool result, List? parameters, List? exceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, object?[]? arguments, List resolveStack) - { - List constructorParameters = constructor.GetParameters().ToList(); - if (!constructorParameters.Any()) - return (true, null, null); + return (false, null, noMatchingConstructorFoundException); + } + + /// + /// Try to get the resolve stack for a given constructor + /// + /// The for the given constructor + /// The given arguments + /// The current resolve stack + /// + /// result: True if successful, false if not + /// parameters: The parameters needed to resolve the given + /// exception: A List of s if the constructor is not matching + /// + private (bool result, List? parameters, List? exceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, object?[]? arguments, List resolveStack) + { + List constructorParameters = constructor.GetParameters().ToList(); + if (!constructorParameters.Any()) + return (true, null, null); - List exceptions = new(); - List parameters = new(); + List exceptions = new(); + List parameters = new(); - List? passedArguments = null; - if (arguments != null) - passedArguments = new List(arguments); + List? passedArguments = null; + if (arguments != null) + passedArguments = new List(arguments); - foreach (ParameterInfo parameter in constructorParameters) + foreach (ParameterInfo parameter in constructorParameters) + { + object? fittingArgument = new InternalResolvePlaceholder(); + if (passedArguments != null) { - object? fittingArgument = new InternalResolvePlaceholder(); - if (passedArguments != null) - { - fittingArgument = passedArguments.FirstOrGiven(a => - a?.GetType() == parameter.ParameterType || parameter.ParameterType.IsInstanceOfType(a)); + fittingArgument = passedArguments.FirstOrGiven(a => + a?.GetType() == parameter.ParameterType || parameter.ParameterType.IsInstanceOfType(a)); - if (fittingArgument is not InternalResolvePlaceholder) - passedArguments.Remove(fittingArgument); - } + if (fittingArgument is not InternalResolvePlaceholder) + passedArguments.Remove(fittingArgument); + } - if (fittingArgument is InternalResolvePlaceholder) + if (fittingArgument is InternalResolvePlaceholder) + { + try { - try - { - fittingArgument = TryResolveNonGeneric(parameter.ParameterType, null, resolveStack); - } - catch (Exception exception) - { - exceptions.Add(new ConstructorNotMatchingException(constructor, exception)); - } + fittingArgument = TryResolveNonGeneric(parameter.ParameterType, null, resolveStack); + } + catch (Exception exception) + { + exceptions.Add(new ConstructorNotMatchingException(constructor, exception)); + } - if (fittingArgument is InternalResolvePlaceholder && passedArguments != null) - { - fittingArgument = passedArguments.FirstOrGiven(a => parameter.ParameterType.GetDefault() == a); + if (fittingArgument is InternalResolvePlaceholder && passedArguments != null) + { + fittingArgument = passedArguments.FirstOrGiven(a => parameter.ParameterType.GetDefault() == a); - if (fittingArgument is not InternalResolvePlaceholder) - passedArguments.Remove(fittingArgument); - } + if (fittingArgument is not InternalResolvePlaceholder) + passedArguments.Remove(fittingArgument); } - - if (fittingArgument is InternalResolvePlaceholder && parameter.HasDefaultValue) - parameters.Add(parameter.DefaultValue); - else - parameters.Add(fittingArgument); } - return (!parameters.Any(p => p is InternalResolvePlaceholder), parameters, exceptions); + if (fittingArgument is InternalResolvePlaceholder && parameter.HasDefaultValue) + parameters.Add(parameter.DefaultValue); + else + parameters.Add(fittingArgument); } - /// - /// Find the for the given - /// - /// The given - /// The for the given - private IRegistration? FindRegistration() => FindRegistration(typeof(T)); - - /// - /// Find the for the given - /// - /// The given - /// The for the given - private IRegistration? FindRegistration(Type type) - { - IRegistration? registration = Registrations.FirstOrDefault(r => r.InterfaceType == type); - if (registration != null) - return registration; + return (!parameters.Any(p => p is InternalResolvePlaceholder), parameters, exceptions); + } - registration = Registrations.OfType().FirstOrDefault(r => r.ImplementationType == type); - if (registration != null) - return registration; + /// + /// Find the for the given + /// + /// The given + /// The for the given + private IRegistration? FindRegistration() => FindRegistration(typeof(T)); + + /// + /// Find the for the given + /// + /// The given + /// The for the given + private IRegistration? FindRegistration(Type type) + { + IRegistration? registration = Registrations.FirstOrDefault(r => r.InterfaceType == type); + if (registration != null) + return registration; + + registration = Registrations.OfType().FirstOrDefault(r => r.ImplementationType == type); + if (registration != null) + return registration; - //check for open generic registration - if (!type.GenericTypeArguments.Any()) - return null; + //check for open generic registration + if (!type.GenericTypeArguments.Any()) + return null; - List openGenericRegistrations = Registrations.Where(r => r.InterfaceType.ContainsGenericParameters).ToList(); - return !openGenericRegistrations.Any() ? null : openGenericRegistrations.FirstOrDefault(r => r.InterfaceType == type.GetGenericTypeDefinition()); - } + List openGenericRegistrations = Registrations.Where(r => r.InterfaceType.ContainsGenericParameters).ToList(); + return !openGenericRegistrations.Any() ? null : openGenericRegistrations.FirstOrDefault(r => r.InterfaceType == type.GetGenericTypeDefinition()); + } - /// - /// Try to get the sorted constructors for the given - /// - /// The given - /// A list of sorted for the given - /// No public constructor was found for the given - private List TryGetSortedConstructors(Type type) - { - List sortedConstructors = type.GetConstructors().OrderByDescending(c => c.GetParameters().Length).ToList(); - if (!sortedConstructors.Any()) //no public constructor available - throw new NoPublicConstructorFoundException(type); + /// + /// Try to get the sorted constructors for the given + /// + /// The given + /// A list of sorted for the given + /// No public constructor was found for the given + private List TryGetSortedConstructors(Type type) + { + List sortedConstructors = type.GetConstructors().OrderByDescending(c => c.GetParameters().Length).ToList(); + if (!sortedConstructors.Any()) //no public constructor available + throw new NoPublicConstructorFoundException(type); - return sortedConstructors; - } - - /// - /// Get the implementation type for the given - /// - /// The given - /// The given of the interface - /// The implementation for the given - /// Unknown passed - private Type GetType(IRegistration registration) => - registration switch - { - ITypedRegistration typedRegistration => typedRegistration.ImplementationType, - ISingleTypeRegistration singleTypeRegistration => singleTypeRegistration.InterfaceType, - _ => throw new UnknownRegistrationException($"Unknown registration used: {registration.GetType().Name}.") - }; + return sortedConstructors; + } - /// - /// Check the given resolve stack for circular dependencies - /// - /// The given resolve stack - /// The given - /// The new resolve stack - /// A circular dependency was detected - private List CheckForCircularDependencies(List? resolveStack) + /// + /// Get the implementation type for the given + /// + /// The given + /// The given of the interface + /// The implementation for the given + /// Unknown passed + private Type GetType(IRegistration registration) => + registration switch { - if (resolveStack == null) //first resolve call - resolveStack = new List {typeof(T)}; //create new stack and add the currently resolving type to the stack - else if (resolveStack.Contains(typeof(T))) - throw new CircularDependencyException(typeof(T), resolveStack); //currently resolving type is still resolving -> circular dependency - else //not the first resolve call in chain but no circular dependencies for now - resolveStack.Add(typeof(T)); //add currently resolving type to the stack + ITypedRegistration typedRegistration => typedRegistration.ImplementationType, + ISingleTypeRegistration singleTypeRegistration => singleTypeRegistration.InterfaceType, + _ => throw new UnknownRegistrationException($"Unknown registration used: {registration.GetType().Name}.") + }; + + /// + /// Check the given resolve stack for circular dependencies + /// + /// The given resolve stack + /// The given + /// The new resolve stack + /// A circular dependency was detected + private List CheckForCircularDependencies(List? resolveStack) + { + if (resolveStack == null) //first resolve call + resolveStack = new List {typeof(T)}; //create new stack and add the currently resolving type to the stack + else if (resolveStack.Contains(typeof(T))) + throw new CircularDependencyException(typeof(T), resolveStack); //currently resolving type is still resolving -> circular dependency + else //not the first resolve call in chain but no circular dependencies for now + resolveStack.Add(typeof(T)); //add currently resolving type to the stack - return resolveStack; - } + return resolveStack; + } - /// - /// Clear the multiton instances of the given from the registered multitons list - /// - /// The to clear the multiton instances - public void ClearMultitonInstances() - { - IRegistration? registration = FindRegistration(); - if (registration is not IMultitonRegistration multitonRegistration) - return; + /// + /// Clear the multiton instances of the given from the registered multitons list + /// + /// The to clear the multiton instances + public void ClearMultitonInstances() + { + IRegistration? registration = FindRegistration(); + if (registration is not IMultitonRegistration multitonRegistration) + return; - var multitonInstance = _multitons.FirstOrDefault(m => m.type == multitonRegistration.ImplementationType); + var multitonInstance = _multitons.FirstOrDefault(m => m.type == multitonRegistration.ImplementationType); - //it is allowed to clear a non existing multiton instance (don't throw an exception) - if (multitonInstance == default) - return; + //it is allowed to clear a non existing multiton instance (don't throw an exception) + if (multitonInstance == default) + return; - _multitons.Remove(multitonInstance); - } + _multitons.Remove(multitonInstance); + } - /// - /// Is the given registered with this - /// - /// The given - /// True if the given is registered with this , false if not - public bool IsTypeRegistered() => FindRegistration() != null; - - /// - /// The method - /// - public void Dispose() - { - _singletons.Where(s => FindRegistration(s.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container}) - .Select(s => s.instance) - .OfType() - .ForEach(d => d.Dispose()); - - _multitons.Where(m => FindRegistration(m.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container}) - .SelectMany(m => m.instances) - .Select(i => i.Value) - .OfType() - .ForEach(d => d.Dispose()); + /// + /// Is the given registered with this + /// + /// The given + /// True if the given is registered with this , false if not + public bool IsTypeRegistered() => FindRegistration() != null; + + /// + /// The method + /// + public void Dispose() + { + _singletons.Where(s => FindRegistration(s.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container}) + .Select(s => s.instance) + .OfType() + .ForEach(d => d.Dispose()); + + _multitons.Where(m => FindRegistration(m.type) is IWithDisposeStrategyInternal {DisposeStrategy: DisposeStrategy.Container}) + .SelectMany(m => m.instances) + .Select(i => i.Value) + .OfType() + .ForEach(d => d.Dispose()); - Registrations.Clear(); - _singletons.Clear(); - _multitons.Clear(); - } + Registrations.Clear(); + _singletons.Clear(); + _multitons.Clear(); } } \ No newline at end of file diff --git a/LightweightIocContainer/Lifestyle.cs b/LightweightIocContainer/Lifestyle.cs index 973e0ee..06a4356 100644 --- a/LightweightIocContainer/Lifestyle.cs +++ b/LightweightIocContainer/Lifestyle.cs @@ -4,26 +4,25 @@ using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +/// +/// The Lifestyles that can be used for a +/// +public enum Lifestyle { /// - /// The Lifestyles that can be used for a + /// A new instance gets created every time an instance is resolved /// - public enum Lifestyle - { - /// - /// A new instance gets created every time an instance is resolved - /// - Transient, + Transient, - /// - /// One instance is created that gets returned every time an instance is resolved - /// - Singleton, + /// + /// One instance is created that gets returned every time an instance is resolved + /// + Singleton, - /// - /// A new instance gets created if the given scope has no created instance yet. Otherwise the already created instance is used. - /// - Multiton - } + /// + /// A new instance gets created if the given scope has no created instance yet. Otherwise the already created instance is used. + /// + Multiton } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs index 877c933..903085d 100644 --- a/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs +++ b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs @@ -7,55 +7,54 @@ using System.Collections.Generic; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// An to register multiple interfaces for on implementation type that implements them as a multiton +/// +/// The first interface +/// The second interface +/// The implementation +internal class MultipleMultitonRegistration : MultitonRegistration, IMultipleMultitonRegistration where TImplementation : TInterface1, TInterface2 { /// /// An to register multiple interfaces for on implementation type that implements them as a multiton /// - /// The first interface - /// The second interface - /// The implementation - internal class MultipleMultitonRegistration : MultitonRegistration, IMultipleMultitonRegistration where TImplementation : TInterface1, TInterface2 + /// The of the first interface + /// The of the second interface + /// The of the implementation + /// The of the multiton scope + /// The current instance of the + public MultipleMultitonRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Type scope, IocContainer container) + : base(interfaceType1, implementationType, scope, container) { - /// - /// An to register multiple interfaces for on implementation type that implements them as a multiton - /// - /// The of the first interface - /// The of the second interface - /// The of the implementation - /// The of the multiton scope - /// The current instance of the - public MultipleMultitonRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Type scope, IocContainer container) - : base(interfaceType1, implementationType, scope, container) + Registrations = new List { - Registrations = new List - { - new MultitonRegistration(interfaceType1, implementationType, scope, container), - new MultitonRegistration(interfaceType2, implementationType, scope, container) - }; - } + new MultitonRegistration(interfaceType1, implementationType, scope, container), + new MultitonRegistration(interfaceType2, implementationType, scope, container) + }; + } - /// - /// A of s that are registered within this - /// - public List Registrations { get; } + /// + /// A of s that are registered within this + /// + public List Registrations { get; } - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public override ITypedRegistration OnCreate(Action action) + /// + /// Pass an that will be invoked when an instance of this type is created + /// + /// The + /// The current instance of this + public override ITypedRegistration OnCreate(Action action) + { + foreach (IRegistration registration in Registrations) { - foreach (IRegistration registration in Registrations) - { - if (registration is IMultitonRegistration interface2Registration) - interface2Registration.OnCreate(action); - else if (registration is IMultitonRegistration interface1Registration) - interface1Registration.OnCreate(action); - } - - return this; + if (registration is IMultitonRegistration interface2Registration) + interface2Registration.OnCreate(action); + else if (registration is IMultitonRegistration interface1Registration) + interface1Registration.OnCreate(action); } + + return this; } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/MultipleRegistration.cs b/LightweightIocContainer/Registrations/MultipleRegistration.cs index 0a24fb6..d944799 100644 --- a/LightweightIocContainer/Registrations/MultipleRegistration.cs +++ b/LightweightIocContainer/Registrations/MultipleRegistration.cs @@ -7,239 +7,238 @@ using System.Collections.Generic; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// The base class for every to register multiple interfaces +/// +/// The first interface +/// The implementation +internal abstract class MultipleRegistration : TypedRegistration, IMultipleRegistration where TImplementation : TInterface1 { /// - /// The base class for every to register multiple interfaces + /// The base class for every to register multiple interfaces + /// + /// The of the first interface + /// The of the implementation + /// The of this + /// The current instance of the + protected MultipleRegistration(Type interfaceType1, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType1, implementationType, lifestyle, container) => + Registrations = new List(); + + /// + /// A of s that are registered within this + /// + public List Registrations { get; protected init; } +} + +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The implementation +internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface1, TInterface2 +{ + /// + /// An to register multiple interfaces for on implementation type /// - /// The first interface - /// The implementation - internal abstract class MultipleRegistration : TypedRegistration, IMultipleRegistration where TImplementation : TInterface1 + /// The of the first interface + /// The of the second interface + /// The of the implementation + /// The of this + /// The current instance of the + public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType1, implementationType, lifestyle, container) { - /// - /// The base class for every to register multiple interfaces - /// - /// The of the first interface - /// The of the implementation - /// The of this - /// The current instance of the - protected MultipleRegistration(Type interfaceType1, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType1, implementationType, lifestyle, container) => - Registrations = new List(); - - /// - /// A of s that are registered within this - /// - public List Registrations { get; protected init; } + Registrations = new List + { + new TypedRegistration(interfaceType1, implementationType, lifestyle, container), + new TypedRegistration(interfaceType2, implementationType, lifestyle, container) + }; } /// - /// An to register multiple interfaces for on implementation type + /// Pass an that will be invoked when an instance of this type is created /// - /// The first interface - /// The second interface - /// The implementation - internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface1, TInterface2 + /// The + /// The current instance of this + public override ITypedRegistration OnCreate(Action action) { - /// - /// An to register multiple interfaces for on implementation type - /// - /// The of the first interface - /// The of the second interface - /// The of the implementation - /// The of this - /// The current instance of the - public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType1, implementationType, lifestyle, container) + foreach (IRegistration registration in Registrations) { - Registrations = new List - { - new TypedRegistration(interfaceType1, implementationType, lifestyle, container), - new TypedRegistration(interfaceType2, implementationType, lifestyle, container) - }; + if (registration is ITypedRegistration interface2Registration) + interface2Registration.OnCreate(action); + else if (registration is ITypedRegistration interface1Registration) + interface1Registration.OnCreate(action); } - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public override ITypedRegistration OnCreate(Action action) - { - foreach (IRegistration registration in Registrations) - { - if (registration is ITypedRegistration interface2Registration) - interface2Registration.OnCreate(action); - else if (registration is ITypedRegistration interface1Registration) - interface1Registration.OnCreate(action); - } - - return this; - } + return this; } +} +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The implementation +internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface3, TInterface2, TInterface1 +{ /// /// An to register multiple interfaces for on implementation type /// - /// The first interface - /// The second interface - /// The third interface - /// The implementation - internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface3, TInterface2, TInterface1 + /// The of the first interface + /// The of the second interface + /// The of the third interface + /// The of the implementation + /// The of this + /// The current instance of the + public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType1, implementationType, lifestyle, container) { - /// - /// An to register multiple interfaces for on implementation type - /// - /// The of the first interface - /// The of the second interface - /// The of the third interface - /// The of the implementation - /// The of this - /// The current instance of the - public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType1, implementationType, lifestyle, container) + Registrations = new List { - Registrations = new List - { - new TypedRegistration(interfaceType1, implementationType, lifestyle, container), - new TypedRegistration(interfaceType2, implementationType, lifestyle, container), - new TypedRegistration(interfaceType3, implementationType, lifestyle, container) - }; - } + new TypedRegistration(interfaceType1, implementationType, lifestyle, container), + new TypedRegistration(interfaceType2, implementationType, lifestyle, container), + new TypedRegistration(interfaceType3, implementationType, lifestyle, container) + }; + } - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public override ITypedRegistration OnCreate(Action action) + /// + /// Pass an that will be invoked when an instance of this type is created + /// + /// The + /// The current instance of this + public override ITypedRegistration OnCreate(Action action) + { + foreach (IRegistration registration in Registrations) { - foreach (IRegistration registration in Registrations) - { - if (registration is ITypedRegistration interface3Registration) - interface3Registration.OnCreate(action); - else if (registration is ITypedRegistration interface2Registration) - interface2Registration.OnCreate(action); - else if (registration is ITypedRegistration interface1Registration) - interface1Registration.OnCreate(action); - } - - return this; + if (registration is ITypedRegistration interface3Registration) + interface3Registration.OnCreate(action); + else if (registration is ITypedRegistration interface2Registration) + interface2Registration.OnCreate(action); + else if (registration is ITypedRegistration interface1Registration) + interface1Registration.OnCreate(action); } + + return this; } +} +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The fourth interface +/// The implementation +internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1 +{ /// /// An to register multiple interfaces for on implementation type /// - /// The first interface - /// The second interface - /// The third interface - /// The fourth interface - /// The implementation - internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface4, TInterface3, TInterface2, TInterface1 + /// The of the first interface + /// The of the second interface + /// The of the third interface + /// The of the fourth interface + /// The of the implementation + /// The of this + /// The current instance of the + public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type interfaceType4, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType1, implementationType, lifestyle, container) { - /// - /// An to register multiple interfaces for on implementation type - /// - /// The of the first interface - /// The of the second interface - /// The of the third interface - /// The of the fourth interface - /// The of the implementation - /// The of this - /// The current instance of the - public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type interfaceType4, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType1, implementationType, lifestyle, container) + Registrations = new List { - Registrations = new List - { - new TypedRegistration(interfaceType1, implementationType, lifestyle, container), - new TypedRegistration(interfaceType2, implementationType, lifestyle, container), - new TypedRegistration(interfaceType3, implementationType, lifestyle, container), - new TypedRegistration(interfaceType4, implementationType, lifestyle, container) - }; - } + new TypedRegistration(interfaceType1, implementationType, lifestyle, container), + new TypedRegistration(interfaceType2, implementationType, lifestyle, container), + new TypedRegistration(interfaceType3, implementationType, lifestyle, container), + new TypedRegistration(interfaceType4, implementationType, lifestyle, container) + }; + } - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public override ITypedRegistration OnCreate(Action action) + /// + /// Pass an that will be invoked when an instance of this type is created + /// + /// The + /// The current instance of this + public override ITypedRegistration OnCreate(Action action) + { + foreach (IRegistration registration in Registrations) { - foreach (IRegistration registration in Registrations) - { - if (registration is ITypedRegistration interface4Registration) - interface4Registration.OnCreate(action); - else if (registration is ITypedRegistration interface3Registration) - interface3Registration.OnCreate(action); - else if (registration is ITypedRegistration interface2Registration) - interface2Registration.OnCreate(action); - else if (registration is ITypedRegistration interface1Registration) - interface1Registration.OnCreate(action); - } - - return this; + if (registration is ITypedRegistration interface4Registration) + interface4Registration.OnCreate(action); + else if (registration is ITypedRegistration interface3Registration) + interface3Registration.OnCreate(action); + else if (registration is ITypedRegistration interface2Registration) + interface2Registration.OnCreate(action); + else if (registration is ITypedRegistration interface1Registration) + interface1Registration.OnCreate(action); } + + return this; } +} +/// +/// An to register multiple interfaces for on implementation type +/// +/// The first interface +/// The second interface +/// The third interface +/// The fourth interface +/// The fifth interface +/// The implementation +internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1 +{ /// /// An to register multiple interfaces for on implementation type /// - /// The first interface - /// The second interface - /// The third interface - /// The fourth interface - /// The fifth interface - /// The implementation - internal class MultipleRegistration : MultipleRegistration, IMultipleRegistration where TImplementation : TInterface5, TInterface4, TInterface3, TInterface2, TInterface1 + /// The of the first interface + /// The of the second interface + /// The of the third interface + /// The of the fourth interface + /// The of the fifth interface + /// The of the implementation + /// The of this + /// The current instance of the + public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type interfaceType4, Type interfaceType5, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType1, implementationType, lifestyle, container) { - /// - /// An to register multiple interfaces for on implementation type - /// - /// The of the first interface - /// The of the second interface - /// The of the third interface - /// The of the fourth interface - /// The of the fifth interface - /// The of the implementation - /// The of this - /// The current instance of the - public MultipleRegistration(Type interfaceType1, Type interfaceType2, Type interfaceType3, Type interfaceType4, Type interfaceType5, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType1, implementationType, lifestyle, container) + Registrations = new List { - Registrations = new List - { - new TypedRegistration(interfaceType1, implementationType, lifestyle, container), - new TypedRegistration(interfaceType2, implementationType, lifestyle, container), - new TypedRegistration(interfaceType3, implementationType, lifestyle, container), - new TypedRegistration(interfaceType4, implementationType, lifestyle, container), - new TypedRegistration(interfaceType5, implementationType, lifestyle, container) - }; - } + new TypedRegistration(interfaceType1, implementationType, lifestyle, container), + new TypedRegistration(interfaceType2, implementationType, lifestyle, container), + new TypedRegistration(interfaceType3, implementationType, lifestyle, container), + new TypedRegistration(interfaceType4, implementationType, lifestyle, container), + new TypedRegistration(interfaceType5, implementationType, lifestyle, container) + }; + } - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public override ITypedRegistration OnCreate(Action action) + /// + /// Pass an that will be invoked when an instance of this type is created + /// + /// The + /// The current instance of this + public override ITypedRegistration OnCreate(Action action) + { + foreach (IRegistration registration in Registrations) { - foreach (IRegistration registration in Registrations) - { - if (registration is ITypedRegistration interface5Registration) - interface5Registration.OnCreate(action); - else if (registration is ITypedRegistration interface4Registration) - interface4Registration.OnCreate(action); - else if (registration is ITypedRegistration interface3Registration) - interface3Registration.OnCreate(action); - else if (registration is ITypedRegistration interface2Registration) - interface2Registration.OnCreate(action); - else if (registration is ITypedRegistration interface1Registration) - interface1Registration.OnCreate(action); - } - - return this; + if (registration is ITypedRegistration interface5Registration) + interface5Registration.OnCreate(action); + else if (registration is ITypedRegistration interface4Registration) + interface4Registration.OnCreate(action); + else if (registration is ITypedRegistration interface3Registration) + interface3Registration.OnCreate(action); + else if (registration is ITypedRegistration interface2Registration) + interface2Registration.OnCreate(action); + else if (registration is ITypedRegistration interface1Registration) + interface1Registration.OnCreate(action); } + + return this; } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/MultitonRegistration.cs b/LightweightIocContainer/Registrations/MultitonRegistration.cs index 083cc13..366f05a 100644 --- a/LightweightIocContainer/Registrations/MultitonRegistration.cs +++ b/LightweightIocContainer/Registrations/MultitonRegistration.cs @@ -8,52 +8,51 @@ using LightweightIocContainer.Exceptions; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// The registration that is used to register a multiton +/// +/// The registered interface +/// The registered implementation +internal class MultitonRegistration : TypedRegistration, IMultitonRegistration where TImplementation : TInterface { /// /// The registration that is used to register a multiton /// - /// The registered interface - /// The registered implementation - internal class MultitonRegistration : TypedRegistration, IMultitonRegistration where TImplementation : TInterface - { - /// - /// The registration that is used to register a multiton - /// - /// The of the Interface - /// The of the Implementation - /// The of the Multiton Scope - /// The current instance of the - public MultitonRegistration(Type interfaceType, Type implementationType, Type scope, IocContainer container) - : base(interfaceType, implementationType, Lifestyle.Multiton, container) => - Scope = scope; + /// The of the Interface + /// The of the Implementation + /// The of the Multiton Scope + /// The current instance of the + public MultitonRegistration(Type interfaceType, Type implementationType, Type scope, IocContainer container) + : base(interfaceType, implementationType, Lifestyle.Multiton, container) => + Scope = scope; - /// - /// The of the multiton scope - /// - public Type Scope { get; } + /// + /// The of the multiton scope + /// + public Type Scope { get; } - /// - /// Validate the - /// - protected override void ValidateFactory() - { - if (Factory == null) - return; + /// + /// Validate the + /// + protected override void ValidateFactory() + { + if (Factory == null) + return; - if (Factory.CreateMethods.Any(c => c.GetParameters().Length == 0)) - throw new InvalidFactoryRegistrationException($"Create methods without parameters are not valid for multitons (Type: {InterfaceType})."); + if (Factory.CreateMethods.Any(c => c.GetParameters().Length == 0)) + throw new InvalidFactoryRegistrationException($"Create methods without parameters are not valid for multitons (Type: {InterfaceType})."); - if (Factory.CreateMethods.Any(c => c.GetParameters()[0].ParameterType != Scope)) - throw new InvalidFactoryRegistrationException($"Create methods without scope type ({Scope}) as first parameter are not valid for multitons (Type: {InterfaceType})."); + if (Factory.CreateMethods.Any(c => c.GetParameters()[0].ParameterType != Scope)) + throw new InvalidFactoryRegistrationException($"Create methods without scope type ({Scope}) as first parameter are not valid for multitons (Type: {InterfaceType})."); - base.ValidateFactory(); - } + base.ValidateFactory(); + } - public override bool Equals(object? obj) => obj is MultitonRegistration multitonRegistration && - base.Equals(obj) && - Scope == multitonRegistration.Scope; + public override bool Equals(object? obj) => obj is MultitonRegistration multitonRegistration && + base.Equals(obj) && + Scope == multitonRegistration.Scope; - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Scope); - } + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Scope); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/OpenGenericRegistration.cs b/LightweightIocContainer/Registrations/OpenGenericRegistration.cs index 0ecd184..a89a36c 100644 --- a/LightweightIocContainer/Registrations/OpenGenericRegistration.cs +++ b/LightweightIocContainer/Registrations/OpenGenericRegistration.cs @@ -7,47 +7,46 @@ using LightweightIocContainer.Exceptions; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// for open generic types +/// +internal class OpenGenericRegistration : RegistrationBase, IOpenGenericRegistration { /// /// for open generic types /// - internal class OpenGenericRegistration : RegistrationBase, IOpenGenericRegistration - { - /// - /// for open generic types - /// - /// The of the interface - /// The of the implementation type - /// The of this - /// The current instance of the - public OpenGenericRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle, IocContainer iocContainer) - : base(interfaceType, lifestyle, iocContainer) => - ImplementationType = implementationType; + /// The of the interface + /// The of the implementation type + /// The of this + /// The current instance of the + public OpenGenericRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle, IocContainer iocContainer) + : base(interfaceType, lifestyle, iocContainer) => + ImplementationType = implementationType; - /// - /// The that implements the that is registered with this - /// - public Type ImplementationType { get; } + /// + /// The that implements the that is registered with this + /// + public Type ImplementationType { get; } - /// - /// Validate this - /// - public override void Validate() - { - if (!InterfaceType.ContainsGenericParameters) - throw new InvalidRegistrationException("This function can only be used to register open generic types."); + /// + /// Validate this + /// + 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? + 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(); - } + base.Validate(); + } - public override bool Equals(object? obj) => obj is OpenGenericRegistration openGenericRegistration && - base.Equals(obj) && - ImplementationType == openGenericRegistration.ImplementationType; + public override bool Equals(object? obj) => obj is OpenGenericRegistration openGenericRegistration && + base.Equals(obj) && + ImplementationType == openGenericRegistration.ImplementationType; - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); - } + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/RegistrationBase.cs b/LightweightIocContainer/Registrations/RegistrationBase.cs index c95d968..f7c4128 100644 --- a/LightweightIocContainer/Registrations/RegistrationBase.cs +++ b/LightweightIocContainer/Registrations/RegistrationBase.cs @@ -12,236 +12,235 @@ using LightweightIocContainer.Interfaces.Registrations; using LightweightIocContainer.Interfaces.Registrations.Fluent; using LightweightIocContainer.ResolvePlaceholders; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// The that is used to register an Interface +/// +internal abstract class RegistrationBase : IRegistrationBase, IWithFactoryInternal, IWithParametersInternal, ILifestyleProvider, IWithDisposeStrategyInternal, IInternalValidationProvider { + private readonly IocContainer _container; + /// /// The that is used to register an Interface /// - internal abstract class RegistrationBase : IRegistrationBase, IWithFactoryInternal, IWithParametersInternal, ILifestyleProvider, IWithDisposeStrategyInternal, IInternalValidationProvider + /// The of the Interface + /// The of the registration + /// The current instance of the + protected RegistrationBase(Type interfaceType, Lifestyle lifestyle, IocContainer container) { - private readonly IocContainer _container; - - /// - /// The that is used to register an Interface - /// - /// The of the Interface - /// The of the registration - /// The current instance of the - protected RegistrationBase(Type interfaceType, Lifestyle lifestyle, IocContainer container) - { - InterfaceType = interfaceType; - Lifestyle = lifestyle; - _container = container; - } + InterfaceType = interfaceType; + Lifestyle = lifestyle; + _container = container; + } - /// - /// The of the Interface that is registered with this - /// - public Type InterfaceType { get; } + /// + /// The of the Interface that is registered with this + /// + public Type InterfaceType { get; } - /// - /// The of Instances that are created with this - /// - public Lifestyle Lifestyle { get; } + /// + /// The of Instances that are created with this + /// + public Lifestyle Lifestyle { get; } - /// - /// The of singletons/multitons that implement and are created with this - /// - public DisposeStrategy DisposeStrategy { get; private set; } - - /// - /// An of parameters that are used to an instance of this - /// Can be set in the by calling - /// - public object[]? Parameters { get; private set; } + /// + /// The of singletons/multitons that implement and are created with this + /// + public DisposeStrategy DisposeStrategy { get; private set; } + + /// + /// An of parameters that are used to an instance of this + /// Can be set in the by calling + /// + public object[]? Parameters { get; private set; } - /// - /// The Factory added with the method - /// - public ITypedFactory? Factory { get; private set; } - - /// - /// Pass parameters that will be used to an instance of this - /// Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving - /// - /// The parameters - /// The current instance of this - /// are already set or no parameters given - public virtual IRegistrationBase WithParameters(params object[] parameters) - { - if (Parameters != null) - throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType})."); + /// + /// The Factory added with the method + /// + public ITypedFactory? Factory { get; private set; } - if (parameters == null || !parameters.Any()) - throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType})."); + /// + /// Pass parameters that will be used to an instance of this + /// Parameters set with this method are always inserted at the beginning of the argument list if more parameters are given when resolving + /// + /// The parameters + /// The current instance of this + /// are already set or no parameters given + public virtual IRegistrationBase WithParameters(params object[] parameters) + { + if (Parameters != null) + throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType})."); - Parameters = parameters; - return this; - } + if (parameters == null || !parameters.Any()) + throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType})."); - /// - /// Pass parameters that will be used to an instance of this - /// Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving - /// - /// The parameters with their position - /// The current instance of this - /// are already set or no parameters given - public virtual IRegistrationBase WithParameters(params (int index, object parameter)[] parameters) - { - if (Parameters != null) - throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType})."); + Parameters = parameters; + return this; + } - if (parameters == null || !parameters.Any()) - throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType})."); + /// + /// Pass parameters that will be used to an instance of this + /// Parameters set with this method are inserted at the position in the argument list that is passed with the parameter if more parameters are given when resolving + /// + /// The parameters with their position + /// The current instance of this + /// are already set or no parameters given + public virtual IRegistrationBase WithParameters(params (int index, object parameter)[] parameters) + { + if (Parameters != null) + throw new InvalidRegistrationException($"Don't use `WithParameters()` method twice (Type: {InterfaceType})."); - int lastIndex = parameters.Max(p => p.index); - Parameters = new object[lastIndex + 1]; + if (parameters == null || !parameters.Any()) + throw new InvalidRegistrationException($"No parameters given to `WithParameters()` method (Type: {InterfaceType})."); - for (int i = 0; i < Parameters.Length; i++) - { - if (parameters.Any(p => p.index == i)) - Parameters[i] = parameters.First(p => p.index == i).parameter; - else - Parameters[i] = new InternalResolvePlaceholder(); - } + int lastIndex = parameters.Max(p => p.index); + Parameters = new object[lastIndex + 1]; - return this; + for (int i = 0; i < Parameters.Length; i++) + { + if (parameters.Any(p => p.index == i)) + Parameters[i] = parameters.First(p => p.index == i).parameter; + else + Parameters[i] = new InternalResolvePlaceholder(); } - /// - /// Register an abstract typed factory for the - /// - /// The type of the abstract typed factory - /// The current instance of this - public IRegistrationBase WithFactory() - { - TypedFactory factory = new(_container); - Factory = factory; + return this; + } + + /// + /// Register an abstract typed factory for the + /// + /// The type of the abstract typed factory + /// The current instance of this + public IRegistrationBase WithFactory() + { + TypedFactory factory = new(_container); + Factory = factory; - _container.RegisterFactory(factory); + _container.RegisterFactory(factory); - return this; - } + return this; + } - /// - /// Register a custom implemented factory for the - /// - /// The type of the interface for the custom factory - /// The type of the implementation for the custom factory - /// The current instance of this - public IRegistrationBase WithFactory() where TFactoryImplementation : TFactoryInterface - { - Factory = new CustomTypedFactory(); - _container.Register(r => r.Add()); + /// + /// Register a custom implemented factory for the + /// + /// The type of the interface for the custom factory + /// The type of the implementation for the custom factory + /// The current instance of this + public IRegistrationBase WithFactory() where TFactoryImplementation : TFactoryInterface + { + Factory = new CustomTypedFactory(); + _container.Register(r => r.Add()); - return this; - } + return this; + } - /// - /// Add a for the - /// - /// The - /// The current instance of this - public IRegistrationBase WithDisposeStrategy(DisposeStrategy disposeStrategy) - { - DisposeStrategy = disposeStrategy; - return this; - } + /// + /// Add a for the + /// + /// The + /// The current instance of this + public IRegistrationBase WithDisposeStrategy(DisposeStrategy disposeStrategy) + { + DisposeStrategy = disposeStrategy; + return this; + } - /// - /// Validate this - /// - public virtual void Validate() - { - ValidateMultiton(); - ValidateFactory(); - ValidateDisposeStrategy(); - } + /// + /// Validate this + /// + public virtual void Validate() + { + ValidateMultiton(); + ValidateFactory(); + ValidateDisposeStrategy(); + } - /// - /// Validate that no registration that isn't derived from has - /// - /// - 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)."); - } + /// + /// Validate that no registration that isn't derived from has + /// + /// + 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)."); + } - /// - /// Validate the - /// - /// No create method that can create the - protected virtual void ValidateFactory() - { - if (Factory == null) - return; + /// + /// Validate the + /// + /// No create method that can create the + protected virtual void ValidateFactory() + { + if (Factory == null) + return; - if (Factory.CreateMethods.All(c => c.ReturnType != InterfaceType)) - throw new InvalidFactoryRegistrationException($"No create method that can create {InterfaceType}."); - } + if (Factory.CreateMethods.All(c => c.ReturnType != InterfaceType)) + throw new InvalidFactoryRegistrationException($"No create method that can create {InterfaceType}."); + } - /// - /// Validate the for the and - /// - protected virtual void ValidateDisposeStrategy() => ValidateDisposeStrategy(InterfaceType); - - /// - /// Validate the for the given and - /// - /// The given - /// Dispose strategy is invalid for this and - protected void ValidateDisposeStrategy(Type type) + /// + /// Validate the for the and + /// + protected virtual void ValidateDisposeStrategy() => ValidateDisposeStrategy(InterfaceType); + + /// + /// Validate the for the given and + /// + /// The given + /// Dispose strategy is invalid for this and + protected void ValidateDisposeStrategy(Type type) + { + if (Lifestyle == Lifestyle.Transient) { - if (Lifestyle == Lifestyle.Transient) + if (DisposeStrategy != DisposeStrategy.None) + throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle); + } + else + { + if (type.IsAssignableTo(typeof(IDisposable))) { - if (DisposeStrategy != DisposeStrategy.None) + if (DisposeStrategy == DisposeStrategy.None) throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle); } else { - if (type.IsAssignableTo(typeof(IDisposable))) - { - if (DisposeStrategy == DisposeStrategy.None) - throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle); - } - else - { - if (DisposeStrategy != DisposeStrategy.None) - throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle); - } + if (DisposeStrategy != DisposeStrategy.None) + throw new InvalidDisposeStrategyException(DisposeStrategy, type, Lifestyle); } } + } - public override bool Equals(object? obj) - { - if (obj is not RegistrationBase registrationBase) - return false; + public override bool Equals(object? obj) + { + if (obj is not RegistrationBase registrationBase) + return false; - if (Parameters == null && registrationBase.Parameters != null) - return false; + if (Parameters == null && registrationBase.Parameters != null) + return false; - if (Parameters != null && registrationBase.Parameters == null) - return false; + if (Parameters != null && registrationBase.Parameters == null) + return false; - if (Parameters?.Length != registrationBase.Parameters?.Length) - return false; + if (Parameters?.Length != registrationBase.Parameters?.Length) + return false; - if (Factory == null && registrationBase.Factory != null) - return false; + if (Factory == null && registrationBase.Factory != null) + return false; - if (Factory != null && registrationBase.Factory == null) - return false; + if (Factory != null && registrationBase.Factory == null) + return false; - if (Factory?.CreateMethods.Count != registrationBase.Factory?.CreateMethods.Count) - return false; + if (Factory?.CreateMethods.Count != registrationBase.Factory?.CreateMethods.Count) + return false; - return InterfaceType == registrationBase.InterfaceType && - Lifestyle == registrationBase.Lifestyle && - DisposeStrategy == registrationBase.DisposeStrategy; - } - - public override int GetHashCode() => HashCode.Combine(InterfaceType, (int) Lifestyle); + return InterfaceType == registrationBase.InterfaceType && + Lifestyle == registrationBase.Lifestyle && + DisposeStrategy == registrationBase.DisposeStrategy; } + + public override int GetHashCode() => HashCode.Combine(InterfaceType, (int) Lifestyle); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/RegistrationFactory.cs b/LightweightIocContainer/Registrations/RegistrationFactory.cs index 9d2ee47..d835dc5 100644 --- a/LightweightIocContainer/Registrations/RegistrationFactory.cs +++ b/LightweightIocContainer/Registrations/RegistrationFactory.cs @@ -7,121 +7,120 @@ using LightweightIocContainer.Interfaces.Factories; using LightweightIocContainer.Interfaces.Installers; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// A factory to register interfaces and factories in an and create the needed s +/// +internal class RegistrationFactory { - /// - /// A factory to register interfaces and factories in an and create the needed s - /// - internal class RegistrationFactory - { - private readonly IocContainer _iocContainer; + private readonly IocContainer _iocContainer; - internal RegistrationFactory(IocContainer container) => _iocContainer = container; + internal RegistrationFactory(IocContainer container) => _iocContainer = container; - /// - /// Register an Interface with a Type that implements it and create a - /// - /// The Interface to register - /// The Type that implements the interface - /// The for this - /// A new created with the given parameters - public ITypedRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface => - new TypedRegistration(typeof(TInterface), typeof(TImplementation), lifestyle, _iocContainer); + /// + /// Register an Interface with a Type that implements it and create a + /// + /// The Interface to register + /// The Type that implements the interface + /// The for this + /// A new created with the given parameters + public ITypedRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface => + new TypedRegistration(typeof(TInterface), typeof(TImplementation), lifestyle, _iocContainer); - /// - /// Register an open generic Interface with an open generic Type that implements it and create a - /// - /// The open generic Interface to register - /// The open generic Type that implements the interface - /// The for this - /// The created - public IOpenGenericRegistration Register(Type tInterface, Type tImplementation, Lifestyle lifestyle) => - new OpenGenericRegistration(tInterface, tImplementation, lifestyle, _iocContainer); + /// + /// Register an open generic Interface with an open generic Type that implements it and create a + /// + /// The open generic Interface to register + /// The open generic Type that implements the interface + /// The for this + /// The created + public IOpenGenericRegistration Register(Type tInterface, Type tImplementation, Lifestyle lifestyle) => + new OpenGenericRegistration(tInterface, tImplementation, lifestyle, _iocContainer); - /// - /// Register multiple interfaces for a that implements them and create a - /// - /// The base interface to register - /// A second interface to register - /// The that implements both interfaces - /// The for this - /// The created - public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2 => - new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), lifestyle, _iocContainer); + /// + /// Register multiple interfaces for a that implements them and create a + /// + /// The base interface to register + /// A second interface to register + /// The that implements both interfaces + /// The for this + /// The created + public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2 => + new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), lifestyle, _iocContainer); - /// - /// Register multiple interfaces for a that implements them and create a - /// - /// The base interface to register - /// A second interface to register - /// A third interface to register - /// The that implements both interfaces - /// The for this - /// The created - public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3 => - new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TImplementation), lifestyle, _iocContainer); + /// + /// Register multiple interfaces for a that implements them and create a + /// + /// The base interface to register + /// A second interface to register + /// A third interface to register + /// The that implements both interfaces + /// The for this + /// The created + public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3 => + new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TImplementation), lifestyle, _iocContainer); - /// - /// Register multiple interfaces for a that implements them and create a - /// - /// The base interface to register - /// A second interface to register - /// A third interface to register - /// A fourth interface to register - /// The that implements both interfaces - /// The for this - /// The created - public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4 => - new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TInterface4), typeof(TImplementation), lifestyle, _iocContainer); + /// + /// Register multiple interfaces for a that implements them and create a + /// + /// The base interface to register + /// A second interface to register + /// A third interface to register + /// A fourth interface to register + /// The that implements both interfaces + /// The for this + /// The created + public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4 => + new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TInterface4), typeof(TImplementation), lifestyle, _iocContainer); - /// - /// Register multiple interfaces for a that implements them and create a - /// - /// The base interface to register - /// A second interface to register - /// A third interface to register - /// A fourth interface to register - /// A fifth interface to register - /// The that implements both interfaces - /// The for this - /// The created - public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4, TInterface5 => - new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TInterface4), typeof(TInterface5), typeof(TImplementation), lifestyle, _iocContainer); + /// + /// Register multiple interfaces for a that implements them and create a + /// + /// The base interface to register + /// A second interface to register + /// A third interface to register + /// A fourth interface to register + /// A fifth interface to register + /// The that implements both interfaces + /// The for this + /// The created + public IMultipleRegistration Register(Lifestyle lifestyle) where TImplementation : TInterface1, TInterface2, TInterface3, TInterface4, TInterface5 => + new MultipleRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TInterface4), typeof(TInterface5), typeof(TImplementation), lifestyle, _iocContainer); - /// - /// Register a without an interface and create a - /// - /// The to register - /// The for this - /// A new created with the given parameters - public ISingleTypeRegistration Register(Lifestyle lifestyle) => new SingleTypeRegistration(typeof(T), lifestyle, _iocContainer); + /// + /// Register a without an interface and create a + /// + /// The to register + /// The for this + /// A new created with the given parameters + public ISingleTypeRegistration Register(Lifestyle lifestyle) => new SingleTypeRegistration(typeof(T), lifestyle, _iocContainer); - /// - /// Register an Interface with a Type that implements it as a multiton and create a - /// - /// The Interface to register - /// The Type that implements the interface - /// The Type of the multiton scope - /// A new created with the given parameters - public IMultitonRegistration RegisterMultiton() where TImplementation : TInterface => - new MultitonRegistration(typeof(TInterface), typeof(TImplementation), typeof(TScope), _iocContainer); + /// + /// Register an Interface with a Type that implements it as a multiton and create a + /// + /// The Interface to register + /// The Type that implements the interface + /// The Type of the multiton scope + /// A new created with the given parameters + public IMultitonRegistration RegisterMultiton() where TImplementation : TInterface => + new MultitonRegistration(typeof(TInterface), typeof(TImplementation), typeof(TScope), _iocContainer); - /// - /// Register multiple interfaces for a that implements them as a multiton - /// - /// The base interface to register - /// A second interface to register - /// The Type that implements the interface - /// The Type of the multiton scope - /// A new created with the given parameters - public IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2 => - new MultipleMultitonRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), typeof(TScope), _iocContainer); + /// + /// Register multiple interfaces for a that implements them as a multiton + /// + /// The base interface to register + /// A second interface to register + /// The Type that implements the interface + /// The Type of the multiton scope + /// A new created with the given parameters + public IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2 => + new MultipleMultitonRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), typeof(TScope), _iocContainer); - /// - /// Register an Interface as an abstract typed factory and create a - /// - /// The abstract typed factory to register - /// A new created with the given parameters - public ITypedFactoryRegistration RegisterFactory(ITypedFactory factory) => new TypedFactoryRegistration(factory); - } + /// + /// Register an Interface as an abstract typed factory and create a + /// + /// The abstract typed factory to register + /// A new created with the given parameters + public ITypedFactoryRegistration RegisterFactory(ITypedFactory factory) => new TypedFactoryRegistration(factory); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/SingleTypeRegistration.cs b/LightweightIocContainer/Registrations/SingleTypeRegistration.cs index 64ea87f..9a2de27 100644 --- a/LightweightIocContainer/Registrations/SingleTypeRegistration.cs +++ b/LightweightIocContainer/Registrations/SingleTypeRegistration.cs @@ -6,56 +6,55 @@ using System; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// The to register either only an interface or only a +/// +/// The of the +internal class SingleTypeRegistration : RegistrationBase, ISingleTypeRegistration { /// /// The to register either only an interface or only a /// - /// The of the - internal class SingleTypeRegistration : RegistrationBase, ISingleTypeRegistration + /// The of the interface or + /// The of the + /// The current instance of the + public SingleTypeRegistration(Type interfaceType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType, lifestyle, container) { - /// - /// The to register either only an interface or only a - /// - /// The of the interface or - /// The of the - /// The current instance of the - public SingleTypeRegistration(Type interfaceType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType, lifestyle, container) - { - } - - /// - /// that is invoked instead of creating an instance of this the default way - /// - public Func? FactoryMethod { get; private set; } - - /// - /// Pass a that will be invoked instead of creating an instance of this the default way - /// - /// The - /// The current instance of this - public ISingleTypeRegistration WithFactoryMethod(Func factoryMethod) - { - FactoryMethod = factoryMethod; - return this; - } + } + + /// + /// that is invoked instead of creating an instance of this the default way + /// + public Func? FactoryMethod { get; private set; } + + /// + /// Pass a that will be invoked instead of creating an instance of this the default way + /// + /// The + /// The current instance of this + public ISingleTypeRegistration WithFactoryMethod(Func factoryMethod) + { + FactoryMethod = factoryMethod; + return this; + } - public override bool Equals(object? obj) - { - if (obj is not SingleTypeRegistration singleTypeRegistration) - return false; + public override bool Equals(object? obj) + { + if (obj is not SingleTypeRegistration singleTypeRegistration) + return false; - if (FactoryMethod == null && singleTypeRegistration.FactoryMethod != null) - return false; + if (FactoryMethod == null && singleTypeRegistration.FactoryMethod != null) + return false; - if (FactoryMethod != null && singleTypeRegistration.FactoryMethod == null) - return false; + if (FactoryMethod != null && singleTypeRegistration.FactoryMethod == null) + return false; - return base.Equals(obj); - } - - public override int GetHashCode() => base.GetHashCode(); + return base.Equals(obj); } + + public override int GetHashCode() => base.GetHashCode(); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs index 56277b5..4007d2d 100644 --- a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs +++ b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs @@ -6,34 +6,33 @@ using System; using LightweightIocContainer.Interfaces.Factories; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// The registration that is used to register an abstract typed factory +/// +/// The of the abstract typed factory +internal class TypedFactoryRegistration : ITypedFactoryRegistration { /// /// The registration that is used to register an abstract typed factory /// - /// The of the abstract typed factory - internal class TypedFactoryRegistration : ITypedFactoryRegistration - { - /// - /// The registration that is used to register an abstract typed factory - /// - /// The for this - public TypedFactoryRegistration(ITypedFactory factory) => Factory = factory; + /// The for this + public TypedFactoryRegistration(ITypedFactory factory) => Factory = factory; - /// - /// The of the factory that is registered with this - /// - public Type InterfaceType => typeof(TFactory); + /// + /// The of the factory that is registered with this + /// + public Type InterfaceType => typeof(TFactory); - /// - /// The class that contains the implemented abstract factory of this - /// - public ITypedFactory Factory { get; } + /// + /// The class that contains the implemented abstract factory of this + /// + public ITypedFactory Factory { get; } - public override bool Equals(object? obj) => obj is TypedFactoryRegistration factoryRegistration && - Factory.CreateMethods.Count == factoryRegistration.Factory.CreateMethods.Count && - InterfaceType == factoryRegistration.InterfaceType; + public override bool Equals(object? obj) => obj is TypedFactoryRegistration factoryRegistration && + Factory.CreateMethods.Count == factoryRegistration.Factory.CreateMethods.Count && + InterfaceType == factoryRegistration.InterfaceType; - public override int GetHashCode() => HashCode.Combine(InterfaceType); - } + public override int GetHashCode() => HashCode.Combine(InterfaceType); } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/TypedRegistration.cs b/LightweightIocContainer/Registrations/TypedRegistration.cs index 99b8e6f..a3a7fb7 100644 --- a/LightweightIocContainer/Registrations/TypedRegistration.cs +++ b/LightweightIocContainer/Registrations/TypedRegistration.cs @@ -8,74 +8,73 @@ using LightweightIocContainer.Interfaces.Installers; using LightweightIocContainer.Interfaces.Registrations; using LightweightIocContainer.Interfaces.Registrations.Fluent; -namespace LightweightIocContainer.Registrations +namespace LightweightIocContainer.Registrations; + +/// +/// A that implements a +/// +internal class TypedRegistration : RegistrationBase, ITypedRegistration where TImplementation : TInterface { /// /// A that implements a /// - internal class TypedRegistration : RegistrationBase, ITypedRegistration where TImplementation : TInterface - { - /// - /// A that implements a - /// - /// The of the interface - /// The of the implementation type - /// The of this - /// The current instance of the - public TypedRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle, IocContainer container) - : base(interfaceType, lifestyle, container) => - ImplementationType = implementationType; + /// The of the interface + /// The of the implementation type + /// The of this + /// The current instance of the + public TypedRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle, IocContainer container) + : base(interfaceType, lifestyle, container) => + ImplementationType = implementationType; - /// - /// The that implements the that is registered with this - /// - public Type ImplementationType { get; } + /// + /// The that implements the that is registered with this + /// + public Type ImplementationType { get; } - /// - /// This is invoked when an instance of this type is created. - /// Can be set in the by calling - /// - private Action? OnCreateAction { get; set; } + /// + /// This is invoked when an instance of this type is created. + /// Can be set in the by calling + /// + private Action? OnCreateAction { get; set; } - /// - /// This is invoked when an instance of this type is created. - /// Can be set in the by calling - /// - Action? IOnCreate.OnCreateAction => OnCreateAction; + /// + /// This is invoked when an instance of this type is created. + /// Can be set in the by calling + /// + Action? IOnCreate.OnCreateAction => OnCreateAction; - /// - /// Pass an that will be invoked when an instance of this type is created - /// - /// The - /// The current instance of this - public virtual ITypedRegistration OnCreate(Action action) - { - OnCreateAction = a => action((TImplementation?) a); - return this; - } + /// + /// Pass an that will be invoked when an instance of this type is created + /// + /// The + /// The current instance of this + public virtual ITypedRegistration OnCreate(Action action) + { + OnCreateAction = a => action((TImplementation?) a); + return this; + } - /// - /// Validate the for the and - /// - protected override void ValidateDisposeStrategy() => ValidateDisposeStrategy(ImplementationType); + /// + /// Validate the for the and + /// + protected override void ValidateDisposeStrategy() => ValidateDisposeStrategy(ImplementationType); - public override bool Equals(object? obj) - { - if (obj is not TypedRegistration typedRegistration) - return false; + public override bool Equals(object? obj) + { + if (obj is not TypedRegistration typedRegistration) + return false; - if (!base.Equals(obj)) - return false; + if (!base.Equals(obj)) + return false; - if (OnCreateAction == null && typedRegistration.OnCreateAction != null) - return false; + if (OnCreateAction == null && typedRegistration.OnCreateAction != null) + return false; - if (OnCreateAction != null && typedRegistration.OnCreateAction == null) - return false; + if (OnCreateAction != null && typedRegistration.OnCreateAction == null) + return false; - return ImplementationType == typedRegistration.ImplementationType; - } - - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); + return ImplementationType == typedRegistration.ImplementationType; } + + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), ImplementationType); } \ No newline at end of file diff --git a/LightweightIocContainer/ResolvePlaceholders/InternalResolvePlaceholder.cs b/LightweightIocContainer/ResolvePlaceholders/InternalResolvePlaceholder.cs index 4bfc7e9..15b776f 100644 --- a/LightweightIocContainer/ResolvePlaceholders/InternalResolvePlaceholder.cs +++ b/LightweightIocContainer/ResolvePlaceholders/InternalResolvePlaceholder.cs @@ -2,13 +2,12 @@ // Created: 2019-11-22 // Copyright(c) 2019 SimonG. All Rights Reserved. -namespace LightweightIocContainer.ResolvePlaceholders +namespace LightweightIocContainer.ResolvePlaceholders; + +/// +/// An internal placeholder that is used during the resolving process +/// +internal class InternalResolvePlaceholder { - /// - /// An internal placeholder that is used during the resolving process - /// - internal class InternalResolvePlaceholder - { - } } \ No newline at end of file diff --git a/LightweightIocContainer/ResolvePlaceholders/InternalToBeResolvedPlaceholder.cs b/LightweightIocContainer/ResolvePlaceholders/InternalToBeResolvedPlaceholder.cs index 09842da..dd9e292 100644 --- a/LightweightIocContainer/ResolvePlaceholders/InternalToBeResolvedPlaceholder.cs +++ b/LightweightIocContainer/ResolvePlaceholders/InternalToBeResolvedPlaceholder.cs @@ -6,33 +6,32 @@ using System; using System.Collections.Generic; using LightweightIocContainer.Interfaces.Registrations; -namespace LightweightIocContainer.ResolvePlaceholders +namespace LightweightIocContainer.ResolvePlaceholders; + +/// +/// An internal placeholder that is used to hold types that need to be resolved during the resolving process +/// +internal class InternalToBeResolvedPlaceholder : IInternalToBeResolvedPlaceholder { - /// - /// An internal placeholder that is used to hold types that need to be resolved during the resolving process - /// - internal class InternalToBeResolvedPlaceholder : IInternalToBeResolvedPlaceholder + public InternalToBeResolvedPlaceholder(Type resolvedType, IRegistration resolvedRegistration, List? parameters) { - public InternalToBeResolvedPlaceholder(Type resolvedType, IRegistration resolvedRegistration, List? parameters) - { - ResolvedType = resolvedType; - ResolvedRegistration = resolvedRegistration; - Parameters = parameters; - } + ResolvedType = resolvedType; + ResolvedRegistration = resolvedRegistration; + Parameters = parameters; + } - /// - /// The to be resolved - /// - public Type ResolvedType { get; } + /// + /// The to be resolved + /// + public Type ResolvedType { get; } - /// - /// The to be resolved - /// - public IRegistration ResolvedRegistration { get; } + /// + /// The to be resolved + /// + public IRegistration ResolvedRegistration { get; } - /// - /// The parameters needed to resolve the - /// - public List? Parameters { get; } - } + /// + /// The parameters needed to resolve the + /// + public List? Parameters { get; } } \ No newline at end of file diff --git a/LightweightIocContainer/TypeExtension.cs b/LightweightIocContainer/TypeExtension.cs index b0682d7..d86dbd5 100644 --- a/LightweightIocContainer/TypeExtension.cs +++ b/LightweightIocContainer/TypeExtension.cs @@ -4,15 +4,14 @@ using System; -namespace LightweightIocContainer +namespace LightweightIocContainer; + +internal static class TypeExtension { - internal static class TypeExtension - { - /// - /// Returns the default value for a given - /// - /// The given - /// The default value for the given - public static object? GetDefault(this Type type) => type.IsValueType ? Activator.CreateInstance(type) : null; - } + /// + /// Returns the default value for a given + /// + /// The given + /// The default value for the given + public static object? GetDefault(this Type type) => type.IsValueType ? Activator.CreateInstance(type) : null; } \ No newline at end of file diff --git a/LightweightIocContainer/Validation/IocValidator.cs b/LightweightIocContainer/Validation/IocValidator.cs index 7f8dce9..60e0a03 100644 --- a/LightweightIocContainer/Validation/IocValidator.cs +++ b/LightweightIocContainer/Validation/IocValidator.cs @@ -9,98 +9,97 @@ using LightweightIocContainer.Interfaces.Registrations; using LightweightIocContainer.Interfaces.Registrations.Fluent; using Moq; -namespace LightweightIocContainer.Validation +namespace LightweightIocContainer.Validation; + +/// +/// Validator for your to check if everything can be resolved with your current setup +/// +public class IocValidator { + private readonly IocContainer _iocContainer; + private readonly List<(Type type, object? parameter)> _parameters; + /// /// Validator for your to check if everything can be resolved with your current setup /// - public class IocValidator + /// The + public IocValidator(IocContainer iocContainer) { - private readonly IocContainer _iocContainer; - private readonly List<(Type type, object? parameter)> _parameters; - - /// - /// Validator for your to check if everything can be resolved with your current setup - /// - /// The - public IocValidator(IocContainer iocContainer) - { - _iocContainer = iocContainer; - _parameters = new List<(Type, object?)>(); - } + _iocContainer = iocContainer; + _parameters = new List<(Type, object?)>(); + } - /// - /// Add parameters that can't be default for your type to be created successfully - /// - /// The new value of the parameter - /// The of your registered interface - /// The of your - public void AddParameter(TParameter parameter) => _parameters.Add((typeof(TInterface), parameter)); + /// + /// Add parameters that can't be default for your type to be created successfully + /// + /// The new value of the parameter + /// The of your registered interface + /// The of your + public void AddParameter(TParameter parameter) => _parameters.Add((typeof(TInterface), parameter)); - /// - /// Validates your given and checks if everything can be resolved with the current setup - /// Collection of all exceptions that are thrown during validation - /// - public void Validate() - { - List validationExceptions = new(); + /// + /// Validates your given and checks if everything can be resolved with the current setup + /// Collection of all exceptions that are thrown during validation + /// + public void Validate() + { + List validationExceptions = new(); - foreach (IRegistration registration in _iocContainer.Registrations) - { - var definedParameters = _parameters.Where(p => p.type == registration.InterfaceType); + foreach (IRegistration registration in _iocContainer.Registrations) + { + var definedParameters = _parameters.Where(p => p.type == registration.InterfaceType); - if (registration is IWithFactoryInternal { Factory: { } } withFactoryRegistration) - { - (from createMethod in withFactoryRegistration.Factory.CreateMethods + if (registration is IWithFactoryInternal { Factory: { } } withFactoryRegistration) + { + (from createMethod in withFactoryRegistration.Factory.CreateMethods select createMethod.GetParameters().Select(p => p.ParameterType) into parameterTypes select (from parameterType in parameterTypes let definedParameter = definedParameters .FirstOrDefault(p => parameterType.IsInstanceOfType(p.parameter)) select definedParameter == default ? GetMockOrDefault(parameterType) : definedParameter.parameter).ToArray()) - .ToList() - .ForEach(p => TryResolve(registration.InterfaceType, p, validationExceptions, true)); - } - else - { - object?[] arguments = definedParameters.Select(p => p.parameter).ToArray(); - TryResolve(registration.InterfaceType, arguments, validationExceptions); - } + .ToList() + .ForEach(p => TryResolve(registration.InterfaceType, p, validationExceptions, true)); } - - if (validationExceptions.Any()) - throw new AggregateException("Validation failed.", validationExceptions); - } - - private void TryResolve(Type type, object?[]? arguments, List validationExceptions, bool isFactoryResolve = false) - { - try + else { - _iocContainer.TryResolveNonGeneric(type, arguments, null, isFactoryResolve); - } - catch (Exception exception) - { - validationExceptions.Add(exception); + object?[] arguments = definedParameters.Select(p => p.parameter).ToArray(); + TryResolve(registration.InterfaceType, arguments, validationExceptions); } } - private T GetMock() where T : class => new Mock().Object; - private object? GetMockOrDefault(Type type) + if (validationExceptions.Any()) + throw new AggregateException("Validation failed.", validationExceptions); + } + + private void TryResolve(Type type, object?[]? arguments, List validationExceptions, bool isFactoryResolve = false) + { + try { - if (type.IsValueType) - return Activator.CreateInstance(type); + _iocContainer.TryResolveNonGeneric(type, arguments, null, isFactoryResolve); + } + catch (Exception exception) + { + validationExceptions.Add(exception); + } + } - if (type == typeof(string)) - return string.Empty; + private T GetMock() where T : class => new Mock().Object; + private object? GetMockOrDefault(Type type) + { + if (type.IsValueType) + return Activator.CreateInstance(type); + + if (type == typeof(string)) + return string.Empty; - try - { - return GenericMethodCaller.CallPrivate(this, nameof(GetMock), type); - } - catch (Exception) - { - return null; - } + try + { + return GenericMethodCaller.CallPrivate(this, nameof(GetMock), type); + } + catch (Exception) + { + return null; } } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/ActionExtensionTest.cs b/Test.LightweightIocContainer/ActionExtensionTest.cs index 7c358cc..acc25dc 100644 --- a/Test.LightweightIocContainer/ActionExtensionTest.cs +++ b/Test.LightweightIocContainer/ActionExtensionTest.cs @@ -6,41 +6,40 @@ using System; using LightweightIocContainer; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class ActionExtensionTest { - [TestFixture] - public class ActionExtensionTest + private interface IBar { - private interface IBar - { - void Throw(); - } + void Throw(); + } - private interface IFoo : IBar - { + private interface IFoo : IBar + { - } + } - private class Foo : IFoo - { - public void Throw() => throw new Exception(); - } + private class Foo : IFoo + { + public void Throw() => throw new Exception(); + } - [Test] - public void TestConvert() - { - Action barAction = bar => bar.Throw(); - Action action = barAction.Convert(); - - Assert.Throws(() => action(new Foo())); - } - - [Test] - public void TestConvertActionNull() - { - Action barAction = null; - Assert.Null(barAction.Convert()); - } + [Test] + public void TestConvert() + { + Action barAction = bar => bar.Throw(); + Action action = barAction.Convert(); + + Assert.Throws(() => action(new Foo())); + } + + [Test] + public void TestConvertActionNull() + { + Action barAction = null; + Assert.Null(barAction.Convert()); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/AssemblyInstallerTest.cs b/Test.LightweightIocContainer/AssemblyInstallerTest.cs index 15fa82d..72c9e5e 100644 --- a/Test.LightweightIocContainer/AssemblyInstallerTest.cs +++ b/Test.LightweightIocContainer/AssemblyInstallerTest.cs @@ -14,65 +14,64 @@ using LightweightIocContainer.Interfaces.Registrations; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class AssemblyInstallerTest { - [TestFixture] - public class AssemblyInstallerTest + [UsedImplicitly] + public class TestInstaller : IIocInstaller { - [UsedImplicitly] - public class TestInstaller : IIocInstaller - { - public void Install(IRegistrationCollector registration) => registration.Add>(); - } + public void Install(IRegistrationCollector registration) => registration.Add>(); + } - [UsedImplicitly] - public class AssemblyWrapper : Assembly - { + [UsedImplicitly] + public class AssemblyWrapper : Assembly + { - } + } - [Test] - public void TestInstall() + [Test] + public void TestInstall() + { + List types = new() { - List types = new() - { - typeof(object), - typeof(TestInstaller) - }; + typeof(object), + typeof(TestInstaller) + }; - Mock assemblyMock = new(); - assemblyMock.Setup(a => a.GetTypes()).Returns(types.ToArray); + Mock assemblyMock = new(); + assemblyMock.Setup(a => a.GetTypes()).Returns(types.ToArray); - Mock registrationCollectorMock = new(); + Mock registrationCollectorMock = new(); - AssemblyInstaller assemblyInstaller = new(assemblyMock.Object); - assemblyInstaller.Install(registrationCollectorMock.Object); + AssemblyInstaller assemblyInstaller = new(assemblyMock.Object); + assemblyInstaller.Install(registrationCollectorMock.Object); - registrationCollectorMock.Verify(r => r.Add>>(It.IsAny()), Times.Once); - } + registrationCollectorMock.Verify(r => r.Add>>(It.IsAny()), Times.Once); + } - [Test] - public void TestFromAssemblyThis() - { - IIocContainer iocContainer = new IocContainer(); - iocContainer.Install(FromAssembly.This()); - } + [Test] + public void TestFromAssemblyThis() + { + IIocContainer iocContainer = new IocContainer(); + iocContainer.Install(FromAssembly.This()); + } - [Test] - public void TestFromAssemblyInstance() + [Test] + public void TestFromAssemblyInstance() + { + List types = new() { - List types = new() - { - typeof(object), - typeof(TestInstaller) - }; + typeof(object), + typeof(TestInstaller) + }; - Mock assemblyMock = new(); - assemblyMock.Setup(a => a.GetTypes()).Returns(types.ToArray); + Mock assemblyMock = new(); + assemblyMock.Setup(a => a.GetTypes()).Returns(types.ToArray); - IIocContainer iocContainer = new IocContainer(); - iocContainer.Install(FromAssembly.Instance(assemblyMock.Object)); - } + IIocContainer iocContainer = new IocContainer(); + iocContainer.Install(FromAssembly.Instance(assemblyMock.Object)); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/EnumerableExtensionTest.cs b/Test.LightweightIocContainer/EnumerableExtensionTest.cs index 95e0d3c..729f0cc 100644 --- a/Test.LightweightIocContainer/EnumerableExtensionTest.cs +++ b/Test.LightweightIocContainer/EnumerableExtensionTest.cs @@ -9,94 +9,93 @@ using LightweightIocContainer; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class EnumerableExtensionTest { - [TestFixture] - public class EnumerableExtensionTest + private class ListObject { - private class ListObject - { - public int Index { get; set; } - } + public int Index { get; set; } + } - private class Given : ListObject - { + private class Given : ListObject + { - } + } - [UsedImplicitly] - public interface ITest - { - void DoSomething(); - } + [UsedImplicitly] + public interface ITest + { + void DoSomething(); + } - [Test] - [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] - public void TestFirstOrGivenNoPredicateEmpty() - { - List list = new(); - Assert.IsInstanceOf(list.FirstOrGiven()); - } + [Test] + [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] + public void TestFirstOrGivenNoPredicateEmpty() + { + List list = new(); + Assert.IsInstanceOf(list.FirstOrGiven()); + } - [Test] - public void TestFirstOrGivenNoPredicate() + [Test] + public void TestFirstOrGivenNoPredicate() + { + List list = new() { - List list = new() - { - new ListObject {Index = 0}, - new ListObject {Index = 1}, - new ListObject {Index = 2}, - new ListObject {Index = 3} - }; - - ListObject listObject = list.FirstOrGiven(); + new ListObject {Index = 0}, + new ListObject {Index = 1}, + new ListObject {Index = 2}, + new ListObject {Index = 3} + }; + + ListObject listObject = list.FirstOrGiven(); - Assert.IsNotInstanceOf(listObject); - Assert.AreEqual(0, listObject.Index); - } + Assert.IsNotInstanceOf(listObject); + Assert.AreEqual(0, listObject.Index); + } - [Test] - [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] - public void TestFirstOrGivenPredicateEmpty() - { - List list = new(); - Assert.IsInstanceOf(list.FirstOrGiven(o => o.Index == 2)); - } + [Test] + [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] + public void TestFirstOrGivenPredicateEmpty() + { + List list = new(); + Assert.IsInstanceOf(list.FirstOrGiven(o => o.Index == 2)); + } - [Test] - public void TestFirstOrGivenPredicate() - { - List list = new() - { - new ListObject {Index = 0}, - new ListObject {Index = 1}, - new ListObject {Index = 2}, - new ListObject {Index = 3} - }; - - ListObject listObject = list.FirstOrGiven(o => o.Index == 2); - - Assert.IsNotInstanceOf(listObject); - Assert.AreEqual(2, listObject.Index); - } - - [Test] - public void TestForEach() + [Test] + public void TestFirstOrGivenPredicate() + { + List list = new() { - Mock test1 = new(); - Mock test2 = new(); - Mock test3 = new(); - Mock test4 = new(); + new ListObject {Index = 0}, + new ListObject {Index = 1}, + new ListObject {Index = 2}, + new ListObject {Index = 3} + }; + + ListObject listObject = list.FirstOrGiven(o => o.Index == 2); + + Assert.IsNotInstanceOf(listObject); + Assert.AreEqual(2, listObject.Index); + } + + [Test] + public void TestForEach() + { + Mock test1 = new(); + Mock test2 = new(); + Mock test3 = new(); + Mock test4 = new(); - IEnumerable enumerable = new[] { test1.Object, test2.Object, test3.Object, test4.Object }; + IEnumerable enumerable = new[] { test1.Object, test2.Object, test3.Object, test4.Object }; - enumerable.ForEach(t => t.DoSomething()); + 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); - } + 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); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs b/Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs index 54d2bf8..5932050 100644 --- a/Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs +++ b/Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs @@ -7,267 +7,266 @@ using LightweightIocContainer; using LightweightIocContainer.Exceptions; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class FluentFactoryRegistrationTest { - [TestFixture] - public class FluentFactoryRegistrationTest + public interface ITest { - public interface ITest - { - } + } - private class Test : ITest - { + private class Test : ITest + { - } + } - private class TestByte : ITest - { - [UsedImplicitly] - private readonly byte _id; + private class TestByte : ITest + { + [UsedImplicitly] + private readonly byte _id; - public TestByte(byte id) => _id = id; - } + public TestByte(byte id) => _id = id; + } - [UsedImplicitly] - private class TestConstructor : ITest + [UsedImplicitly] + private class TestConstructor : ITest + { + public TestConstructor(string name, Test test) { - public TestConstructor(string name, Test test) - { - } + } - public TestConstructor(Test test, string name = null) - { + public TestConstructor(Test test, string name = null) + { - } } + } - private interface ITestFactoryNoCreate - { + private interface ITestFactoryNoCreate + { - } + } - private interface ITestFactoryNonGenericClear - { - ITest Create(); + private interface ITestFactoryNonGenericClear + { + ITest Create(); - void ClearMultitonInstance(); - } + void ClearMultitonInstance(); + } - [UsedImplicitly] - public interface ITestFactory - { - ITest Create(); - ITest Create(string name); - ITest CreateTest(string name = null); - ITest Create(byte id); - } + [UsedImplicitly] + public interface ITestFactory + { + ITest Create(); + ITest Create(string name); + ITest CreateTest(string name = null); + ITest Create(byte id); + } - private class TestFactory : ITestFactory - { - public ITest Create() => new Test(); - public ITest Create(string name) => throw new System.NotImplementedException(); - public ITest CreateTest(string name = null) => throw new System.NotImplementedException(); - public ITest Create(byte id) => throw new System.NotImplementedException(); - } + private class TestFactory : ITestFactory + { + public ITest Create() => new Test(); + public ITest Create(string name) => throw new System.NotImplementedException(); + public ITest CreateTest(string name = null) => throw new System.NotImplementedException(); + public ITest Create(byte id) => throw new System.NotImplementedException(); + } - [UsedImplicitly] - public interface IMultitonTestFactory - { - ITest Create(MultitonScope scope); - void ClearMultitonInstance(); - } + [UsedImplicitly] + public interface IMultitonTestFactory + { + ITest Create(MultitonScope scope); + void ClearMultitonInstance(); + } - [UsedImplicitly] - public interface IInvalidMultitonTestFactory - { - ITest Create(MultitonScope scope); - ITest Create(int number); - } + [UsedImplicitly] + public interface IInvalidMultitonTestFactory + { + ITest Create(MultitonScope scope); + ITest Create(int number); + } - [UsedImplicitly] - public interface ITestFactoryWrongReturn - { - public MultitonScope Create(); - } + [UsedImplicitly] + public interface ITestFactoryWrongReturn + { + public MultitonScope Create(); + } - public class MultitonScope - { + public class MultitonScope + { - } + } - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestFluentFactoryRegistration() - { - _iocContainer.Register(r => r.Add().WithFactory()); + [Test] + public void TestFluentFactoryRegistration() + { + _iocContainer.Register(r => r.Add().WithFactory()); - ITestFactory factory = _iocContainer.Resolve(); - ITest test = factory.Create(); - ITest test2 = factory.CreateTest(); + ITestFactory factory = _iocContainer.Resolve(); + ITest test = factory.Create(); + ITest test2 = factory.CreateTest(); - Assert.IsInstanceOf(factory); - Assert.IsInstanceOf(test); - Assert.IsInstanceOf(test2); - } + Assert.IsInstanceOf(factory); + Assert.IsInstanceOf(test); + Assert.IsInstanceOf(test2); + } - [Test] - public void TestFluentFactoryRegistrationResolveWithoutFactoryFails() - { - _iocContainer.Register(r => r.Add().WithFactory()); - Assert.Throws(()=>_iocContainer.Resolve()); - } + [Test] + public void TestFluentFactoryRegistrationResolveWithoutFactoryFails() + { + _iocContainer.Register(r => r.Add().WithFactory()); + Assert.Throws(()=>_iocContainer.Resolve()); + } - [Test] - public void TestFluentFactoryRegistration_CustomFactory() - { - _iocContainer.Register(r => r.Add().WithFactory()); + [Test] + public void TestFluentFactoryRegistration_CustomFactory() + { + _iocContainer.Register(r => r.Add().WithFactory()); - ITestFactory factory = _iocContainer.Resolve(); - ITest test = factory.Create(); + ITestFactory factory = _iocContainer.Resolve(); + ITest test = factory.Create(); - Assert.IsInstanceOf(factory); - Assert.IsInstanceOf(test); - } + Assert.IsInstanceOf(factory); + Assert.IsInstanceOf(test); + } - [Test] - public void TestFluentFactoryRegistration_WithoutFactoryFails() - { - _iocContainer.Register(r => r.Add().WithFactory()); - Assert.Throws(()=>_iocContainer.Resolve()); - } + [Test] + public void TestFluentFactoryRegistration_WithoutFactoryFails() + { + _iocContainer.Register(r => r.Add().WithFactory()); + Assert.Throws(()=>_iocContainer.Resolve()); + } - [Test] - public void TestRegisterFactoryWithoutCreate() => Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); + [Test] + public void TestRegisterFactoryWithoutCreate() => Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); - [Test] - public void TestRegisterFactoryClearMultitonsNonGeneric() => Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); + [Test] + public void TestRegisterFactoryClearMultitonsNonGeneric() => Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); - [Test] - public void TestResolveFromFactory() - { - _iocContainer.Register(r => r.Add().WithFactory()); + [Test] + public void TestResolveFromFactory() + { + _iocContainer.Register(r => r.Add().WithFactory()); - ITestFactory testFactory = _iocContainer.Resolve(); - ITest createdTest = testFactory.Create(); + ITestFactory testFactory = _iocContainer.Resolve(); + ITest createdTest = testFactory.Create(); - Assert.IsInstanceOf(createdTest); - } + Assert.IsInstanceOf(createdTest); + } - [Test] - public void TestResolveFromFactoryWithParams() - { - _iocContainer.Register(r => r.Add().WithFactory()); - _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + [Test] + public void TestResolveFromFactoryWithParams() + { + _iocContainer.Register(r => r.Add().WithFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests - ITestFactory testFactory = _iocContainer.Resolve(); - ITest createdTest = testFactory.Create("Test"); + ITestFactory testFactory = _iocContainer.Resolve(); + ITest createdTest = testFactory.Create("Test"); - Assert.IsInstanceOf(createdTest); - } + Assert.IsInstanceOf(createdTest); + } - [Test] - public void TestResolveFromFactoryWithDefaultParamCreate() - { - _iocContainer.Register(r => r.Add().WithFactory()); - _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + [Test] + public void TestResolveFromFactoryWithDefaultParamCreate() + { + _iocContainer.Register(r => r.Add().WithFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests - ITestFactory testFactory = _iocContainer.Resolve(); - ITest createdTest = testFactory.CreateTest(); + ITestFactory testFactory = _iocContainer.Resolve(); + ITest createdTest = testFactory.CreateTest(); - Assert.IsInstanceOf(createdTest); - } + Assert.IsInstanceOf(createdTest); + } - [Test] - public void TestResolveFromFactoryWithDefaultParamCtor() - { - _iocContainer.Register(r => r.Add().WithFactory()); - _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + [Test] + public void TestResolveFromFactoryWithDefaultParamCtor() + { + _iocContainer.Register(r => r.Add().WithFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests - ITestFactory testFactory = _iocContainer.Resolve(); - ITest createdTest = testFactory.Create(); + ITestFactory testFactory = _iocContainer.Resolve(); + ITest createdTest = testFactory.Create(); - Assert.IsInstanceOf(createdTest); - } + Assert.IsInstanceOf(createdTest); + } - [Test] - public void TestResolveFromFactoryWithByte() - { - _iocContainer.Register(r => r.Add().WithFactory()); + [Test] + public void TestResolveFromFactoryWithByte() + { + _iocContainer.Register(r => r.Add().WithFactory()); - ITestFactory testFactory = _iocContainer.Resolve(); - ITest createdTest = testFactory.Create(1); + ITestFactory testFactory = _iocContainer.Resolve(); + ITest createdTest = testFactory.Create(1); - Assert.IsInstanceOf(createdTest); - } + Assert.IsInstanceOf(createdTest); + } - [Test] - public void TestResolveMultitonFromFactory() - { - _iocContainer.Register(r => r.AddMultiton().WithFactory()); + [Test] + public void TestResolveMultitonFromFactory() + { + _iocContainer.Register(r => r.AddMultiton().WithFactory()); - MultitonScope scope1 = new(); - MultitonScope scope2 = new(); + MultitonScope scope1 = new(); + MultitonScope scope2 = new(); - IMultitonTestFactory testFactory = _iocContainer.Resolve(); + IMultitonTestFactory testFactory = _iocContainer.Resolve(); - ITest resolvedTest1 = testFactory.Create(scope1); - ITest resolvedTest2 = testFactory.Create(scope1); - ITest resolvedTest3 = testFactory.Create(scope2); + ITest resolvedTest1 = testFactory.Create(scope1); + ITest resolvedTest2 = testFactory.Create(scope1); + ITest resolvedTest3 = testFactory.Create(scope2); - Assert.AreSame(resolvedTest1, resolvedTest2); - Assert.AreNotSame(resolvedTest1, resolvedTest3); - Assert.AreNotSame(resolvedTest2, resolvedTest3); - } + Assert.AreSame(resolvedTest1, resolvedTest2); + Assert.AreNotSame(resolvedTest1, resolvedTest3); + Assert.AreNotSame(resolvedTest2, resolvedTest3); + } - [Test] - public void TestResolveMultitonFromFactoryClearInstances() - { - _iocContainer.Register(r => r.AddMultiton().WithFactory()); + [Test] + public void TestResolveMultitonFromFactoryClearInstances() + { + _iocContainer.Register(r => r.AddMultiton().WithFactory()); - MultitonScope scope1 = new(); - MultitonScope scope2 = new(); + MultitonScope scope1 = new(); + MultitonScope scope2 = new(); - IMultitonTestFactory testFactory = _iocContainer.Resolve(); + IMultitonTestFactory testFactory = _iocContainer.Resolve(); - ITest resolvedTest1 = testFactory.Create(scope1); - ITest resolvedTest2 = testFactory.Create(scope1); - ITest resolvedTest3 = testFactory.Create(scope2); + ITest resolvedTest1 = testFactory.Create(scope1); + ITest resolvedTest2 = testFactory.Create(scope1); + ITest resolvedTest3 = testFactory.Create(scope2); - Assert.AreSame(resolvedTest1, resolvedTest2); - Assert.AreNotSame(resolvedTest1, resolvedTest3); - Assert.AreNotSame(resolvedTest2, resolvedTest3); + Assert.AreSame(resolvedTest1, resolvedTest2); + Assert.AreNotSame(resolvedTest1, resolvedTest3); + Assert.AreNotSame(resolvedTest2, resolvedTest3); - testFactory.ClearMultitonInstance(); + testFactory.ClearMultitonInstance(); - ITest resolvedTest4 = testFactory.Create(scope1); - ITest resolvedTest5 = testFactory.Create(scope2); + ITest resolvedTest4 = testFactory.Create(scope1); + ITest resolvedTest5 = testFactory.Create(scope2); - Assert.AreNotSame(resolvedTest1, resolvedTest4); - Assert.AreNotSame(resolvedTest2, resolvedTest4); - Assert.AreNotSame(resolvedTest3, resolvedTest5); - } + Assert.AreNotSame(resolvedTest1, resolvedTest4); + Assert.AreNotSame(resolvedTest2, resolvedTest4); + Assert.AreNotSame(resolvedTest3, resolvedTest5); + } - [Test] - public void InvalidMultitonFactoryRegistrationFactoryWithoutParameter() => - Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithFactory())); + [Test] + public void InvalidMultitonFactoryRegistrationFactoryWithoutParameter() => + Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithFactory())); - [Test] - public void InvalidMultitonFactoryRegistrationFactoryWithoutScopeAsFirstParameter() => - Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithFactory())); + [Test] + public void InvalidMultitonFactoryRegistrationFactoryWithoutScopeAsFirstParameter() => + Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithFactory())); - [Test] - public void TestInvalidCreateMethodReturnType() => - Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); - } + [Test] + public void TestInvalidCreateMethodReturnType() => + Assert.Throws(() => _iocContainer.Register(r => r.Add().WithFactory())); } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerInterfaceSegregationTest.cs b/Test.LightweightIocContainer/IocContainerInterfaceSegregationTest.cs index bc4e939..044c01e 100644 --- a/Test.LightweightIocContainer/IocContainerInterfaceSegregationTest.cs +++ b/Test.LightweightIocContainer/IocContainerInterfaceSegregationTest.cs @@ -7,158 +7,157 @@ using JetBrains.Annotations; using LightweightIocContainer; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class IocContainerInterfaceSegregationTest { - [TestFixture] - public class IocContainerInterfaceSegregationTest + private interface IBar { - private interface IBar - { - } - - private interface IFoo - { - void ThrowFoo(); - } - private interface IAnotherBar - { + } + + private interface IFoo + { + void ThrowFoo(); + } + private interface IAnotherBar + { - } + } - private interface IAnotherFoo - { + private interface IAnotherFoo + { - } + } - private interface IAnotherOne - { + private interface IAnotherOne + { - } + } - [UsedImplicitly] - private class Foo : IFoo, IBar, IAnotherFoo, IAnotherBar, IAnotherOne - { - public void ThrowFoo() => throw new Exception("Foo"); - } + [UsedImplicitly] + private class Foo : IFoo, IBar, IAnotherFoo, IAnotherBar, IAnotherOne + { + public void ThrowFoo() => throw new Exception("Foo"); + } - private IocContainer _container; + private IocContainer _container; - [SetUp] - public void SetUp() => _container = new IocContainer(); + [SetUp] + public void SetUp() => _container = new IocContainer(); - [TearDown] - public void TearDown() => _container.Dispose(); + [TearDown] + public void TearDown() => _container.Dispose(); - [Test] - public void TestRegistrationOnCreate2() - { - _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); + [Test] + public void TestRegistrationOnCreate2() + { + _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); - Exception fooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", fooException?.Message); + Exception fooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", fooException?.Message); - Exception barException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", barException?.Message); - } - - [Test] - public void TestRegistrationOnCreate3() - { - _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); - - Exception fooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", fooException?.Message); - - Exception barException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", barException?.Message); - - Exception anotherFooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherFooException?.Message); - } - - [Test] - public void TestRegistrationOnCreate4() - { - _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); - - Exception fooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", fooException?.Message); - - Exception barException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", barException?.Message); - - Exception anotherFooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherFooException?.Message); - - Exception anotherBarException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherBarException?.Message); - } - - [Test] - public void TestRegistrationOnCreate5() - { - _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); - - Exception fooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", fooException?.Message); - - Exception barException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", barException?.Message); - - Exception anotherFooException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherFooException?.Message); - - Exception anotherBarException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherBarException?.Message); - - Exception anotherOneException = Assert.Throws(() => _container.Resolve()); - Assert.AreEqual("Foo", anotherOneException?.Message); - } - - [Test] - public void TestResolveTransient() - { - _container.Register(r => r.Add()); - IFoo foo = _container.Resolve(); - IBar bar = _container.Resolve(); - IAnotherFoo anotherFoo = _container.Resolve(); - IAnotherBar anotherBar = _container.Resolve(); - IAnotherOne anotherOne = _container.Resolve(); - - Assert.IsInstanceOf(foo); - Assert.IsInstanceOf(bar); - Assert.IsInstanceOf(anotherFoo); - Assert.IsInstanceOf(anotherBar); - Assert.IsInstanceOf(anotherOne); - } - - [Test] - public void TestResolveSingleton() - { - _container.Register(r => r.Add(Lifestyle.Singleton)); - IFoo foo = _container.Resolve(); - IBar bar = _container.Resolve(); - IAnotherFoo anotherFoo = _container.Resolve(); - IAnotherBar anotherBar = _container.Resolve(); - IAnotherOne anotherOne = _container.Resolve(); - - Assert.IsInstanceOf(foo); - Assert.IsInstanceOf(bar); - Assert.IsInstanceOf(anotherFoo); - Assert.IsInstanceOf(anotherBar); - Assert.IsInstanceOf(anotherOne); + Exception barException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", barException?.Message); + } + + [Test] + public void TestRegistrationOnCreate3() + { + _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); + + Exception fooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", fooException?.Message); + + Exception barException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", barException?.Message); + + Exception anotherFooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherFooException?.Message); + } + + [Test] + public void TestRegistrationOnCreate4() + { + _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); + + Exception fooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", fooException?.Message); + + Exception barException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", barException?.Message); + + Exception anotherFooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherFooException?.Message); + + Exception anotherBarException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherBarException?.Message); + } + + [Test] + public void TestRegistrationOnCreate5() + { + _container.Register(r => r.Add().OnCreate(foo => foo.ThrowFoo())); + + Exception fooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", fooException?.Message); + + Exception barException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", barException?.Message); + + Exception anotherFooException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherFooException?.Message); + + Exception anotherBarException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherBarException?.Message); + + Exception anotherOneException = Assert.Throws(() => _container.Resolve()); + Assert.AreEqual("Foo", anotherOneException?.Message); + } + + [Test] + public void TestResolveTransient() + { + _container.Register(r => r.Add()); + IFoo foo = _container.Resolve(); + IBar bar = _container.Resolve(); + IAnotherFoo anotherFoo = _container.Resolve(); + IAnotherBar anotherBar = _container.Resolve(); + IAnotherOne anotherOne = _container.Resolve(); + + Assert.IsInstanceOf(foo); + Assert.IsInstanceOf(bar); + Assert.IsInstanceOf(anotherFoo); + Assert.IsInstanceOf(anotherBar); + Assert.IsInstanceOf(anotherOne); + } + + [Test] + public void TestResolveSingleton() + { + _container.Register(r => r.Add(Lifestyle.Singleton)); + IFoo foo = _container.Resolve(); + IBar bar = _container.Resolve(); + IAnotherFoo anotherFoo = _container.Resolve(); + IAnotherBar anotherBar = _container.Resolve(); + IAnotherOne anotherOne = _container.Resolve(); + + Assert.IsInstanceOf(foo); + Assert.IsInstanceOf(bar); + Assert.IsInstanceOf(anotherFoo); + Assert.IsInstanceOf(anotherBar); + Assert.IsInstanceOf(anotherOne); - Assert.AreEqual(foo, bar); - Assert.AreEqual(foo, anotherFoo); - Assert.AreEqual(foo, anotherBar); - Assert.AreEqual(foo, anotherOne); - - Assert.AreSame(foo, bar); - Assert.AreSame(foo, anotherFoo); - Assert.AreSame(foo, anotherBar); - Assert.AreSame(foo, anotherOne); - } + Assert.AreEqual(foo, bar); + Assert.AreEqual(foo, anotherFoo); + Assert.AreEqual(foo, anotherBar); + Assert.AreEqual(foo, anotherOne); + + Assert.AreSame(foo, bar); + Assert.AreSame(foo, anotherFoo); + Assert.AreSame(foo, anotherBar); + Assert.AreSame(foo, anotherOne); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs b/Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs index 481964f..4f965a3 100644 --- a/Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs +++ b/Test.LightweightIocContainer/IocContainerParameterRegistrationTest.cs @@ -6,154 +6,153 @@ using JetBrains.Annotations; using LightweightIocContainer; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +// ReSharper disable MemberHidesStaticFromOuterClass +public class IocContainerParameterRegistrationTest { - [TestFixture] - // ReSharper disable MemberHidesStaticFromOuterClass - public class IocContainerParameterRegistrationTest + [UsedImplicitly] + public interface IA { - [UsedImplicitly] - public interface IA - { - IB B { get; } - IC C { get; } - } + IB B { get; } + IC C { get; } + } - [UsedImplicitly] - public interface IB - { + [UsedImplicitly] + public interface IB + { - } + } - [UsedImplicitly] - public interface IC - { + [UsedImplicitly] + public interface IC + { - } + } - [UsedImplicitly] - public interface ID - { - IA A { get; } - IA A2 { get; } - IB B { get; } - IC C { get; } - } + [UsedImplicitly] + public interface ID + { + IA A { get; } + IA A2 { get; } + IB B { get; } + IC C { get; } + } - [UsedImplicitly] - private class A : IA + [UsedImplicitly] + private class A : IA + { + public A(IB b, IC c) { - public A(IB b, IC c) - { - B = b; - C = c; - } - - public IB B { get; } - public IC C { get; } + B = b; + C = c; } - [UsedImplicitly] - private class B : IB + public IB B { get; } + public IC C { get; } + } + + [UsedImplicitly] + private class B : IB + { + public B(IC c) { - public B(IC c) - { - } } + } - [UsedImplicitly] - private class C : IC - { + [UsedImplicitly] + private class C : IC + { - } + } - [UsedImplicitly] - private class D : ID + [UsedImplicitly] + private class D : ID + { + public D(IA a, IA a2, IB b, IC c) { - public D(IA a, IA a2, IB b, IC c) - { - A = a; - A2 = a2; - B = b; - C = c; - } - - public IA A { get; } - public IA A2 { get; } - public IB B { get; } - public IC C { get; } + A = a; + A2 = a2; + B = b; + C = c; } + public IA A { get; } + public IA A2 { get; } + public IB B { get; } + public IC C { get; } + } + - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestResolveOnlyRegistrationParameters() - { - IC c = new C(); - IB b = new B(c); + [Test] + public void TestResolveOnlyRegistrationParameters() + { + IC c = new C(); + IB b = new B(c); - _iocContainer.Register(r => r.Add().WithParameters(b, c)); - IA a = _iocContainer.Resolve(); + _iocContainer.Register(r => r.Add().WithParameters(b, c)); + IA a = _iocContainer.Resolve(); - Assert.AreEqual(b, a.B); - Assert.AreEqual(c, a.C); - } + Assert.AreEqual(b, a.B); + Assert.AreEqual(c, a.C); + } - [Test] - public void TestResolveRegistrationAndResolveParameters() - { - IC c = new C(); - IB b = new B(c); + [Test] + public void TestResolveRegistrationAndResolveParameters() + { + IC c = new C(); + IB b = new B(c); - _iocContainer.Register(r => r.Add().WithParameters(b)); - IA a = _iocContainer.Resolve(c); + _iocContainer.Register(r => r.Add().WithParameters(b)); + IA a = _iocContainer.Resolve(c); - Assert.AreEqual(b, a.B); - Assert.AreEqual(c, a.C); - } + Assert.AreEqual(b, a.B); + Assert.AreEqual(c, a.C); + } - [Test] - public void TestResolveRegistrationAndResolveParametersMixedOrder() - { - IC c = new C(); - IB b = new B(c); - IA a = new A(b, c); - IA a2 = new A(b, c); - - _iocContainer.Register(r => r.Add().WithParameters((0, a), (2, b), (3, c))); - ID d = _iocContainer.Resolve(a2); - - Assert.AreEqual(a, d.A); - Assert.AreEqual(a2, d.A2); - Assert.AreEqual(b, d.B); - Assert.AreEqual(c, d.C); - } + [Test] + public void TestResolveRegistrationAndResolveParametersMixedOrder() + { + IC c = new C(); + IB b = new B(c); + IA a = new A(b, c); + IA a2 = new A(b, c); + + _iocContainer.Register(r => r.Add().WithParameters((0, a), (2, b), (3, c))); + ID d = _iocContainer.Resolve(a2); + + Assert.AreEqual(a, d.A); + Assert.AreEqual(a2, d.A2); + Assert.AreEqual(b, d.B); + Assert.AreEqual(c, d.C); + } - [Test] - public void TestResolveRegistrationParametersAndResolvedParameters() - { - IC c = new C(); - IB b = new B(c); - IA a = new A(b, c); - IA a2 = new A(b, c); + [Test] + public void TestResolveRegistrationParametersAndResolvedParameters() + { + IC c = new C(); + IB b = new B(c); + IA a = new A(b, c); + IA a2 = new A(b, c); - _iocContainer.Register(r => r.Add().WithParameters(a2)); - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add().WithParameters(a2)); + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); - ID d = _iocContainer.Resolve(a); + ID d = _iocContainer.Resolve(a); - Assert.AreEqual(a, d.A2); - Assert.AreEqual(a2, d.A); - } + Assert.AreEqual(a, d.A2); + Assert.AreEqual(a2, d.A); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerRecursionTest.cs b/Test.LightweightIocContainer/IocContainerRecursionTest.cs index 2c0d960..38a8d0e 100644 --- a/Test.LightweightIocContainer/IocContainerRecursionTest.cs +++ b/Test.LightweightIocContainer/IocContainerRecursionTest.cs @@ -9,158 +9,157 @@ using LightweightIocContainer.Exceptions; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class IocContainerRecursionTest { - [TestFixture] - public class IocContainerRecursionTest + [UsedImplicitly] + public interface IFoo { - [UsedImplicitly] - public interface IFoo - { - } + } - [UsedImplicitly] - public interface IBar - { + [UsedImplicitly] + public interface IBar + { - } + } - [UsedImplicitly] - private class Foo : IFoo + [UsedImplicitly] + private class Foo : IFoo + { + public Foo(IBar bar) { - public Foo(IBar bar) - { - } } + } - [UsedImplicitly] - private class Bar : IBar + [UsedImplicitly] + private class Bar : IBar + { + public Bar(IFoo foo) { - public Bar(IFoo foo) - { - } } + } - [UsedImplicitly] - public interface IA - { + [UsedImplicitly] + public interface IA + { - } + } - [UsedImplicitly] - public interface IB - { + [UsedImplicitly] + public interface IB + { - } + } - [UsedImplicitly] - public interface IC - { + [UsedImplicitly] + public interface IC + { - } + } - [UsedImplicitly] - private class A : IA + [UsedImplicitly] + private class A : IA + { + public A(IB b, IC c) { - public A(IB b, IC c) - { - } } + } - [UsedImplicitly] - private class B : IB + [UsedImplicitly] + private class B : IB + { + public B(IC c) { - public B(IC c) - { - } } + } - [UsedImplicitly] - private class C : IC - { + [UsedImplicitly] + private class C : IC + { - } + } - [UsedImplicitly] - private class ATwoCtor : IA - { - public ATwoCtor(IB b) => Console.WriteLine("A with args"); - public ATwoCtor() => Console.WriteLine("A without args"); - } + [UsedImplicitly] + private class ATwoCtor : IA + { + public ATwoCtor(IB b) => Console.WriteLine("A with args"); + public ATwoCtor() => Console.WriteLine("A without args"); + } - [UsedImplicitly] - private class BTwoCtor : IB - { - public BTwoCtor(IA a) => Console.WriteLine("B with args"); - public BTwoCtor() => Console.WriteLine("B without args"); - } + [UsedImplicitly] + private class BTwoCtor : IB + { + public BTwoCtor(IA a) => Console.WriteLine("B with args"); + public BTwoCtor() => Console.WriteLine("B without args"); + } - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestCircularDependencies() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); + [Test] + public void TestCircularDependencies() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); - NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws(() => _iocContainer.Resolve()); - ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.InnerExceptions[0]; - NoMatchingConstructorFoundException noMatchingBarConstructorFoundException = (NoMatchingConstructorFoundException) fooConstructorNotMatchingException?.InnerExceptions[0]; - ConstructorNotMatchingException barConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingBarConstructorFoundException?.InnerExceptions[0]; + NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws(() => _iocContainer.Resolve()); + ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.InnerExceptions[0]; + NoMatchingConstructorFoundException noMatchingBarConstructorFoundException = (NoMatchingConstructorFoundException) fooConstructorNotMatchingException?.InnerExceptions[0]; + ConstructorNotMatchingException barConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingBarConstructorFoundException?.InnerExceptions[0]; - CircularDependencyException exception = (CircularDependencyException) barConstructorNotMatchingException?.InnerExceptions[0]; + CircularDependencyException exception = (CircularDependencyException) barConstructorNotMatchingException?.InnerExceptions[0]; - Assert.AreEqual(typeof(IFoo), exception?.ResolvingType); - Assert.AreEqual(2, exception.ResolveStack.Count); + Assert.AreEqual(typeof(IFoo), exception?.ResolvingType); + Assert.AreEqual(2, exception.ResolveStack.Count); - string message = $"Circular dependency has been detected when trying to resolve `{typeof(IFoo)}`.\n" + - "Resolve stack that resulted in the circular dependency:\n" + - $"\t`{typeof(IFoo)}` resolved as dependency of\n" + - $"\t`{typeof(IBar)}` resolved as dependency of\n" + - $"\t`{typeof(IFoo)}` which is the root type being resolved."; + string message = $"Circular dependency has been detected when trying to resolve `{typeof(IFoo)}`.\n" + + "Resolve stack that resulted in the circular dependency:\n" + + $"\t`{typeof(IFoo)}` resolved as dependency of\n" + + $"\t`{typeof(IBar)}` resolved as dependency of\n" + + $"\t`{typeof(IFoo)}` which is the root type being resolved."; - Assert.AreEqual(message, exception.Message); - } + Assert.AreEqual(message, exception.Message); + } - [Test] - public void TestNonCircularDependencies() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); + [Test] + public void TestNonCircularDependencies() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); - IA a = _iocContainer.Resolve(); - Assert.IsNotNull(a); - } + IA a = _iocContainer.Resolve(); + Assert.IsNotNull(a); + } - [Test] - public void TestRecursionWithParam() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); + [Test] + public void TestRecursionWithParam() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); - Assert.DoesNotThrow(() => _iocContainer.Resolve(new Mock().Object)); - Assert.DoesNotThrow(() => _iocContainer.Resolve(new Mock().Object)); - } + Assert.DoesNotThrow(() => _iocContainer.Resolve(new Mock().Object)); + Assert.DoesNotThrow(() => _iocContainer.Resolve(new Mock().Object)); + } - [Test] - public void TestNonCircularCrossDependencies() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); + [Test] + public void TestNonCircularCrossDependencies() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); - Assert.DoesNotThrow(() => _iocContainer.Resolve()); - Assert.DoesNotThrow(() => _iocContainer.Resolve()); - } + Assert.DoesNotThrow(() => _iocContainer.Resolve()); + Assert.DoesNotThrow(() => _iocContainer.Resolve()); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerTest.cs b/Test.LightweightIocContainer/IocContainerTest.cs index b323f3d..6ed266a 100644 --- a/Test.LightweightIocContainer/IocContainerTest.cs +++ b/Test.LightweightIocContainer/IocContainerTest.cs @@ -7,356 +7,355 @@ using LightweightIocContainer.Interfaces.Registrations; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class IocContainerTest { - [TestFixture] - public class IocContainerTest + private interface ITest { - private interface ITest - { - } + } - private interface IFoo - { + private interface IFoo + { - } + } - private class Test : ITest - { + private class Test : ITest + { - } + } - [UsedImplicitly] - private class TestConstructor : ITest + [UsedImplicitly] + private class TestConstructor : ITest + { + public TestConstructor(string name, Test test) { - public TestConstructor(string name, Test test) - { - - } - - public TestConstructor(Test test, string name = null) - { - - } - - public TestConstructor(IFoo foo, string name) - { - } } - [UsedImplicitly] - private class TestPrivateConstructor : ITest + public TestConstructor(Test test, string name = null) { - private TestPrivateConstructor() - { - } } - [UsedImplicitly] - private class TestMultipleConstructors : ITest + public TestConstructor(IFoo foo, string name) { - public TestMultipleConstructors(string name, bool success) - { - } + } + } - public TestMultipleConstructors(string name) - { + [UsedImplicitly] + private class TestPrivateConstructor : ITest + { + private TestPrivateConstructor() + { - } } + } - [UsedImplicitly] - private class TestWithFoo : ITest + [UsedImplicitly] + private class TestMultipleConstructors : ITest + { + public TestMultipleConstructors(string name, bool success) { - public TestWithFoo(IFoo testFoo) => TestFoo = testFoo; - public IFoo TestFoo { get; } + } - [UsedImplicitly] - private class Foo : IFoo + public TestMultipleConstructors(string name) { } + } - [UsedImplicitly] - private class FooConstructor : IFoo + [UsedImplicitly] + private class TestWithFoo : ITest + { + public TestWithFoo(IFoo testFoo) => TestFoo = testFoo; + public IFoo TestFoo { get; } + } + + [UsedImplicitly] + private class Foo : IFoo + { + + } + + [UsedImplicitly] + private class FooConstructor : IFoo + { + public FooConstructor(string test) { - public FooConstructor(string test) - { - } } + } - private class MultitonScope - { + private class MultitonScope + { - } + } - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestInstall() - { - Mock installerMock = new(); - IIocContainer returnedContainer = _iocContainer.Install(installerMock.Object); + [Test] + public void TestInstall() + { + Mock installerMock = new(); + IIocContainer returnedContainer = _iocContainer.Install(installerMock.Object); - installerMock.Verify(m => m.Install(It.IsAny()), Times.Once); + installerMock.Verify(m => m.Install(It.IsAny()), Times.Once); - Assert.AreEqual(_iocContainer, returnedContainer); - } + Assert.AreEqual(_iocContainer, returnedContainer); + } - [Test] - public void TestInstallMultiple() - { - Mock installer1Mock = new(); - Mock installer2Mock = new(); - Mock installer3Mock = new(); + [Test] + public void TestInstallMultiple() + { + Mock installer1Mock = new(); + Mock installer2Mock = new(); + Mock installer3Mock = new(); - IIocContainer returnedContainer = _iocContainer.Install(installer1Mock.Object, installer2Mock.Object, installer3Mock.Object); + IIocContainer returnedContainer = _iocContainer.Install(installer1Mock.Object, installer2Mock.Object, installer3Mock.Object); - installer1Mock.Verify(m => m.Install(It.IsAny()), Times.Once); - installer2Mock.Verify(m => m.Install(It.IsAny()), Times.Once); - installer3Mock.Verify(m => m.Install(It.IsAny()), Times.Once); + installer1Mock.Verify(m => m.Install(It.IsAny()), Times.Once); + installer2Mock.Verify(m => m.Install(It.IsAny()), Times.Once); + installer3Mock.Verify(m => m.Install(It.IsAny()), Times.Once); - Assert.AreEqual(_iocContainer, returnedContainer); - } + Assert.AreEqual(_iocContainer, returnedContainer); + } - [Test] - public void TestRegister() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); + [Test] + public void TestRegister() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); - [Test] - public void TestRegisterTypeWithoutInterface() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); + [Test] + public void TestRegisterTypeWithoutInterface() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); - [Test] - public void TestRegisterMultiton() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.AddMultiton())); + [Test] + public void TestRegisterMultiton() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.AddMultiton())); - [Test] - public void TestInvalidMultitonRegistration() => Assert.Throws(() => _iocContainer.Register(r => r.Add(Lifestyle.Multiton))); + [Test] + public void TestInvalidMultitonRegistration() => Assert.Throws(() => _iocContainer.Register(r => r.Add(Lifestyle.Multiton))); - [Test] - public void TestRegisterMultipleDifferent() - { - _iocContainer.Register(r => r.Add()); - MultipleRegistrationException exception = Assert.Throws(() => _iocContainer.Register(r => r.Add())); - Assert.AreEqual(typeof(ITest), exception?.Type); - } + [Test] + public void TestRegisterMultipleDifferent() + { + _iocContainer.Register(r => r.Add()); + MultipleRegistrationException exception = Assert.Throws(() => _iocContainer.Register(r => r.Add())); + Assert.AreEqual(typeof(ITest), exception?.Type); + } - [Test] - public void TestRegisterMultipleSame() - { - _iocContainer.Register(r => r.Add()); - Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); - } + [Test] + public void TestRegisterMultipleSame() + { + _iocContainer.Register(r => r.Add()); + Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add())); + } - [Test] - public void TestRegisterMultipleSameWithParameters() - { - _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo())); - Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo()))); - } + [Test] + public void TestRegisterMultipleSameWithParameters() + { + _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo())); + Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add().WithParameters("test", 1, new Foo()))); + } - [Test] - public void TestResolveNotRegistered() - { - TypeNotRegisteredException exception = Assert.Throws(() => _iocContainer.Resolve()); - Assert.AreEqual(typeof(ITest), exception?.Type); - } + [Test] + public void TestResolveNotRegistered() + { + TypeNotRegisteredException exception = Assert.Throws(() => _iocContainer.Resolve()); + Assert.AreEqual(typeof(ITest), exception?.Type); + } - [Test] - public void TestResolve() - { - _iocContainer.Register(r => r.Add()); + [Test] + public void TestResolve() + { + _iocContainer.Register(r => r.Add()); - ITest resolvedTest = _iocContainer.Resolve(); + ITest resolvedTest = _iocContainer.Resolve(); - Assert.IsInstanceOf(resolvedTest); - } + Assert.IsInstanceOf(resolvedTest); + } - [Test] - public void TestResolveWithoutInterface() - { - _iocContainer.Register(r => r.Add()); + [Test] + public void TestResolveWithoutInterface() + { + _iocContainer.Register(r => r.Add()); - Test resolvedTest = _iocContainer.Resolve(); + Test resolvedTest = _iocContainer.Resolve(); - Assert.IsInstanceOf(resolvedTest); - } + Assert.IsInstanceOf(resolvedTest); + } - [Test] - public void TestResolveInterfaceWithoutImplementation() - { - _iocContainer.Register(r => r.Add()); - Assert.Throws(() => _iocContainer.Resolve()); - } + [Test] + public void TestResolveInterfaceWithoutImplementation() + { + _iocContainer.Register(r => r.Add()); + Assert.Throws(() => _iocContainer.Resolve()); + } - [Test] - public void TestResolveImplementationRegisteredWithInterface() - { - _iocContainer.Register(r => r.Add()); + [Test] + public void TestResolveImplementationRegisteredWithInterface() + { + _iocContainer.Register(r => r.Add()); - Test resolvedTest = _iocContainer.Resolve(); + Test resolvedTest = _iocContainer.Resolve(); - Assert.IsInstanceOf(resolvedTest); - } + Assert.IsInstanceOf(resolvedTest); + } - [Test] - public void TestResolveWithParams() - { - _iocContainer.Register(r => r.Add()); + [Test] + public void TestResolveWithParams() + { + _iocContainer.Register(r => r.Add()); - ITest resolvedTest = _iocContainer.Resolve("Test", new Test()); + ITest resolvedTest = _iocContainer.Resolve("Test", new Test()); - Assert.IsInstanceOf(resolvedTest); - } + Assert.IsInstanceOf(resolvedTest); + } - [Test] - public void TestResolveWithMissingParam() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + [Test] + public void TestResolveWithMissingParam() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests - ITest resolvedTest = _iocContainer.Resolve("Test"); + ITest resolvedTest = _iocContainer.Resolve("Test"); - Assert.IsInstanceOf(resolvedTest); - } + Assert.IsInstanceOf(resolvedTest); + } - [Test] - public void TestResolveSingleton() - { - _iocContainer.Register(r => r.Add(Lifestyle.Singleton)); + [Test] + public void TestResolveSingleton() + { + _iocContainer.Register(r => r.Add(Lifestyle.Singleton)); - ITest resolvedTest = _iocContainer.Resolve(); - ITest secondResolvedTest = _iocContainer.Resolve(); + ITest resolvedTest = _iocContainer.Resolve(); + ITest secondResolvedTest = _iocContainer.Resolve(); - Assert.AreEqual(resolvedTest, secondResolvedTest); - } + Assert.AreEqual(resolvedTest, secondResolvedTest); + } - [Test] - public void TestResolveMultiton() - { - _iocContainer.Register(r => r.AddMultiton()); + [Test] + public void TestResolveMultiton() + { + _iocContainer.Register(r => r.AddMultiton()); - MultitonScope scope1 = new(); - MultitonScope scope2 = new(); + MultitonScope scope1 = new(); + MultitonScope scope2 = new(); - ITest resolvedTest1 = _iocContainer.Resolve(scope1); - ITest resolvedTest2 = _iocContainer.Resolve(scope1); - ITest resolvedTest3 = _iocContainer.Resolve(scope2); + ITest resolvedTest1 = _iocContainer.Resolve(scope1); + ITest resolvedTest2 = _iocContainer.Resolve(scope1); + ITest resolvedTest3 = _iocContainer.Resolve(scope2); - Assert.AreSame(resolvedTest1, resolvedTest2); - Assert.AreNotSame(resolvedTest1, resolvedTest3); - Assert.AreNotSame(resolvedTest2, resolvedTest3); - } + Assert.AreSame(resolvedTest1, resolvedTest2); + Assert.AreNotSame(resolvedTest1, resolvedTest3); + Assert.AreNotSame(resolvedTest2, resolvedTest3); + } - [Test] - public void TestResolveMultitonNoArgs() - { - _iocContainer.Register(r => r.AddMultiton()); + [Test] + public void TestResolveMultitonNoArgs() + { + _iocContainer.Register(r => r.AddMultiton()); - MultitonResolveException exception = Assert.Throws(() => _iocContainer.Resolve()); - Assert.AreEqual(typeof(ITest), exception?.Type); - } + MultitonResolveException exception = Assert.Throws(() => _iocContainer.Resolve()); + Assert.AreEqual(typeof(ITest), exception?.Type); + } - [Test] - public void TestResolveMultitonWrongArgs() - { - _iocContainer.Register(r => r.AddMultiton()); + [Test] + public void TestResolveMultitonWrongArgs() + { + _iocContainer.Register(r => r.AddMultiton()); - MultitonResolveException exception = Assert.Throws(() => _iocContainer.Resolve(new object())); - Assert.AreEqual(typeof(ITest), exception?.Type); - } + MultitonResolveException exception = Assert.Throws(() => _iocContainer.Resolve(new object())); + Assert.AreEqual(typeof(ITest), exception?.Type); + } - [Test] - public void TestResolveTransient() - { - _iocContainer.Register(r => r.Add()); + [Test] + public void TestResolveTransient() + { + _iocContainer.Register(r => r.Add()); - ITest resolvedTest = _iocContainer.Resolve(); - ITest secondResolvedTest = _iocContainer.Resolve(); + ITest resolvedTest = _iocContainer.Resolve(); + ITest secondResolvedTest = _iocContainer.Resolve(); - Assert.AreNotEqual(resolvedTest, secondResolvedTest); - } + Assert.AreNotEqual(resolvedTest, secondResolvedTest); + } - [Test] - public void TestResolveNoMatchingConstructor() - { - _iocContainer.Register(r => r.Add()); - NoMatchingConstructorFoundException exception = Assert.Throws(() => _iocContainer.Resolve()); - Assert.AreEqual(typeof(TestConstructor), exception?.Type); - } + [Test] + public void TestResolveNoMatchingConstructor() + { + _iocContainer.Register(r => r.Add()); + NoMatchingConstructorFoundException exception = Assert.Throws(() => _iocContainer.Resolve()); + Assert.AreEqual(typeof(TestConstructor), exception?.Type); + } - [Test] - public void TestResolveNoMatchingConstructorNotThrownWrongly() - { - _iocContainer.Register(r => r.Add()); - Assert.DoesNotThrow(() => _iocContainer.Resolve("Name")); - } + [Test] + public void TestResolveNoMatchingConstructorNotThrownWrongly() + { + _iocContainer.Register(r => r.Add()); + Assert.DoesNotThrow(() => _iocContainer.Resolve("Name")); + } - [Test] - public void TestResolvePrivateConstructor() - { - _iocContainer.Register(r => r.Add()); - NoPublicConstructorFoundException exception = Assert.Throws(() => _iocContainer.Resolve()); - Assert.AreEqual(typeof(TestPrivateConstructor), exception?.Type); - } + [Test] + public void TestResolvePrivateConstructor() + { + _iocContainer.Register(r => r.Add()); + NoPublicConstructorFoundException exception = Assert.Throws(() => _iocContainer.Resolve()); + Assert.AreEqual(typeof(TestPrivateConstructor), exception?.Type); + } - [Test] - public void TestResolveSingleTypeRegistrationWithFactoryMethod() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add().WithFactoryMethod(c => new TestConstructor(c.Resolve(), "someName"))); + [Test] + public void TestResolveSingleTypeRegistrationWithFactoryMethod() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add().WithFactoryMethod(c => new TestConstructor(c.Resolve(), "someName"))); - ITest test = _iocContainer.Resolve(); + ITest test = _iocContainer.Resolve(); - Assert.NotNull(test); - } + Assert.NotNull(test); + } - [Test] - public void TestResolveParameterIsRegisteredWithParameters() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add().WithParameters("TestString")); + [Test] + public void TestResolveParameterIsRegisteredWithParameters() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add().WithParameters("TestString")); - ITest test = _iocContainer.Resolve("testName"); + ITest test = _iocContainer.Resolve("testName"); - Assert.IsInstanceOf(test); - } + Assert.IsInstanceOf(test); + } - [Test] - public void TestResolveParameterWithParameterThatIsAlreadyExistingSingleton() - { - _iocContainer.Register(r => r.Add()); - _iocContainer.Register(r => r.Add(Lifestyle.Singleton).WithParameters("TestString")); + [Test] + public void TestResolveParameterWithParameterThatIsAlreadyExistingSingleton() + { + _iocContainer.Register(r => r.Add()); + _iocContainer.Register(r => r.Add(Lifestyle.Singleton).WithParameters("TestString")); - IFoo foo = _iocContainer.Resolve(); - ITest test = _iocContainer.Resolve("testName"); + IFoo foo = _iocContainer.Resolve(); + ITest test = _iocContainer.Resolve("testName"); - Assert.IsInstanceOf(test); - Assert.AreSame(foo, ((TestWithFoo) test).TestFoo); - } + Assert.IsInstanceOf(test); + Assert.AreSame(foo, ((TestWithFoo) test).TestFoo); + } - [Test] - public void TestIsTypeRegistered() - { - Assert.False(_iocContainer.IsTypeRegistered()); + [Test] + public void TestIsTypeRegistered() + { + Assert.False(_iocContainer.IsTypeRegistered()); - _iocContainer.Register(r => r.Add()); - Assert.True(_iocContainer.IsTypeRegistered()); + _iocContainer.Register(r => r.Add()); + Assert.True(_iocContainer.IsTypeRegistered()); - _iocContainer.Register(r => r.Add()); - Assert.True(_iocContainer.IsTypeRegistered()); - } + _iocContainer.Register(r => r.Add()); + Assert.True(_iocContainer.IsTypeRegistered()); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocValidatorTest.cs b/Test.LightweightIocContainer/IocValidatorTest.cs index d968a21..3dab9f5 100644 --- a/Test.LightweightIocContainer/IocValidatorTest.cs +++ b/Test.LightweightIocContainer/IocValidatorTest.cs @@ -12,177 +12,176 @@ using LightweightIocContainer.Validation; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class IocValidatorTest { - [TestFixture] - public class IocValidatorTest + public interface ITest { - public interface ITest - { - } + } - public interface ITest2 - { + public interface ITest2 + { - } + } - [UsedImplicitly] - public interface IParameter - { - bool Method(); - } + [UsedImplicitly] + public interface IParameter + { + bool Method(); + } - private class Test : ITest - { - public Test(IParameter parameter) => parameter.Method(); - } + private class Test : ITest + { + public Test(IParameter parameter) => parameter.Method(); + } - [UsedImplicitly] - public interface ITestFactory - { - ITest Create(IParameter parameter); - } + [UsedImplicitly] + public interface ITestFactory + { + ITest Create(IParameter parameter); + } - [UsedImplicitly] - public interface ITest2Factory - { - ITest2 InvalidCreate(); - ITest2 Create(ITest test); - } + [UsedImplicitly] + public interface ITest2Factory + { + ITest2 InvalidCreate(); + ITest2 Create(ITest test); + } - private class Test2 : ITest2 + private class Test2 : ITest2 + { + public Test2(ITest parameter) { - public Test2(ITest parameter) - { - } } + } - [UsedImplicitly] - public interface IInvalidFactory - { - ITest Create(); - } + [UsedImplicitly] + public interface IInvalidFactory + { + ITest Create(); + } - private class TestInstallerNoFactory : IIocInstaller - { - public void Install(IRegistrationCollector registration) => registration.Add(); - } + private class TestInstallerNoFactory : IIocInstaller + { + public void Install(IRegistrationCollector registration) => registration.Add(); + } - private class TestInstallerWithFactory : IIocInstaller - { - public void Install(IRegistrationCollector registration) => registration.Add().WithFactory(); - } + private class TestInstallerWithFactory : IIocInstaller + { + public void Install(IRegistrationCollector registration) => registration.Add().WithFactory(); + } - private class TestInstallerWithInvalidFactory : IIocInstaller - { - public void Install(IRegistrationCollector registration) => registration.Add().WithFactory(); - } + private class TestInstallerWithInvalidFactory : IIocInstaller + { + public void Install(IRegistrationCollector registration) => registration.Add().WithFactory(); + } - private class InvalidTestClassInstaller : IIocInstaller + private class InvalidTestClassInstaller : IIocInstaller + { + public void Install(IRegistrationCollector registration) { - public void Install(IRegistrationCollector registration) - { - registration.Add().WithFactory(); - registration.Add().WithFactory(); - } + registration.Add().WithFactory(); + registration.Add().WithFactory(); } + } - [Test] - public void TestValidateWithoutFactory() - { - IocContainer iocContainer = new(); - iocContainer.Install(new TestInstallerNoFactory()); + [Test] + public void TestValidateWithoutFactory() + { + IocContainer iocContainer = new(); + iocContainer.Install(new TestInstallerNoFactory()); - IocValidator validator = new(iocContainer); + IocValidator validator = new(iocContainer); - AggregateException aggregateException = Assert.Throws(() => validator.Validate()); + AggregateException aggregateException = Assert.Throws(() => validator.Validate()); - AssertNoMatchingConstructorFoundForType(aggregateException); - } + AssertNoMatchingConstructorFoundForType(aggregateException); + } - [Test] - public void TestValidateWithFactory() - { - IocContainer iocContainer = new(); - iocContainer.Install(new TestInstallerWithFactory()); + [Test] + public void TestValidateWithFactory() + { + IocContainer iocContainer = new(); + iocContainer.Install(new TestInstallerWithFactory()); - IocValidator validator = new(iocContainer); + IocValidator validator = new(iocContainer); - validator.Validate(); - } + validator.Validate(); + } - [Test] - public void TestValidateWithParameter() - { - IocContainer iocContainer = new(); - iocContainer.Install(new TestInstallerNoFactory()); + [Test] + public void TestValidateWithParameter() + { + IocContainer iocContainer = new(); + iocContainer.Install(new TestInstallerNoFactory()); - IocValidator validator = new(iocContainer); + IocValidator validator = new(iocContainer); - Mock parameterMock = new(); - parameterMock.Setup(p => p.Method()).Returns(true); + Mock parameterMock = new(); + parameterMock.Setup(p => p.Method()).Returns(true); - validator.AddParameter(parameterMock.Object); + validator.AddParameter(parameterMock.Object); - validator.Validate(); + validator.Validate(); - parameterMock.Verify(p => p.Method(), Times.Never); - } + parameterMock.Verify(p => p.Method(), Times.Never); + } - [Test] - public void TestValidateWithInvalidParameterWithFactory() - { - IocContainer iocContainer = new(); - iocContainer.Install(new InvalidTestClassInstaller()); + [Test] + public void TestValidateWithInvalidParameterWithFactory() + { + IocContainer iocContainer = new(); + iocContainer.Install(new InvalidTestClassInstaller()); - IocValidator validator = new(iocContainer); + IocValidator validator = new(iocContainer); - Mock parameterMock = new(); - validator.AddParameter(parameterMock.Object); + Mock parameterMock = new(); + validator.AddParameter(parameterMock.Object); - AggregateException aggregateException = Assert.Throws(() => validator.Validate()); + AggregateException aggregateException = Assert.Throws(() => validator.Validate()); - if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException) - { - Assert.Fail(); - return; - } - - if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException) - { - Assert.Fail(); - return; - } - - Assert.IsInstanceOf(iTest2CtorNotMatchingException.InnerExceptions[0]); + if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException) + { + Assert.Fail(); + return; } - - [Test] - public void TestValidateInvalidFactory() + + if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException) { - IocContainer iocContainer = new(); - iocContainer.Install(new TestInstallerWithInvalidFactory()); + Assert.Fail(); + return; + } - IocValidator validator = new(iocContainer); + Assert.IsInstanceOf(iTest2CtorNotMatchingException.InnerExceptions[0]); + } + + [Test] + public void TestValidateInvalidFactory() + { + IocContainer iocContainer = new(); + iocContainer.Install(new TestInstallerWithInvalidFactory()); - AggregateException aggregateException = Assert.Throws(() => validator.Validate()); + IocValidator validator = new(iocContainer); - AssertNoMatchingConstructorFoundForType(aggregateException); - } + AggregateException aggregateException = Assert.Throws(() => validator.Validate()); + + AssertNoMatchingConstructorFoundForType(aggregateException); + } - private void AssertNoMatchingConstructorFoundForType(AggregateException aggregateException) - { - Exception exception = aggregateException?.InnerExceptions[0]; - if (exception is NoMatchingConstructorFoundException noMatchingConstructorFoundException) - Assert.AreEqual(typeof(T), noMatchingConstructorFoundException.Type); - else - Assert.Fail($"Exception is no NoMatchingConstructorFoundException, actual type: {exception?.GetType()}"); - } + private void AssertNoMatchingConstructorFoundForType(AggregateException aggregateException) + { + Exception exception = aggregateException?.InnerExceptions[0]; + if (exception is NoMatchingConstructorFoundException noMatchingConstructorFoundException) + Assert.AreEqual(typeof(T), noMatchingConstructorFoundException.Type); + else + Assert.Fail($"Exception is no NoMatchingConstructorFoundException, actual type: {exception?.GetType()}"); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs b/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs index b346a27..1a89ef7 100644 --- a/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs +++ b/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs @@ -6,96 +6,95 @@ using JetBrains.Annotations; using LightweightIocContainer; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class MultipleMultitonRegistrationTest { - [TestFixture] - public class MultipleMultitonRegistrationTest - { - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [UsedImplicitly] - public interface ITest : IProvider - { + [UsedImplicitly] + public interface ITest : IProvider + { - } + } - public interface IProvider - { - int Number { get; } - void DoSomething(int number); - } + public interface IProvider + { + int Number { get; } + void DoSomething(int number); + } - [UsedImplicitly] - public class Test : ITest - { - public int Number { get; private set; } + [UsedImplicitly] + public class Test : ITest + { + public int Number { get; private set; } - public void DoSomething(int number) => Number = number; - } + public void DoSomething(int number) => Number = number; + } - private class MultitonScope - { + private class MultitonScope + { - } + } - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestRegisterAndResolveMultipleMultitonRegistration() - { - _iocContainer.Register(r => r.AddMultiton()); + [Test] + public void TestRegisterAndResolveMultipleMultitonRegistration() + { + _iocContainer.Register(r => r.AddMultiton()); - MultitonScope scope = new(); + MultitonScope scope = new(); - ITest test = _iocContainer.Resolve(scope); - Assert.NotNull(test); + ITest test = _iocContainer.Resolve(scope); + Assert.NotNull(test); - IProvider provider = _iocContainer.Resolve(scope); - Assert.NotNull(provider); - Assert.AreEqual(test, provider); - Assert.AreSame(test, provider); - } + IProvider provider = _iocContainer.Resolve(scope); + Assert.NotNull(provider); + Assert.AreEqual(test, provider); + Assert.AreSame(test, provider); + } - [Test] - public void TestRegisterAndResolveMultipleMultitonRegistrationWithDifferentScope() - { - _iocContainer.Register(r => r.AddMultiton()); + [Test] + public void TestRegisterAndResolveMultipleMultitonRegistrationWithDifferentScope() + { + _iocContainer.Register(r => r.AddMultiton()); - MultitonScope scope = new(); - MultitonScope differentScope = new(); + MultitonScope scope = new(); + MultitonScope differentScope = new(); - ITest test = _iocContainer.Resolve(scope); - Assert.NotNull(test); + ITest test = _iocContainer.Resolve(scope); + Assert.NotNull(test); - IProvider provider = _iocContainer.Resolve(differentScope); - Assert.NotNull(provider); + IProvider provider = _iocContainer.Resolve(differentScope); + Assert.NotNull(provider); - Assert.AreNotEqual(test, provider); - Assert.AreNotSame(test, provider); - } + Assert.AreNotEqual(test, provider); + Assert.AreNotSame(test, provider); + } - [Test] - public void TestMultipleMultitonRegistrationOnCreate() - { - _iocContainer.Register(r => r.AddMultiton().OnCreate(t => t.DoSomething(1))); + [Test] + public void TestMultipleMultitonRegistrationOnCreate() + { + _iocContainer.Register(r => r.AddMultiton().OnCreate(t => t.DoSomething(1))); - MultitonScope scope = new(); + MultitonScope scope = new(); - ITest test = _iocContainer.Resolve(scope); - Assert.NotNull(test); - Assert.AreEqual(1, test.Number); + ITest test = _iocContainer.Resolve(scope); + Assert.NotNull(test); + Assert.AreEqual(1, test.Number); - IProvider provider = _iocContainer.Resolve(scope); - Assert.NotNull(provider); - Assert.AreEqual(1, provider.Number); + IProvider provider = _iocContainer.Resolve(scope); + Assert.NotNull(provider); + Assert.AreEqual(1, provider.Number); - Assert.AreEqual(test, provider); - Assert.AreSame(test, provider); - } + Assert.AreEqual(test, provider); + Assert.AreSame(test, provider); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/OnCreateTest.cs b/Test.LightweightIocContainer/OnCreateTest.cs index 8e00c81..8237d55 100644 --- a/Test.LightweightIocContainer/OnCreateTest.cs +++ b/Test.LightweightIocContainer/OnCreateTest.cs @@ -9,31 +9,30 @@ using LightweightIocContainer.Registrations; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class OnCreateTest { - [TestFixture] - public class OnCreateTest + private interface ITest { - private interface ITest - { - void DoSomething(); - } + void DoSomething(); + } - private class Test : ITest - { - public void DoSomething() => throw new Exception(); - } + private class Test : ITest + { + public void DoSomething() => throw new Exception(); + } - [Test] - public void TestOnCreate() - { - RegistrationFactory registrationFactory = new(new Mock().Object); - ITypedRegistration testRegistration = registrationFactory.Register(Lifestyle.Transient).OnCreate(t => t.DoSomething()); + [Test] + public void TestOnCreate() + { + RegistrationFactory registrationFactory = new(new Mock().Object); + ITypedRegistration testRegistration = registrationFactory.Register(Lifestyle.Transient).OnCreate(t => t.DoSomething()); - Test test = new(); + Test test = new(); - Assert.Throws(() => testRegistration.OnCreateAction!(test)); - } + Assert.Throws(() => testRegistration.OnCreateAction!(test)); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/OpenGenericRegistrationTest.cs b/Test.LightweightIocContainer/OpenGenericRegistrationTest.cs index bd880bf..c9dcac0 100644 --- a/Test.LightweightIocContainer/OpenGenericRegistrationTest.cs +++ b/Test.LightweightIocContainer/OpenGenericRegistrationTest.cs @@ -8,62 +8,61 @@ using LightweightIocContainer; using LightweightIocContainer.Exceptions; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class OpenGenericRegistrationTest { - [TestFixture] - public class OpenGenericRegistrationTest - { - private IocContainer _iocContainer; + private IocContainer _iocContainer; - [UsedImplicitly] - [SuppressMessage("ReSharper", "UnusedTypeParameter")] - public interface ITest - { + [UsedImplicitly] + [SuppressMessage("ReSharper", "UnusedTypeParameter")] + public interface ITest + { - } + } - [UsedImplicitly] - public class Test : ITest - { + [UsedImplicitly] + public class Test : ITest + { - } + } - [SetUp] - public void SetUp() => _iocContainer = new IocContainer(); + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); - [TearDown] - public void TearDown() => _iocContainer.Dispose(); + [TearDown] + public void TearDown() => _iocContainer.Dispose(); - [Test] - public void TestRegisterOpenGenericType() - { - _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>))); + [Test] + public void TestRegisterOpenGenericType() + { + _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>))); - ITest test = _iocContainer.Resolve>(); - Assert.NotNull(test); - } + ITest test = _iocContainer.Resolve>(); + Assert.NotNull(test); + } - [Test] - public void TestRegisterOpenGenericTypeAsSingleton() - { - _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Singleton)); + [Test] + public void TestRegisterOpenGenericTypeAsSingleton() + { + _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Singleton)); - ITest test = _iocContainer.Resolve>(); - Assert.NotNull(test); + ITest test = _iocContainer.Resolve>(); + Assert.NotNull(test); - ITest secondTest = _iocContainer.Resolve>(); - Assert.NotNull(secondTest); + ITest secondTest = _iocContainer.Resolve>(); + Assert.NotNull(secondTest); - Assert.AreEqual(test, secondTest); - Assert.AreSame(test, secondTest); - } + Assert.AreEqual(test, secondTest); + Assert.AreSame(test, secondTest); + } - [Test] - public void TestRegisterOpenGenericTypeAsMultitonThrowsException() => - Assert.Throws(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Multiton))); + [Test] + public void TestRegisterOpenGenericTypeAsMultitonThrowsException() => + Assert.Throws(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(ITest<>), typeof(Test<>), Lifestyle.Multiton))); - [Test] - public void TestRegisterNonOpenGenericTypeWithOpenGenericsFunctionThrowsException() => - Assert.Throws(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(int), typeof(int)))); - } + [Test] + public void TestRegisterNonOpenGenericTypeWithOpenGenericsFunctionThrowsException() => + Assert.Throws(() => _iocContainer.Register(r => r.AddOpenGenerics(typeof(int), typeof(int)))); } \ No newline at end of file diff --git a/Test.LightweightIocContainer/RegistrationBaseTest.cs b/Test.LightweightIocContainer/RegistrationBaseTest.cs index e5ed34f..8027334 100644 --- a/Test.LightweightIocContainer/RegistrationBaseTest.cs +++ b/Test.LightweightIocContainer/RegistrationBaseTest.cs @@ -10,90 +10,89 @@ using LightweightIocContainer.ResolvePlaceholders; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +public class RegistrationBaseTest { - [TestFixture] - public class RegistrationBaseTest + private interface ITest { - private interface ITest - { - } + } - private interface IFoo - { + private interface IFoo + { - } + } - private interface IBar - { + private interface IBar + { - } + } - private class Test : ITest - { + private class Test : ITest + { - } + } - [UsedImplicitly] - private class Foo : IFoo + [UsedImplicitly] + private class Foo : IFoo + { + public Foo(IBar bar, ITest test) { - public Foo(IBar bar, ITest test) - { - } } + } - private class Bar : IBar - { + private class Bar : IBar + { - } + } - [Test] - public void TestWithParameters() - { - RegistrationFactory registrationFactory = new(new Mock().Object); + [Test] + public void TestWithParameters() + { + RegistrationFactory registrationFactory = new(new Mock().Object); - IBar bar = new Bar(); - ITest test = new Test(); + IBar bar = new Bar(); + ITest test = new Test(); - RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register(Lifestyle.Transient).WithParameters(bar, test); + RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register(Lifestyle.Transient).WithParameters(bar, test); - Assert.AreEqual(bar, testRegistration.Parameters![0]); - Assert.AreEqual(test, testRegistration.Parameters[1]); - } + Assert.AreEqual(bar, testRegistration.Parameters![0]); + Assert.AreEqual(test, testRegistration.Parameters[1]); + } - [Test] - public void TestWithParametersDifferentOrder() - { - RegistrationFactory registrationFactory = new(new Mock().Object); + [Test] + public void TestWithParametersDifferentOrder() + { + RegistrationFactory registrationFactory = new(new Mock().Object); - IBar bar = new Bar(); - ITest test = new Test(); + IBar bar = new Bar(); + ITest test = new Test(); - RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register(Lifestyle.Transient).WithParameters((0, bar), (3, test), (2, "SomeString")); + RegistrationBase testRegistration = (RegistrationBase) registrationFactory.Register(Lifestyle.Transient).WithParameters((0, bar), (3, test), (2, "SomeString")); - Assert.AreEqual(bar, testRegistration.Parameters![0]); - Assert.IsInstanceOf(testRegistration.Parameters[1]); - Assert.AreEqual("SomeString", testRegistration.Parameters[2]); - Assert.AreEqual(test, testRegistration.Parameters[3]); - } + Assert.AreEqual(bar, testRegistration.Parameters![0]); + Assert.IsInstanceOf(testRegistration.Parameters[1]); + Assert.AreEqual("SomeString", testRegistration.Parameters[2]); + Assert.AreEqual(test, testRegistration.Parameters[3]); + } - [Test] - public void TestWithParametersCalledTwice() - { - RegistrationFactory registrationFactory = new(new Mock().Object); - Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters(new Bar()).WithParameters(new Test())); - Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters((0, new Bar())).WithParameters((1, new Test()))); - } + [Test] + public void TestWithParametersCalledTwice() + { + RegistrationFactory registrationFactory = new(new Mock().Object); + Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters(new Bar()).WithParameters(new Test())); + Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters((0, new Bar())).WithParameters((1, new Test()))); + } - [Test] - public void TestWithParametersNoParametersGiven() - { - RegistrationFactory registrationFactory = new(new Mock().Object); - Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters((object[])null)); - Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters(((int index, object parameter)[])null)); - } + [Test] + public void TestWithParametersNoParametersGiven() + { + RegistrationFactory registrationFactory = new(new Mock().Object); + Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters((object[])null)); + Assert.Throws(() => registrationFactory.Register(Lifestyle.Transient).WithParameters(((int index, object parameter)[])null)); } } \ No newline at end of file diff --git a/Test.LightweightIocContainer/SingleTypeRegistrationTest.cs b/Test.LightweightIocContainer/SingleTypeRegistrationTest.cs index a80eff8..a57a163 100644 --- a/Test.LightweightIocContainer/SingleTypeRegistrationTest.cs +++ b/Test.LightweightIocContainer/SingleTypeRegistrationTest.cs @@ -9,63 +9,62 @@ using LightweightIocContainer.Registrations; using Moq; using NUnit.Framework; -namespace Test.LightweightIocContainer +namespace Test.LightweightIocContainer; + +[TestFixture] +// ReSharper disable MemberHidesStaticFromOuterClass +public class SingleTypeRegistrationTest { - [TestFixture] - // ReSharper disable MemberHidesStaticFromOuterClass - public class SingleTypeRegistrationTest + private interface IFoo { - private interface IFoo - { - IBar Bar { get; } - } + IBar Bar { get; } + } - private interface IBar - { + private interface IBar + { - } + } - [UsedImplicitly] - private class Foo : IFoo - { - public Foo(IBar bar) => Bar = bar; + [UsedImplicitly] + private class Foo : IFoo + { + public Foo(IBar bar) => Bar = bar; - public IBar Bar { get; } - } + public IBar Bar { get; } + } - [UsedImplicitly] - private class Bar : IBar - { + [UsedImplicitly] + private class Bar : IBar + { - } + } - [Test] - public void TestSingleTypeRegistrationWithFactoryMethod() - { - IBar bar = new Bar(); + [Test] + public void TestSingleTypeRegistrationWithFactoryMethod() + { + IBar bar = new Bar(); - Mock iocContainerMock = new(); - iocContainerMock.Setup(c => c.Resolve()).Returns(bar); + Mock iocContainerMock = new(); + iocContainerMock.Setup(c => c.Resolve()).Returns(bar); - RegistrationFactory registrationFactory = new(iocContainerMock.Object); - ISingleTypeRegistration registration = registrationFactory.Register(Lifestyle.Transient).WithFactoryMethod(c => new Foo(c.Resolve())); + RegistrationFactory registrationFactory = new(iocContainerMock.Object); + ISingleTypeRegistration registration = registrationFactory.Register(Lifestyle.Transient).WithFactoryMethod(c => new Foo(c.Resolve())); - IFoo foo = registration.FactoryMethod!(iocContainerMock.Object); - Assert.AreEqual(bar, foo.Bar); - } + IFoo foo = registration.FactoryMethod!(iocContainerMock.Object); + Assert.AreEqual(bar, foo.Bar); + } - [Test] - public void TestSingleTypeRegistrationResolveSingleton() - { - IocContainer container = new(); + [Test] + public void TestSingleTypeRegistrationResolveSingleton() + { + IocContainer container = new(); - IBar bar = new Bar(); - container.Register(r => r.Add(Lifestyle.Singleton).WithFactoryMethod(_ => new Foo(bar))); + IBar bar = new Bar(); + container.Register(r => r.Add(Lifestyle.Singleton).WithFactoryMethod(_ => new Foo(bar))); - IFoo foo = container.Resolve(); + IFoo foo = container.Resolve(); - Assert.IsInstanceOf(foo); - Assert.AreEqual(bar, foo.Bar); - } + Assert.IsInstanceOf(foo); + Assert.AreEqual(bar, foo.Bar); } } \ No newline at end of file