diff --git a/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs b/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs
new file mode 100644
index 0000000..88034cf
--- /dev/null
+++ b/LightweightIocContainer/Exceptions/IllegalAbstractMethodCreationException.cs
@@ -0,0 +1,26 @@
+// // Author: Gockner, Simon
+// // Created: 2019-06-28
+// // Copyright(c) 2019 SimonG. All Rights Reserved.
+
+using System;
+using System.Reflection;
+
+namespace LightweightIocContainer.Exceptions
+{
+ ///
+ /// The creation of the abstract method is illegal in its current state
+ ///
+ public class IllegalAbstractMethodCreationException : Exception
+ {
+ public IllegalAbstractMethodCreationException(string message, MethodInfo method)
+ : base(message)
+ {
+ Method = method;
+ }
+
+ ///
+ /// The Method whose creation is illegal
+ ///
+ public MethodInfo Method { get; }
+ }
+}
\ No newline at end of file
diff --git a/LightweightIocContainer/Interfaces/IIocContainer.cs b/LightweightIocContainer/Interfaces/IIocContainer.cs
index f18b469..ff23b00 100644
--- a/LightweightIocContainer/Interfaces/IIocContainer.cs
+++ b/LightweightIocContainer/Interfaces/IIocContainer.cs
@@ -51,5 +51,11 @@ namespace LightweightIocContainer.Interfaces
/// An instance of the given type
/// Could not find function
object Resolve(Type type, object[] arguments);
+
+ ///
+ /// Clear the multiton instances of the given type from the registered multitons list
+ ///
+ /// The Type to clear the multiton instances
+ void ClearMultitonInstances();
}
}
\ No newline at end of file
diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs
index d3d3cf9..7009119 100644
--- a/LightweightIocContainer/IocContainer.cs
+++ b/LightweightIocContainer/IocContainer.cs
@@ -158,7 +158,7 @@ namespace LightweightIocContainer
throw new MultitonResolveException("Can not resolve multiton without arguments.", typeof(T));
object scopeArgument = arguments[0];
- if (scopeArgument.GetType() != registration.Scope)
+ 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}).", typeof(T));
//if a multiton for the given scope exists return it
@@ -245,7 +245,22 @@ namespace LightweightIocContainer
return null;
}
-
+
+ ///
+ /// Clear the multiton instances of the given type from the registered multitons list
+ ///
+ /// The Type to clear the multiton instances
+ public void ClearMultitonInstances()
+ {
+ var multitonInstance = _multitons.FirstOrDefault(m => m.type == typeof(T));
+
+ //it is allowed to clear a non existing multiton instance (don't throw an exception)
+ if (multitonInstance == default)
+ return;
+
+ _multitons.Remove(multitonInstance);
+ }
+
public void Dispose()
{
_registrations.Clear();
diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml
index dd41291..71c031c 100644
--- a/LightweightIocContainer/LightweightIocContainer.xml
+++ b/LightweightIocContainer/LightweightIocContainer.xml
@@ -4,6 +4,16 @@
LightweightIocContainer
+
+
+ The creation of the abstract method is illegal in its current state
+
+
+
+
+ The Method whose creation is illegal
+
+
An internal Error happened while the tried to resolve an instance
@@ -153,6 +163,12 @@
An instance of the given type
Could not find function
+
+
+ Clear the multiton instances of the given type from the registered multitons list
+
+ The Type to clear the multiton instances
+
An that installs all s for its given
@@ -330,6 +346,12 @@
The existing arguments
An array of all needed constructor arguments to create
+
+
+ Clear the multiton instances of the given type from the registered multitons list
+
+ The Type to clear the multiton instances
+
The Lifestyles that can be used for a
@@ -483,6 +505,7 @@
Creates the factory from the given abstract factory type
Factory registration is invalid
+ Creation of abstract methods are illegal in their current state
diff --git a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs
index ee3d1d1..e85de8c 100644
--- a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs
+++ b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs
@@ -21,6 +21,8 @@ namespace LightweightIocContainer.Registrations
/// The type of the abstract typed factory
public class TypedFactoryRegistration : ITypedFactoryRegistration
{
+ private const string CLEAR_MULTITON_INSTANCE_METHOD_NAME = "ClearMultitonInstance";
+
public TypedFactoryRegistration(Type factoryType, IIocContainer container)
{
InterfaceType = factoryType;
@@ -49,6 +51,7 @@ namespace LightweightIocContainer.Registrations
/// Creates the factory from the given abstract factory type
///
/// Factory registration is invalid
+ /// Creation of abstract methods are illegal in their current state
private void CreateFactory(IIocContainer container)
{
List createMethods = InterfaceType.GetMethods().Where(m => m.ReturnType != typeof(void)).ToList();
@@ -129,6 +132,41 @@ namespace LightweightIocContainer.Registrations
generator.Emit(OpCodes.Ret);
}
+ //if factory contains a method to clear multiton instances
+ MethodInfo multitonClearMethod = InterfaceType.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();
+ //}
+
+ if (multitonClearMethod.IsGenericMethod)
+ {
+ Type typeToClear = multitonClearMethod.GetGenericArguments().FirstOrDefault();
+ if (typeToClear == null)
+ throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod);
+
+ MethodBuilder multitonClearMethodBuilder = typeBuilder.DefineMethod(multitonClearMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual,
+ multitonClearMethod.ReturnType, null);
+ multitonClearMethodBuilder.DefineGenericParameters(typeToClear.Name);
+
+ typeBuilder.DefineMethodOverride(multitonClearMethodBuilder, multitonClearMethod);
+
+ ILGenerator multitonClearGenerator = multitonClearMethodBuilder.GetILGenerator();
+ multitonClearGenerator.Emit(OpCodes.Ldarg_0);
+ multitonClearGenerator.Emit(OpCodes.Ldfld, containerFieldBuilder);
+
+ multitonClearGenerator.EmitCall(OpCodes.Callvirt, typeof(IIocContainer).GetMethod(nameof(IIocContainer.ClearMultitonInstances))?.MakeGenericMethod(typeToClear), null);
+ multitonClearGenerator.Emit(OpCodes.Ret);
+ }
+ else
+ {
+ throw new IllegalAbstractMethodCreationException("No Type to clear specified.", multitonClearMethod);
+ }
+ }
+
Factory.Factory = (TFactory) Activator.CreateInstance(typeBuilder.CreateTypeInfo().AsType(), container);
}
}
diff --git a/Test.LightweightIocContainer/IocContainerTest.cs b/Test.LightweightIocContainer/IocContainerTest.cs
index d9be809..13052a1 100644
--- a/Test.LightweightIocContainer/IocContainerTest.cs
+++ b/Test.LightweightIocContainer/IocContainerTest.cs
@@ -26,6 +26,8 @@ namespace Test.LightweightIocContainer
ITest Create();
ITest Create(string name);
ITest Create(MultitonScope scope);
+
+ void ClearMultitonInstance();
}
private interface ITestFactoryNoCreate
@@ -33,6 +35,13 @@ namespace Test.LightweightIocContainer
}
+ private interface ITestFactoryNonGenericClear
+ {
+ ITest Create();
+
+ void ClearMultitonInstance();
+ }
+
private class Test : ITest
{
@@ -112,6 +121,14 @@ namespace Test.LightweightIocContainer
Assert.Throws(() => iocContainer.Register(RegistrationFactory.RegisterFactory(iocContainer)));
}
+ [Test]
+ public void TestRegisterFactoryClearMultitonsNonGeneric()
+ {
+ IIocContainer iocContainer = new IocContainer();
+
+ Assert.Throws(() => iocContainer.Register(RegistrationFactory.RegisterFactory(iocContainer)));
+ }
+
[Test]
public void TestResolveNotRegistered()
{
@@ -287,5 +304,35 @@ namespace Test.LightweightIocContainer
Assert.AreNotSame(resolvedTest1, resolvedTest3);
Assert.AreNotSame(resolvedTest2, resolvedTest3);
}
+
+ [Test]
+ public void TestResolveMultitonFromFactoryClearInstances()
+ {
+ IIocContainer iocContainer = new IocContainer();
+ iocContainer.Register(RegistrationFactory.Register());
+ iocContainer.Register(RegistrationFactory.RegisterFactory(iocContainer));
+
+ MultitonScope scope1 = new MultitonScope();
+ MultitonScope scope2 = new MultitonScope();
+
+ ITestFactory testFactory = iocContainer.Resolve();
+
+ 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);
+
+ testFactory.ClearMultitonInstance();
+
+ ITest resolvedTest4 = testFactory.Create(scope1);
+ ITest resolvedTest5 = testFactory.Create(scope2);
+
+ Assert.AreNotSame(resolvedTest1, resolvedTest4);
+ Assert.AreNotSame(resolvedTest2, resolvedTest4);
+ Assert.AreNotSame(resolvedTest3, resolvedTest5);
+ }
}
}
\ No newline at end of file