-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Added support for type based parameter binding (#35496) #35535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for type based parameter binding (#35496) #35535
Conversation
* Added support for type based parameter binding - Added a convention that allows custom async binding logic to run for parameters that have a static BindAsync method that takes an HttpContext and return a ValueTask of object. This allows customers to write custom binders based solely on type (it's an extension of the existing TryParse pattern). - There's allocation overhead per request once there's a parameter binder for a delegate. This is because we need to box all of the arguments since we're not using generated code to compute data from the list of binders. - Changed TryParse tests to BindAsync tests and added more tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll trust @halter73 to review the changes to the factory.
var isOptional = parameter.HasDefaultValue || nullability.ReadState == NullabilityState.Nullable; | ||
|
||
// Get the BindAsync method | ||
var body = TryParseMethodCache.FindBindAsyncMethod(parameter.ParameterType)!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super small nit, but the name is no longer an accurate reflection of what's being cached. BinderMethodCache
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In .NET 7. This shared source is painful.
@@ -499,6 +499,53 @@ public static bool TryParse(string? value, out MyTryParsableRecord? result) | |||
} | |||
} | |||
|
|||
private class MyBindAsyncTypeThatThrows | |||
{ | |||
public static ValueTask<object?> BindAsync(HttpContext context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the behavior like if the signature does not match? e.g. ValueTask BindAsync(HttpContext context)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't find it sorta like TryParse
today and will fall through to the other things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could fail if it found the method but had the wrong return type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Toss it in the Analyzer pile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just look for ValueTask<{type}>
in FindBindAsyncMethod
? What's the benefit of allowing any object to be returned? I get that we're going to box anyway for structs, but might as well lean on the type-safety checks of the compiler.
We could even throw at startup if a parameter type has a static BindAsync(HttpContext)
method with the wrong return type.
cc @wtgodbe |
Customer Impact
We've had several requests to enable MVC style model binding for minimal APIs, for both framework authors and customers who have written basic model binders for various types. We're enabling typed based modeling binding to unlock these scenarios so we can get feedback for .NET 7.0 for the overall design
Testing
Unit testing, lots of it.
Risk
Low