Skip to content

Commit 6e3516d

Browse files
committed
Fixing resolving of T[][]
1 parent acbb340 commit 6e3516d

File tree

3 files changed

+27
-32
lines changed

3 files changed

+27
-32
lines changed

src/Injection/GenericResolvedArrayParameter.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
22

33
using System;
4+
using System.Linq;
45
using System.Collections.Generic;
56
using System.Globalization;
67
using System.Reflection;
@@ -74,13 +75,8 @@ public override IResolverPolicy GetResolverPolicy(Type typeToBuild)
7475
GuardTypeToBuildHasMatchingGenericParameter(typeToBuild);
7576

7677
Type typeToResolve = typeToBuild.GetNamedGenericParameter(_genericParameterName);
77-
78-
var resolverPolicies = new List<IResolverPolicy>();
79-
foreach (InjectionParameterValue pv in _elementValues)
80-
{
81-
resolverPolicies.Add(pv.GetResolverPolicy(typeToBuild));
82-
}
83-
return new ResolvedArrayWithElementsResolverPolicy(typeToResolve, resolverPolicies.ToArray());
78+
var elementPolicies = _elementValues.Select(pv => pv.GetResolverPolicy(typeToBuild)).ToArray();
79+
return new ResolvedArrayWithElementsResolverPolicy(typeToResolve, elementPolicies);
8480
}
8581

8682
private void GuardTypeToBuildIsGeneric(Type typeToBuild)

src/Injection/ResolvedArrayParameter.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Globalization;
6+
using System.Linq;
67
using Unity.Policy;
78
using Unity.ResolverPolicy;
9+
using Unity.Utility;
810

911
namespace Unity.Injection
1012
{
@@ -26,7 +28,7 @@ public class ResolvedArrayParameter : TypedInjectionValue
2628
/// <param name="elementValues">The values for the elements, that will
2729
/// be converted to <see cref="InjectionParameterValue"/> objects.</param>
2830
public ResolvedArrayParameter(Type elementType, params object[] elementValues)
29-
: this(GetArrayType(elementType), elementType, elementValues)
31+
: this(elementType.MakeArrayType(), elementType, elementValues)
3032
{
3133
}
3234

@@ -66,17 +68,13 @@ protected ResolvedArrayParameter(Type arrayParameterType, Type elementType, para
6668
/// <returns>The <see cref="IResolverPolicy"/>.</returns>
6769
public override IResolverPolicy GetResolverPolicy(Type typeToBuild)
6870
{
69-
List<IResolverPolicy> resolverPolicies = new List<IResolverPolicy>();
70-
foreach (InjectionParameterValue pv in _elementValues)
71-
{
72-
resolverPolicies.Add(pv.GetResolverPolicy(_elementType));
73-
}
74-
return new ResolvedArrayWithElementsResolverPolicy(_elementType, resolverPolicies.ToArray());
75-
}
71+
var elementType = !_elementType.IsArray ? _elementType
72+
: _elementType.GetArrayParameterType(typeToBuild.GenericTypeArguments);
7673

77-
private static Type GetArrayType(Type elementType)
78-
{
79-
return (elementType ?? throw new ArgumentNullException(nameof(elementType))).MakeArrayType();
74+
var elementPolicies = _elementValues.Select(pv => pv.GetResolverPolicy(typeToBuild))
75+
.ToArray();
76+
77+
return new ResolvedArrayWithElementsResolverPolicy(elementType, elementPolicies);
8078
}
8179
}
8280

src/Utility/TypeReflectionExtensions.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,29 +104,31 @@ public static Type GetClosedParameterType(this Type typeToReflect, Type[] generi
104104
return typeToReflect.GetGenericTypeDefinition().MakeGenericType(typeArgs);
105105
}
106106

107-
if (info.IsGenericParameter)
107+
if (typeToReflect.IsArray)
108108
{
109-
return genericArguments[typeToReflect.GenericParameterPosition];
109+
return typeToReflect.GetArrayParameterType(genericArguments);
110110
}
111111

112-
if (typeToReflect.IsArray && typeToReflect.GetElementType().GetTypeInfo().IsGenericParameter)
112+
if (info.IsGenericParameter)
113113
{
114-
int rank;
115-
if ((rank = typeToReflect.GetArrayRank()) == 1)
116-
{
117-
// work around to the fact that Type.MakeArrayType() != Type.MakeArrayType(1)
118-
return genericArguments[typeToReflect.GetElementType().GenericParameterPosition]
119-
.MakeArrayType();
120-
}
121-
122-
return genericArguments[typeToReflect.GetElementType().GenericParameterPosition]
123-
.MakeArrayType(rank);
114+
return genericArguments[typeToReflect.GenericParameterPosition];
124115
}
125116

126117
return typeToReflect;
127118
}
128119

129120

121+
public static Type GetArrayParameterType(this Type typeToReflect, Type[] genericArguments)
122+
{
123+
var rank = typeToReflect.GetArrayRank();
124+
var element = typeToReflect.GetElementType();
125+
var type = element.IsArray ? element.GetArrayParameterType(genericArguments)
126+
: genericArguments[element.GenericParameterPosition];
127+
128+
return 1 == rank ? type.MakeArrayType() : type.MakeArrayType(rank);
129+
}
130+
131+
130132
/// <summary>
131133
/// Given a generic argument name, return the corresponding type for this
132134
/// closed type. For example, if the current type is SomeType&lt;User&gt;, and the
@@ -189,6 +191,5 @@ public static bool Matches(this IEnumerable<InjectionParameterValue> parametersT
189191

190192
return !toMatch.Where((t, i) => !t.MatchesType(candidateTypes[i])).Any();
191193
}
192-
193194
}
194195
}

0 commit comments

Comments
 (0)