Skip to content

Commit 6ee9f1a

Browse files
committed
patch: async handlers resolution
1 parent 76820e6 commit 6ee9f1a

2 files changed

Lines changed: 26 additions & 27 deletions

File tree

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
namespace FSharp.MinimalApi;
1+
using System.Reflection;
2+
3+
namespace FSharp.MinimalApi;
24

35
using Microsoft.FSharp.Core;
46
using Microsoft.AspNetCore.Http;
57

68
public static class AsParameters
79
{
810
public static Delegate Of<TParam, TResult>(FSharpFunc<TParam, TResult> requestDelegate) =>
9-
typeof(TParam) == typeof(Unit)
10-
? typeof(TResult) == typeof(Unit)
11-
? void () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
12-
: () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
13-
: typeof(TResult) == typeof(Unit)
14-
? void ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
15-
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);
11+
typeof(TResult).IsGenericType &&
12+
typeof(TResult).GetGenericTypeDefinition() == typeof(Task<>)
13+
? CreateAsTask(requestDelegate)
14+
: typeof(TParam) == typeof(Unit)
15+
? typeof(TResult) == typeof(Unit)
16+
? void () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
17+
: () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
18+
: typeof(TResult) == typeof(Unit)
19+
? void ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
20+
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);
1621

1722
public static Delegate OfTask<TParam, TResult>(
1823
FSharpFunc<TParam, Task<TResult>> requestDelegate) =>
@@ -25,4 +30,15 @@ public static Delegate OfTask<TParam, TResult>(
2530
: typeof(TResult) == typeof(Unit)
2631
? Task ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
2732
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);
33+
34+
static Delegate CreateAsTask<TParam, TResult>(FSharpFunc<TParam, TResult> requestDelegate)
35+
{
36+
var underType = typeof(TResult).GetGenericArguments()[0];
37+
var method =
38+
typeof(AsParameters).GetMethod(nameof(OfTask),
39+
BindingFlags.Public | BindingFlags.Static)!
40+
.MakeGenericMethod(typeof(TParam), underType);
41+
42+
return (Delegate) method.Invoke(null, new object?[] {requestDelegate})!;
43+
}
2844
}

FSharp.MinimalApi/Builder/EndpointHandlerBuilder.fs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,11 @@ type RouterBaseBuilder<'state>() =
6161
//****************************************************************************************************
6262
// MapGet
6363
[<CustomOperation(HttpMethodName.Get)>]
64-
member this.MapGet(s, route, f: Delegate, ?config) = this.get s route f config
65-
66-
[<CustomOperation(HttpMethodName.Get)>]
67-
member this.MapGet(s, route, f: 'p -> 'r, ?config) =
64+
member inline this.MapGet(s, route, f: 'p -> 'r, ?config) =
6865
this.get s route (AsParameters.Of f) config
6966

7067
[<CustomOperation(HttpMethodName.Get)>]
71-
member this.MapGet(s, route, f: 'p -> Task<'r>, ?config) =
72-
this.get s route (AsParameters.OfTask f) config
68+
member this.MapGet(s, route, f: Delegate, ?config) = this.get s route f config
7369

7470
// MapPost
7571
[<CustomOperation(HttpMethodName.Post)>]
@@ -79,10 +75,6 @@ type RouterBaseBuilder<'state>() =
7975
member this.MapPost(s, route, f: 'p -> 'r, ?config) =
8076
this.post s route (AsParameters.Of f) config
8177

82-
[<CustomOperation(HttpMethodName.Post)>]
83-
member this.MapPost(s, route, f: 'p -> Task<'r>, ?config) =
84-
this.post s route (AsParameters.OfTask f) config
85-
8678
// MapPut
8779
[<CustomOperation(HttpMethodName.Put)>]
8880
member this.MapPut(s, route, f: Delegate, ?config) = this.put s route f config
@@ -91,10 +83,6 @@ type RouterBaseBuilder<'state>() =
9183
member this.MapPut(s, route, f: 'p -> 'r, ?config) =
9284
this.put s route (AsParameters.Of f) config
9385

94-
[<CustomOperation(HttpMethodName.Put)>]
95-
member this.MapPut(s, route, f: 'p -> Task<'r>, ?config) =
96-
this.put s route (AsParameters.OfTask f) config
97-
9886
// MapDelete
9987
[<CustomOperation(HttpMethodName.Delete)>]
10088
member this.MapDelete(s, route, f: Delegate, ?config) = this.delete s route f config
@@ -103,11 +91,6 @@ type RouterBaseBuilder<'state>() =
10391
member this.MapDelete(s, route, f: 'p -> 'r, ?config) =
10492
this.delete s route (AsParameters.Of f) config
10593

106-
[<CustomOperation(HttpMethodName.Delete)>]
107-
member this.MapDelete(s, route, f: 'p -> Task<'r>, ?config) =
108-
this.delete s route (AsParameters.OfTask f) config
109-
110-
11194
//****************************************************************************************************
11295
// TypedResult Maps
11396
//****************************************************************************************************

0 commit comments

Comments
 (0)