From b324ee74fd6534561404acaae4b881b96675f426 Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 11:41:24 +0100 Subject: [PATCH 1/9] #45: add first implementation of IMultipleMultitonRegistration --- .../IMultipleMultitonRegistration.cs | 11 ++++++ .../MultipleMultitonRegistration.cs | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs create mode 100644 LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs new file mode 100644 index 0000000..cfc9c7f --- /dev/null +++ b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs @@ -0,0 +1,11 @@ +// Author: Gockner, Simon +// Created: 2020-11-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +namespace LightweightIocContainer.Interfaces.Registrations +{ + public interface IMultipleMultitonRegistration : IMultitonRegistration, IMultipleRegistration where TImplementation : TInterface1, TInterface2 + { + + } +} \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs new file mode 100644 index 0000000..abc784f --- /dev/null +++ b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs @@ -0,0 +1,38 @@ +// Author: Gockner, Simon +// Created: 2020-11-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System; +using System.Collections.Generic; +using LightweightIocContainer.Interfaces.Registrations; + +namespace LightweightIocContainer.Registrations +{ + public class MultipleMultitonRegistration : MultitonRegistration, IMultipleMultitonRegistration where TImplementation : TInterface1, TInterface2 + { + public MultipleMultitonRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Type scope) + : base(interfaceType1, implementationType, scope) + { + Registrations = new List() + { + new MultitonRegistration(interfaceType1, implementationType, scope), + new MultitonRegistration(interfaceType2, implementationType, scope) + }; + } + + public List Registrations { get; } + + public override ITypedRegistrationBase OnCreate(Action action) + { + foreach (var registration in Registrations) + { + 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 From 17df31ec3f0816dc2ee9a670f31243a4c6138bfb Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 12:01:09 +0100 Subject: [PATCH 2/9] #45: IMultitonRegistration inherits from ITypedRegistration now --- .../Interfaces/Registrations/IMultitonRegistration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs index 2106215..5b20f0e 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IMultitonRegistration.cs @@ -17,7 +17,7 @@ namespace LightweightIocContainer.Interfaces.Registrations /// /// A base without implementation /// - public interface IMultitonRegistration : IRegistrationBase, IMultitonRegistration + public interface IMultitonRegistration : ITypedRegistrationBase, IMultitonRegistration { /// /// The of the multiton scope From e51298c5e08457aa2b6fe8a282f0c1920504bbac Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 12:01:39 +0100 Subject: [PATCH 3/9] #45: add method to create iMultipleMultitonRegistration --- LightweightIocContainer/Registrations/RegistrationFactory.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/LightweightIocContainer/Registrations/RegistrationFactory.cs b/LightweightIocContainer/Registrations/RegistrationFactory.cs index 7ff2487..d17d1e4 100644 --- a/LightweightIocContainer/Registrations/RegistrationFactory.cs +++ b/LightweightIocContainer/Registrations/RegistrationFactory.cs @@ -119,6 +119,11 @@ namespace LightweightIocContainer.Registrations return new MultitonRegistration(typeof(TInterface), typeof(TImplementation), typeof(TScope)); } + public IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2 + { + return new MultipleMultitonRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), typeof(TScope)); + } + /// /// Register an Interface as an abstract typed factory and create a /// From 07c626d42a4edb5d420513a9cd177685b35f76af Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 12:02:10 +0100 Subject: [PATCH 4/9] #45: add registration method for IMultipleMultitonRegistration --- LightweightIocContainer/IocContainer.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index c95a555..cb64982 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -193,6 +193,14 @@ namespace LightweightIocContainer return registration; } + public IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2 + { + IMultipleMultitonRegistration registration = _registrationFactory.RegisterMultiton(); + Register(registration); + + return registration; + } + /// /// Register an Interface as an abstract typed factory /// @@ -377,7 +385,7 @@ namespace LightweightIocContainer 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 - var instances = _multitons.FirstOrDefault(m => m.type == typeof(T) && m.scope == registration.Scope).instances; //get instances for the given type and scope + var instances = _multitons.FirstOrDefault(m => m.type == registration.ImplementationType && m.scope == registration.Scope).instances; //get instances for the given type and scope (use implementation type to resolve the correct instance for multiple multiton registrations as well) if (instances != null) { if (instances.TryGetValue(scopeArgument, out object instance)) @@ -394,7 +402,7 @@ namespace LightweightIocContainer ConditionalWeakTable weakTable = new ConditionalWeakTable(); weakTable.Add(scopeArgument, newInstance); - _multitons.Add((typeof(T), registration.Scope, weakTable)); + _multitons.Add((registration.ImplementationType, registration.Scope, weakTable)); return newInstance; } From 9c99ba26823d556b778146b08b4e15496c10595e Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 12:02:26 +0100 Subject: [PATCH 5/9] - update modules.xml --- .idea/.idea.LightweightIocContainer/.idea/modules.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/.idea.LightweightIocContainer/.idea/modules.xml b/.idea/.idea.LightweightIocContainer/.idea/modules.xml index fd7a90d..0d06f78 100644 --- a/.idea/.idea.LightweightIocContainer/.idea/modules.xml +++ b/.idea/.idea.LightweightIocContainer/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file From d79f33146cadbeb40b4138224f8ae4143032496b Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 13:38:22 +0100 Subject: [PATCH 6/9] #45: add register method to interface --- LightweightIocContainer/Interfaces/IIocContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/LightweightIocContainer/Interfaces/IIocContainer.cs b/LightweightIocContainer/Interfaces/IIocContainer.cs index d4c1465..676e121 100644 --- a/LightweightIocContainer/Interfaces/IIocContainer.cs +++ b/LightweightIocContainer/Interfaces/IIocContainer.cs @@ -101,6 +101,8 @@ namespace LightweightIocContainer.Interfaces /// The created IMultitonRegistration RegisterMultiton() where TImplementation : TInterface; + IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2; + /// /// Register an Interface as an abstract typed factory /// From 865f36d0a76b00c6014dff039ed81493b249bf0d Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 13:38:55 +0100 Subject: [PATCH 7/9] #45: clearMultitonInstances() gets registration first now --- LightweightIocContainer/IocContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index cb64982..57c2e84 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -611,7 +611,11 @@ namespace LightweightIocContainer /// The to clear the multiton instances public void ClearMultitonInstances() { - var multitonInstance = _multitons.FirstOrDefault(m => m.type == typeof(T)); + IRegistration registration = FindRegistration(); + if (!(registration is IMultitonRegistration multitonRegistration)) + return; + + 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) From 4654ed303f641ffe27cf1f7ba861a7f324790a4e Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 13:39:06 +0100 Subject: [PATCH 8/9] #45: add MultipleMultitonRegistrationTest --- .../MultipleMultitonRegistrationTest.cs | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs diff --git a/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs b/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs new file mode 100644 index 0000000..59d1188 --- /dev/null +++ b/Test.LightweightIocContainer/MultipleMultitonRegistrationTest.cs @@ -0,0 +1,102 @@ +// Author: Gockner, Simon +// Created: 2020-11-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using JetBrains.Annotations; +using LightweightIocContainer; +using LightweightIocContainer.Interfaces; +using NUnit.Framework; + +namespace Test.LightweightIocContainer +{ + [TestFixture] + public class MultipleMultitonRegistrationTest + { + private IIocContainer _iocContainer; + + [UsedImplicitly] + public interface ITest : IProvider + { + + } + + public interface IProvider + { + int Number { get; } + void DoSomething(int number); + } + + [UsedImplicitly] + public class Test : ITest + { + public int Number { get; private set; } + + public void DoSomething(int number) => Number = number; + } + + private class MultitonScope + { + + } + + + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); + + [TearDown] + public void TearDown() => _iocContainer.Dispose(); + + [Test] + public void TestRegisterAndResolveMultipleMultitonRegistration() + { + _iocContainer.RegisterMultiton(); + + MultitonScope scope = new MultitonScope(); + + ITest test = _iocContainer.Resolve(scope); + Assert.NotNull(test); + + IProvider provider = _iocContainer.Resolve(scope); + Assert.NotNull(provider); + Assert.AreEqual(test, provider); + Assert.AreSame(test, provider); + } + + [Test] + public void TestRegisterAndResolveMultipleMultitonRegistrationWithDifferentScope() + { + _iocContainer.RegisterMultiton(); + + MultitonScope scope = new MultitonScope(); + MultitonScope differentScope = new MultitonScope(); + + ITest test = _iocContainer.Resolve(scope); + Assert.NotNull(test); + + IProvider provider = _iocContainer.Resolve(differentScope); + Assert.NotNull(provider); + + Assert.AreNotEqual(test, provider); + Assert.AreNotSame(test, provider); + } + + [Test] + public void TestMultipleMultitonRegistrationOnCreate() + { + _iocContainer.RegisterMultiton().OnCreate(t => t.DoSomething(1)); + + MultitonScope scope = new MultitonScope(); + + 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); + + Assert.AreEqual(test, provider); + Assert.AreSame(test, provider); + } + } +} \ No newline at end of file From 78eae75296d45cedd2a577aeb0945ced3ea5c62a Mon Sep 17 00:00:00 2001 From: Simon G Date: Thu, 19 Nov 2020 13:48:26 +0100 Subject: [PATCH 9/9] #45: add comments --- .../Interfaces/IIocContainer.cs | 8 +++ .../IMultipleMultitonRegistration.cs | 6 ++ LightweightIocContainer/IocContainer.cs | 8 +++ .../LightweightIocContainer.xml | 67 +++++++++++++++++++ .../MultipleMultitonRegistration.cs | 21 ++++++ .../Registrations/RegistrationFactory.cs | 8 +++ 6 files changed, 118 insertions(+) diff --git a/LightweightIocContainer/Interfaces/IIocContainer.cs b/LightweightIocContainer/Interfaces/IIocContainer.cs index 676e121..efdb7ba 100644 --- a/LightweightIocContainer/Interfaces/IIocContainer.cs +++ b/LightweightIocContainer/Interfaces/IIocContainer.cs @@ -101,6 +101,14 @@ namespace LightweightIocContainer.Interfaces /// The created IMultitonRegistration RegisterMultiton() where TImplementation : TInterface; + /// + /// 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 + /// The created IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2; /// diff --git a/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs index cfc9c7f..079248d 100644 --- a/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs +++ b/LightweightIocContainer/Interfaces/Registrations/IMultipleMultitonRegistration.cs @@ -4,6 +4,12 @@ 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 { diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 57c2e84..0382121 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -193,6 +193,14 @@ namespace LightweightIocContainer return registration; } + /// + /// 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 + /// The created public IMultipleMultitonRegistration RegisterMultiton() where TImplementation : TInterface1, TInterface2 { IMultipleMultitonRegistration registration = _registrationFactory.RegisterMultiton(); diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml index a2891e6..9d9947d 100644 --- a/LightweightIocContainer/LightweightIocContainer.xml +++ b/LightweightIocContainer/LightweightIocContainer.xml @@ -447,6 +447,16 @@ The Type of the multiton scope The created + + + 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 + The created + Register an Interface as an abstract typed factory @@ -575,6 +585,14 @@ The Lifestyle of Instances that are created with this + + + An to register multiple interfaces for on implementation type that implements them as a multiton + + The first interface + The second interface + The implementation + The base interface for every to register multiple interfaces @@ -827,6 +845,16 @@ The Type of the multiton scope The created + + + 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 + The created + Register an Interface as an abstract typed factory @@ -989,6 +1017,35 @@ The of the implementation The of the + + + An to register multiple interfaces for on implementation type that implements them as a multiton + + The first interface + The second interface + The implementation + + + + 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 + + + + A of s that are registered within this + + + + + Pass an that will be invoked when an instance of this type is created + + The + The current instance of this + The base class for every to register multiple interfaces @@ -1299,6 +1356,16 @@ The Type of the multiton scope A new created with the given parameters + + + 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 + Register an Interface as an abstract typed factory and create a diff --git a/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs index abc784f..d2ce510 100644 --- a/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs +++ b/LightweightIocContainer/Registrations/MultipleMultitonRegistration.cs @@ -8,8 +8,21 @@ using LightweightIocContainer.Interfaces.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 public class MultipleMultitonRegistration : MultitonRegistration, IMultipleMultitonRegistration where TImplementation : TInterface1, TInterface2 { + /// + /// 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 public MultipleMultitonRegistration(Type interfaceType1, Type interfaceType2, Type implementationType, Type scope) : base(interfaceType1, implementationType, scope) { @@ -20,8 +33,16 @@ namespace LightweightIocContainer.Registrations }; } + /// + /// 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 ITypedRegistrationBase OnCreate(Action action) { foreach (var registration in Registrations) diff --git a/LightweightIocContainer/Registrations/RegistrationFactory.cs b/LightweightIocContainer/Registrations/RegistrationFactory.cs index d17d1e4..03913e5 100644 --- a/LightweightIocContainer/Registrations/RegistrationFactory.cs +++ b/LightweightIocContainer/Registrations/RegistrationFactory.cs @@ -119,6 +119,14 @@ namespace LightweightIocContainer.Registrations return new MultitonRegistration(typeof(TInterface), typeof(TImplementation), typeof(TScope)); } + /// + /// 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 { return new MultipleMultitonRegistration(typeof(TInterface1), typeof(TInterface2), typeof(TImplementation), typeof(TScope));