From 64d3a5823c3bf764befad20d1c1c90c15b030da7 Mon Sep 17 00:00:00 2001 From: Simon Gockner Date: Tue, 15 Oct 2019 13:38:13 +0200 Subject: [PATCH] #24: add UnitTestResolveCallback and needed registration --- .../Interfaces/IIocContainer.cs | 7 ++ .../IUnitTestCallbackRegistration.cs | 18 +++++ LightweightIocContainer/IocContainer.cs | 18 ++++- .../LightweightIocContainer.xml | 60 +++++++++++++++- .../Registrations/RegistrationFactory.cs | 9 ++- .../UnitTestCallbackRegistration.cs | 45 ++++++++++++ LightweightIocContainer/ResolveCallback.cs | 11 +++ .../IocContainerTest.cs | 17 +++++ .../UnitTestCallbackRegistrationTest.cs | 70 +++++++++++++++++++ 9 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 LightweightIocContainer/Interfaces/Registrations/IUnitTestCallbackRegistration.cs create mode 100644 LightweightIocContainer/Registrations/UnitTestCallbackRegistration.cs create mode 100644 LightweightIocContainer/ResolveCallback.cs create mode 100644 Test.LightweightIocContainer/UnitTestCallbackRegistrationTest.cs diff --git a/LightweightIocContainer/Interfaces/IIocContainer.cs b/LightweightIocContainer/Interfaces/IIocContainer.cs index 8b3712f..d680ec4 100644 --- a/LightweightIocContainer/Interfaces/IIocContainer.cs +++ b/LightweightIocContainer/Interfaces/IIocContainer.cs @@ -79,6 +79,13 @@ namespace LightweightIocContainer.Interfaces /// The abstract typed factory to register void RegisterFactory(Type tFactory); + /// + /// Register an Interface with an as a callback that is called when is called + /// + /// The Interface to register + /// The for the callback + void RegisterUnitTestCallback(ResolveCallback unitTestCallback); + /// /// Gets an instance of the given /// diff --git a/LightweightIocContainer/Interfaces/Registrations/IUnitTestCallbackRegistration.cs b/LightweightIocContainer/Interfaces/Registrations/IUnitTestCallbackRegistration.cs new file mode 100644 index 0000000..9ccbe08 --- /dev/null +++ b/LightweightIocContainer/Interfaces/Registrations/IUnitTestCallbackRegistration.cs @@ -0,0 +1,18 @@ +// Author: Gockner, Simon +// Created: 2019-10-15 +// Copyright(c) 2019 SimonG. All Rights Reserved. + +namespace LightweightIocContainer.Interfaces.Registrations +{ + /// + /// A special that allows to set an as a callback that is called on + /// + /// + public interface IUnitTestCallbackRegistration : IRegistrationBase + { + /// + /// An that is set as a callback that is called on + /// + ResolveCallback UnitTestResolveCallback { get; } + } +} \ No newline at end of file diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 08d99a8..f07bfbd 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -29,7 +29,7 @@ namespace LightweightIocContainer /// - /// The constructor of the + /// The main container that carries all the s and can resolve all the types you'll ever want /// public IocContainer() { @@ -134,6 +134,16 @@ namespace LightweightIocContainer Register(_registrationFactory.RegisterFactory(tFactory)); } + /// + /// Register an Interface with an as a callback that is called when is called + /// + /// The Interface to register + /// The for the callback + public void RegisterUnitTestCallback(ResolveCallback unitTestCallback) + { + Register(_registrationFactory.RegisterUnitTestCallback(unitTestCallback)); + } + /// /// Add the to the the /// @@ -201,7 +211,11 @@ namespace LightweightIocContainer if (registration == null) throw new TypeNotRegisteredException(typeof(T)); - if (registration is IDefaultRegistration defaultRegistration) + if (registration is IUnitTestCallbackRegistration unitTestCallbackRegistration) + { + return unitTestCallbackRegistration.UnitTestResolveCallback.Invoke(arguments); + } + else if (registration is IDefaultRegistration defaultRegistration) { if (defaultRegistration.Lifestyle == Lifestyle.Singleton) return GetOrCreateSingletonInstance(defaultRegistration, arguments); diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml index f532526..718098e 100644 --- a/LightweightIocContainer/LightweightIocContainer.xml +++ b/LightweightIocContainer/LightweightIocContainer.xml @@ -275,6 +275,13 @@ The abstract typed factory to register + + + Register an Interface with an as a callback that is called when is called + + The Interface to register + The for the callback + Gets an instance of the given @@ -399,6 +406,17 @@ The class that contains the implemented abstract factory of this + + + A special that allows to set an as a callback that is called on + + + + + + An that is set as a callback that is called on + + The main container that carries all the s and can resolve all the types you'll ever want @@ -406,7 +424,7 @@ - The constructor of the + The main container that carries all the s and can resolve all the types you'll ever want @@ -474,6 +492,13 @@ The abstract typed factory to register + + + Register an Interface with an as a callback that is called when is called + + The Interface to register + The for the callback + Add the to the the @@ -767,6 +792,39 @@ Factory registration is invalid Creation of abstract methods are illegal in their current state + + + A special that allows to set an as a callback that is called on + + + + + + A special that allows to set an as a callback that is called on + + The of the interface + The that is set as a callback + + + + The name of the + + + + + The of the Interface that is registered with this + + + + + An that is set as a callback that is called on + + + + + The resolve callback delegate + + Returns the default value for a given diff --git a/LightweightIocContainer/Registrations/RegistrationFactory.cs b/LightweightIocContainer/Registrations/RegistrationFactory.cs index e4dca51..08284a8 100644 --- a/LightweightIocContainer/Registrations/RegistrationFactory.cs +++ b/LightweightIocContainer/Registrations/RegistrationFactory.cs @@ -42,7 +42,7 @@ namespace LightweightIocContainer.Registrations /// A new created with the given parameters public IDefaultRegistration Register(Lifestyle lifestyle) { - if (typeof(TImplementation).IsInterface) //TODO: handle `Instance` case when an instance is given + if (typeof(TImplementation).IsInterface) throw new InvalidRegistrationException("Can't register an interface without its implementation type."); return Register(lifestyle); @@ -81,7 +81,7 @@ namespace LightweightIocContainer.Registrations /// A new created with the given parameters public IRegistrationBase Register(Type tImplementation, Lifestyle lifestyle) { - if (tImplementation.IsInterface) //TODO: handle `Instance` case when an instance is given + if (tImplementation.IsInterface) throw new InvalidRegistrationException("Can't register an interface without its implementation type."); return Register(tImplementation, tImplementation, lifestyle); @@ -120,5 +120,10 @@ namespace LightweightIocContainer.Registrations Type factoryRegistrationType = typeof(TypedFactoryRegistration<>).MakeGenericType(tFactory); return (IRegistrationBase)Activator.CreateInstance(factoryRegistrationType, tFactory, _iocContainer); } + + public IUnitTestCallbackRegistration RegisterUnitTestCallback(ResolveCallback unitTestResolveCallback) + { + return new UnitTestCallbackRegistration(typeof(TInterface), unitTestResolveCallback); + } } } \ No newline at end of file diff --git a/LightweightIocContainer/Registrations/UnitTestCallbackRegistration.cs b/LightweightIocContainer/Registrations/UnitTestCallbackRegistration.cs new file mode 100644 index 0000000..36cf062 --- /dev/null +++ b/LightweightIocContainer/Registrations/UnitTestCallbackRegistration.cs @@ -0,0 +1,45 @@ +// Author: Gockner, Simon +// Created: 2019-10-15 +// Copyright(c) 2019 SimonG. All Rights Reserved. + +using System; +using LightweightIocContainer.Interfaces; +using LightweightIocContainer.Interfaces.Registrations; + +namespace LightweightIocContainer.Registrations +{ + /// + /// A special that allows to set an as a callback that is called on + /// + /// + public class UnitTestCallbackRegistration : IUnitTestCallbackRegistration + { + /// + /// A special that allows to set an as a callback that is called on + /// + /// The of the interface + /// The that is set as a callback + public UnitTestCallbackRegistration(Type interfaceType, ResolveCallback unitTestResolveCallback) + { + InterfaceType = interfaceType; + UnitTestResolveCallback = unitTestResolveCallback; + + Name = InterfaceType.Name; + } + + /// + /// The name of the + /// + public string Name { get; } + + /// + /// The of the Interface that is registered with this + /// + public Type InterfaceType { get; } + + /// + /// An that is set as a callback that is called on + /// + public ResolveCallback UnitTestResolveCallback { get; } + } +} \ No newline at end of file diff --git a/LightweightIocContainer/ResolveCallback.cs b/LightweightIocContainer/ResolveCallback.cs new file mode 100644 index 0000000..d89dfff --- /dev/null +++ b/LightweightIocContainer/ResolveCallback.cs @@ -0,0 +1,11 @@ +// Author: Gockner, Simon +// Created: 2019-10-15 +// Copyright(c) 2019 SimonG. All Rights Reserved. + +namespace LightweightIocContainer +{ + /// + /// The resolve callback delegate + /// + public delegate TInterface ResolveCallback(params object[] parameters); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer/IocContainerTest.cs b/Test.LightweightIocContainer/IocContainerTest.cs index d9d7340..a20e2eb 100644 --- a/Test.LightweightIocContainer/IocContainerTest.cs +++ b/Test.LightweightIocContainer/IocContainerTest.cs @@ -163,6 +163,12 @@ namespace Test.LightweightIocContainer Assert.Throws(() => _iocContainer.RegisterFactory()); } + [Test] + public void TestRegisterUnitTestCallback() + { + Assert.DoesNotThrow(() => _iocContainer.RegisterUnitTestCallback(delegate {return new Test(); })); + } + [Test] public void TestResolveNotRegistered() { @@ -389,6 +395,17 @@ namespace Test.LightweightIocContainer Assert.AreNotSame(resolvedTest3, resolvedTest5); } + [Test] + public void TestResolveUnitTestCallbackRegistration() + { + ITest callbackTest = new Test(); + + _iocContainer.RegisterUnitTestCallback(delegate { return callbackTest; }); + ITest test = _iocContainer.Resolve(); + + Assert.AreEqual(callbackTest, test); + } + [Test] public void TestIsTypeRegistered() { diff --git a/Test.LightweightIocContainer/UnitTestCallbackRegistrationTest.cs b/Test.LightweightIocContainer/UnitTestCallbackRegistrationTest.cs new file mode 100644 index 0000000..0e4a099 --- /dev/null +++ b/Test.LightweightIocContainer/UnitTestCallbackRegistrationTest.cs @@ -0,0 +1,70 @@ +// Author: Gockner, Simon +// Created: 2019-10-15 +// Copyright(c) 2019 SimonG. All Rights Reserved. + +using LightweightIocContainer; +using LightweightIocContainer.Interfaces; +using LightweightIocContainer.Interfaces.Registrations; +using LightweightIocContainer.Registrations; +using Moq; +using NUnit.Framework; + +namespace Test.LightweightIocContainer +{ + [TestFixture] + public class UnitTestCallbackRegistrationTest + { + private interface ITest + { + int Count { get; } + string Name { get; } + bool Testing { get; } + } + + private class Test : ITest + { + public Test() + { + Count = -1; + Name = "Test"; + Testing = false; + } + + public Test(int count, string name, bool testing) + { + Count = count; + Name = name; + Testing = testing; + } + + public int Count { get; } + public string Name { get; } + public bool Testing { get; } + } + + [Test] + public void TestUnitTestResolveCallback() + { + RegistrationFactory registrationFactory = new RegistrationFactory(new Mock().Object); + + ITest test = new Test(); + IUnitTestCallbackRegistration testCallbackRegistration = registrationFactory.RegisterUnitTestCallback(delegate { return test; }); + + Assert.AreEqual(test, testCallbackRegistration.UnitTestResolveCallback.Invoke()); + } + + [Test] + public void TestUnitTestResolveCallbackWithParams() + { + RegistrationFactory registrationFactory = new RegistrationFactory(new Mock().Object); + IUnitTestCallbackRegistration testCallbackRegistration = + registrationFactory.RegisterUnitTestCallback(new ResolveCallback(parameters => new Test((int) parameters[0], (string) parameters[1], (bool) parameters[2]))); + + ITest test = testCallbackRegistration.UnitTestResolveCallback.Invoke(4, "SomeTest", true); + + Assert.AreEqual(4, test.Count); + Assert.AreEqual("SomeTest", test.Name); + Assert.True(test.Testing); + } + } +} \ No newline at end of file