Skip to content

Commit 77bc86e

Browse files
committed
Refactoring
1 parent 0d809bd commit 77bc86e

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

src/Shared/ParameterBindingMethodCache.cs

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -179,41 +179,19 @@ static bool ValidateReturnType(MethodInfo methodInfo)
179179
{
180180
(Func<ParameterInfo, Expression>?, int) Finder(Type nonNullableParameterType)
181181
{
182-
// Check if parameter is bindable via static abstract method on IBindableFromHttpContext<TSelf>
183-
184-
var isBindableViaInterface = true;
185-
try
186-
{
187-
var bindableType = typeof(IBindableFromHttpContext<>).MakeGenericType(nonNullableParameterType);
188-
}
189-
catch (ArgumentException)
190-
{
191-
isBindableViaInterface = false;
192-
}
193-
194-
if (isBindableViaInterface)
195-
{
196-
var staticMethodInfo = nonNullableParameterType.GetMethod("BindAsync", BindingFlags.Public | BindingFlags.Static)!;
197-
return ((parameter) =>
198-
{
199-
// parameter is being intentionally shadowed. We never want to use the outer ParameterInfo inside
200-
// this Func because the ParameterInfo varies after it's been cached for a given parameter type.
201-
MethodCallExpression typedCall = Expression.Call(staticMethodInfo, HttpContextExpr, Expression.Constant(parameter));
202-
return Expression.Call(GetGenericConvertValueTask(nonNullableParameterType), typedCall);
203-
}, 2);
204-
205-
[UnconditionalSuppressMessage("Trimmer", "IL2060", Justification = "Linker workaround. The type is annotated with RequiresUnreferencedCode")]
206-
static MethodInfo GetGenericConvertValueTask(Type nonNullableParameterType) => ConvertValueTaskMethod.MakeGenericMethod(nonNullableParameterType);
207-
}
208-
209182
var hasParameterInfo = true;
183+
var methodInfo = GetIBindableFromHttpContextMethod(nonNullableParameterType);
210184

211-
// There should only be one BindAsync method with these parameters since C# does not allow overloading on return type.
212-
var methodInfo = GetStaticMethodFromHierarchy(nonNullableParameterType, "BindAsync", new[] { typeof(HttpContext), typeof(ParameterInfo) }, ValidateReturnType);
213185
if (methodInfo is null)
214186
{
215-
hasParameterInfo = false;
216-
methodInfo = GetStaticMethodFromHierarchy(nonNullableParameterType, "BindAsync", new[] { typeof(HttpContext) }, ValidateReturnType);
187+
// There should only be one BindAsync method with these parameters since C# does not allow overloading on return type.
188+
methodInfo = GetStaticMethodFromHierarchy(nonNullableParameterType, "BindAsync", new[] { typeof(HttpContext), typeof(ParameterInfo) }, ValidateReturnType);
189+
190+
if (methodInfo is null)
191+
{
192+
hasParameterInfo = false;
193+
methodInfo = GetStaticMethodFromHierarchy(nonNullableParameterType, "BindAsync", new[] { typeof(HttpContext) }, ValidateReturnType);
194+
}
217195
}
218196

219197
// We're looking for a method with the following signatures:
@@ -300,6 +278,29 @@ static bool ValidateReturnType(MethodInfo methodInfo)
300278
}
301279
}
302280

281+
private static MethodInfo? GetIBindableFromHttpContextMethod(Type type)
282+
{
283+
// Check if parameter is bindable via static abstract method on IBindableFromHttpContext<TSelf>
284+
// JonSkeet himself said this is the way (https://stackoverflow.com/a/4864565/405892)
285+
// but if we find another less exceptiony way we should probably do that instead
286+
var isBindableViaInterface = true;
287+
try
288+
{
289+
var _ = typeof(IBindableFromHttpContext<>).MakeGenericType(type);
290+
}
291+
catch (ArgumentException)
292+
{
293+
isBindableViaInterface = false;
294+
}
295+
296+
if (isBindableViaInterface)
297+
{
298+
return type.GetMethod("BindAsync", BindingFlags.Public | BindingFlags.Static)!;
299+
}
300+
301+
return null;
302+
}
303+
303304
private MethodInfo? GetStaticMethodFromHierarchy(Type type, string name, Type[] parameterTypes, Func<MethodInfo, bool> validateReturnType)
304305
{
305306
bool IsMatch(MethodInfo? method) => method is not null && !method.IsAbstract && validateReturnType(method);

0 commit comments

Comments
 (0)