diff --git a/src/Shared/ActivatorUtilities/ActivatorUtilities.cs b/src/Shared/ActivatorUtilities/ActivatorUtilities.cs index c88914ee28..3fd2b557ff 100644 --- a/src/Shared/ActivatorUtilities/ActivatorUtilities.cs +++ b/src/Shared/ActivatorUtilities/ActivatorUtilities.cs @@ -43,43 +43,45 @@ namespace Microsoft.Extensions.Internal int bestLength = -1; var seenPreferred = false; - ConstructorMatcher bestMatcher = null; + ConstructorMatcher bestMatcher = default; if (!instanceType.GetTypeInfo().IsAbstract) { foreach (var constructor in instanceType .GetTypeInfo() - .DeclaredConstructors - .Where(c => !c.IsStatic && c.IsPublic)) + .DeclaredConstructors) { - var matcher = new ConstructorMatcher(constructor); - var isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false); - var length = matcher.Match(parameters); - - if (isPreferred) + if (!constructor.IsStatic && constructor.IsPublic) { - if (seenPreferred) + var matcher = new ConstructorMatcher(constructor); + var isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false); + var length = matcher.Match(parameters); + + if (isPreferred) { - ThrowMultipleCtorsMarkedWithAttributeException(); + if (seenPreferred) + { + ThrowMultipleCtorsMarkedWithAttributeException(); + } + + if (length == -1) + { + ThrowMarkedCtorDoesNotTakeAllProvidedArguments(); + } } - if (length == -1) + if (isPreferred || bestLength < length) { - ThrowMarkedCtorDoesNotTakeAllProvidedArguments(); + bestLength = length; + bestMatcher = matcher; } - } - if (isPreferred || bestLength < length) - { - bestLength = length; - bestMatcher = matcher; + seenPreferred |= isPreferred; } - - seenPreferred |= isPreferred; } } - if (bestMatcher == null) + if (bestLength == -1) { var message = $"A suitable constructor for type '{instanceType}' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor."; throw new InvalidOperationException(message); @@ -327,18 +329,16 @@ namespace Microsoft.Extensions.Internal return true; } - private class ConstructorMatcher + private struct ConstructorMatcher { private readonly ConstructorInfo _constructor; private readonly ParameterInfo[] _parameters; private readonly object[] _parameterValues; - private readonly bool[] _parameterValuesSet; public ConstructorMatcher(ConstructorInfo constructor) { _constructor = constructor; _parameters = _constructor.GetParameters(); - _parameterValuesSet = new bool[_parameters.Length]; _parameterValues = new object[_parameters.Length]; } @@ -353,11 +353,10 @@ namespace Microsoft.Extensions.Internal for (var applyIndex = applyIndexStart; givenMatched == false && applyIndex != _parameters.Length; ++applyIndex) { - if (_parameterValuesSet[applyIndex] == false && + if (_parameterValues[applyIndex] == null && _parameters[applyIndex].ParameterType.GetTypeInfo().IsAssignableFrom(givenType)) { givenMatched = true; - _parameterValuesSet[applyIndex] = true; _parameterValues[applyIndex] = givenParameters[givenIndex]; if (applyIndexStart == applyIndex) { @@ -382,7 +381,7 @@ namespace Microsoft.Extensions.Internal { for (var index = 0; index != _parameters.Length; index++) { - if (_parameterValuesSet[index] == false) + if (_parameterValues[index] == null) { var value = provider.GetService(_parameters[index].ParameterType); if (value == null)