From eb04d55d2b7b1cfd68d2a205033d3951454652cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Knippers?= Date: Mon, 16 Mar 2020 20:00:39 +0100 Subject: [PATCH 1/3] Makes sure supplied arguments cannot be used more than once. --- src/Umbraco.Core/FactoryExtensions.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/FactoryExtensions.cs b/src/Umbraco.Core/FactoryExtensions.cs index 8514525417..8ae2f76af3 100644 --- a/src/Umbraco.Core/FactoryExtensions.cs +++ b/src/Umbraco.Core/FactoryExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using Umbraco.Core.Composing; @@ -77,15 +78,28 @@ namespace Umbraco.Core var ctorParameters = ctor.GetParameters(); var ctorArgs = new object[ctorParameters.Length]; + var availableArgs = new List(args); var i = 0; foreach (var parameter in ctorParameters) { // no! IsInstanceOfType is not ok here // ReSharper disable once UseMethodIsInstanceOfType - var arg = args?.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType())); - ctorArgs[i++] = arg ?? factory.GetInstance(parameter.ParameterType); + var idx = availableArgs.FindIndex(a => parameter.ParameterType.IsAssignableFrom(a.GetType())); + if(idx >= 0) + { + // Found a suitable supplied argument + ctorArgs[i++] = availableArgs[idx]; + + // A supplied argument can be used at most once + availableArgs.RemoveAt(idx); + } + else + { + // None of the provided arguments is suitable: get an instance from the factory + ctorArgs[i++] = factory.GetInstance(parameter.ParameterType); + } } return ctor.Invoke(ctorArgs); } } -} \ No newline at end of file +} From 5215a769feb593d4675d832e112618a581912cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Knippers?= Date: Mon, 25 May 2020 21:30:56 +0200 Subject: [PATCH 2/3] Added unit test that fails before PR and succeeds after PR --- .../Composing/ContainerConformingTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs index f5c1ff9bc7..06ab246d84 100644 --- a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs +++ b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs @@ -330,6 +330,17 @@ namespace Umbraco.Tests.Composing var s1 = factory.GetInstance(); var s2 = factory.GetInstance(); Assert.AreSame(s1, s2); + + register.Register(factory => + { + var param1 = new Thing1(); + var param2 = new Thing1(); + + return factory.CreateInstance(param1, param2); + }); + + var instance = factory.GetInstance(); + Assert.AreNotEqual(instance.Thing, instance.AnotherThing); } public interface IThing { } @@ -352,5 +363,17 @@ namespace Umbraco.Tests.Composing public IEnumerable Things { get; } } + + public class Thing4 : ThingBase + { + public readonly Thing1 Thing; + public readonly Thing1 AnotherThing; + + public Thing4(Thing1 thing, Thing1 anotherThing) + { + Thing = thing; + AnotherThing = anotherThing; + } + } } } From 558ffaeba70e922240a124a47faa1718a8f3e0be Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 26 May 2020 09:18:09 +0200 Subject: [PATCH 3/3] Move test and use params that are easier to distinguish --- .../Composing/ContainerConformingTests.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs index 06ab246d84..22978bdb43 100644 --- a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs +++ b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs @@ -330,15 +330,20 @@ namespace Umbraco.Tests.Composing var s1 = factory.GetInstance(); var s2 = factory.GetInstance(); Assert.AreSame(s1, s2); + } - register.Register(factory => + [Test] + public void CanRegisterMultipleSameTypeParametersWithCreateInstance() + { + var register = GetRegister(); + var factory = register.CreateFactory(); + register.Register(factory => { - var param1 = new Thing1(); - var param2 = new Thing1(); + var param1 = "param1"; + var param2 = "param2"; return factory.CreateInstance(param1, param2); }); - var instance = factory.GetInstance(); Assert.AreNotEqual(instance.Thing, instance.AnotherThing); } @@ -366,10 +371,10 @@ namespace Umbraco.Tests.Composing public class Thing4 : ThingBase { - public readonly Thing1 Thing; - public readonly Thing1 AnotherThing; + public readonly string Thing; + public readonly string AnotherThing; - public Thing4(Thing1 thing, Thing1 anotherThing) + public Thing4(string thing, string anotherThing) { Thing = thing; AnotherThing = anotherThing;