@@ -62,21 +62,27 @@ public static class RequestDelegateFactory
62
62
/// Creates a <see cref="RequestDelegate"/> implementation for <paramref name="action"/>.
63
63
/// </summary>
64
64
/// <param name="action">A request handler with any number of custom parameters that often produces a response with its return value.</param>
65
+ /// <param name="serviceProvider">The <see cref="IServiceProvider"/> instance used to detect which parameters are services.</param>
65
66
/// <returns>The <see cref="RequestDelegate"/>.</returns>
66
- public static RequestDelegate Create ( Delegate action )
67
+ public static RequestDelegate Create ( Delegate action , IServiceProvider serviceProvider )
67
68
{
68
69
if ( action is null )
69
70
{
70
71
throw new ArgumentNullException ( nameof ( action ) ) ;
71
72
}
72
73
74
+ if ( serviceProvider is null )
75
+ {
76
+ throw new ArgumentNullException ( nameof ( serviceProvider ) ) ;
77
+ }
78
+
73
79
var targetExpression = action . Target switch
74
80
{
75
81
object => Expression . Convert ( TargetExpr , action . Target . GetType ( ) ) ,
76
82
null => null ,
77
83
} ;
78
84
79
- var targetableRequestDelegate = CreateTargetableRequestDelegate ( action . Method , targetExpression ) ;
85
+ var targetableRequestDelegate = CreateTargetableRequestDelegate ( action . Method , serviceProvider , targetExpression ) ;
80
86
81
87
return httpContext =>
82
88
{
@@ -88,15 +94,21 @@ public static RequestDelegate Create(Delegate action)
88
94
/// Creates a <see cref="RequestDelegate"/> implementation for <paramref name="methodInfo"/>.
89
95
/// </summary>
90
96
/// <param name="methodInfo">A static request handler with any number of custom parameters that often produces a response with its return value.</param>
97
+ /// <param name="serviceProvider">The <see cref="IServiceProvider"/> instance used to detect which parameters are services.</param>
91
98
/// <returns>The <see cref="RequestDelegate"/>.</returns>
92
- public static RequestDelegate Create ( MethodInfo methodInfo )
99
+ public static RequestDelegate Create ( MethodInfo methodInfo , IServiceProvider serviceProvider )
93
100
{
94
101
if ( methodInfo is null )
95
102
{
96
103
throw new ArgumentNullException ( nameof ( methodInfo ) ) ;
97
104
}
98
105
99
- var targetableRequestDelegate = CreateTargetableRequestDelegate ( methodInfo , targetExpression : null ) ;
106
+ if ( serviceProvider is null )
107
+ {
108
+ throw new ArgumentNullException ( nameof ( serviceProvider ) ) ;
109
+ }
110
+
111
+ var targetableRequestDelegate = CreateTargetableRequestDelegate ( methodInfo , serviceProvider , targetExpression : null ) ;
100
112
101
113
return httpContext =>
102
114
{
@@ -108,15 +120,21 @@ public static RequestDelegate Create(MethodInfo methodInfo)
108
120
/// Creates a <see cref="RequestDelegate"/> implementation for <paramref name="methodInfo"/>.
109
121
/// </summary>
110
122
/// <param name="methodInfo">A request handler with any number of custom parameters that often produces a response with its return value.</param>
123
+ /// <param name="serviceProvider">The <see cref="IServiceProvider"/> instance used to detect which parameters are services.</param>
111
124
/// <param name="targetFactory">Creates the <see langword="this"/> for the non-static method.</param>
112
125
/// <returns>The <see cref="RequestDelegate"/>.</returns>
113
- public static RequestDelegate Create ( MethodInfo methodInfo , Func < HttpContext , object > targetFactory )
126
+ public static RequestDelegate Create ( MethodInfo methodInfo , IServiceProvider serviceProvider , Func < HttpContext , object > targetFactory )
114
127
{
115
128
if ( methodInfo is null )
116
129
{
117
130
throw new ArgumentNullException ( nameof ( methodInfo ) ) ;
118
131
}
119
132
133
+ if ( serviceProvider is null )
134
+ {
135
+ throw new ArgumentNullException ( nameof ( serviceProvider ) ) ;
136
+ }
137
+
120
138
if ( targetFactory is null )
121
139
{
122
140
throw new ArgumentNullException ( nameof ( targetFactory ) ) ;
@@ -128,15 +146,15 @@ public static RequestDelegate Create(MethodInfo methodInfo, Func<HttpContext, ob
128
146
}
129
147
130
148
var targetExpression = Expression . Convert ( TargetExpr , methodInfo . DeclaringType ) ;
131
- var targetableRequestDelegate = CreateTargetableRequestDelegate ( methodInfo , targetExpression ) ;
149
+ var targetableRequestDelegate = CreateTargetableRequestDelegate ( methodInfo , serviceProvider , targetExpression ) ;
132
150
133
151
return httpContext =>
134
152
{
135
153
return targetableRequestDelegate ( targetFactory ( httpContext ) , httpContext ) ;
136
154
} ;
137
155
}
138
156
139
- private static Func < object ? , HttpContext , Task > CreateTargetableRequestDelegate ( MethodInfo methodInfo , Expression ? targetExpression )
157
+ private static Func < object ? , HttpContext , Task > CreateTargetableRequestDelegate ( MethodInfo methodInfo , IServiceProvider serviceProvider , Expression ? targetExpression )
140
158
{
141
159
// Non void return type
142
160
@@ -154,7 +172,10 @@ public static RequestDelegate Create(MethodInfo methodInfo, Func<HttpContext, ob
154
172
// return default;
155
173
// }
156
174
157
- var factoryContext = new FactoryContext ( ) ;
175
+ var factoryContext = new FactoryContext ( )
176
+ {
177
+ ServiceProvider = serviceProvider
178
+ } ;
158
179
159
180
var arguments = CreateArguments ( methodInfo . GetParameters ( ) , factoryContext ) ;
160
181
@@ -234,6 +255,17 @@ private static Expression CreateArgument(ParameterInfo parameter, FactoryContext
234
255
}
235
256
else
236
257
{
258
+ if ( factoryContext . ServiceProvider != null )
259
+ {
260
+ using var scope = factoryContext . ServiceProvider . CreateScope ( ) ;
261
+
262
+ // If the parameter resolves as a service then get it from services
263
+ if ( scope . ServiceProvider . GetService ( parameter . ParameterType ) is not null )
264
+ {
265
+ return Expression . Call ( GetRequiredServiceMethod . MakeGenericMethod ( parameter . ParameterType ) , RequestServicesExpr ) ;
266
+ }
267
+ }
268
+
237
269
return BindParameterFromBody ( parameter . ParameterType , allowEmpty : false , factoryContext ) ;
238
270
}
239
271
}
@@ -788,6 +820,7 @@ private class FactoryContext
788
820
{
789
821
public Type ? JsonRequestBodyType { get ; set ; }
790
822
public bool AllowEmptyRequestBody { get ; set ; }
823
+ public IServiceProvider ? ServiceProvider { get ; set ; }
791
824
792
825
public bool UsingTempSourceString { get ; set ; }
793
826
public List < ( ParameterExpression , Expression ) > TryParseParams { get ; } = new ( ) ;
0 commit comments