Skip to content

Commit b0644fb

Browse files
committed
Unify response writing implementations across RDF and RDG
1 parent 66a2d5e commit b0644fb

File tree

44 files changed

+1068
-194
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1068
-194
lines changed

src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
7878
codeWriter.WriteLine(@"Debug.Assert(options.EndpointBuilder.FilterFactories != null, ""FilterFactories not found."");");
7979
codeWriter.WriteLine($"var handler = ({endpoint.EmitHandlerDelegateType(considerOptionality: true)})del;");
8080
codeWriter.WriteLine("EndpointFilterDelegate? filteredInvocation = null;");
81-
if (endpoint.EmitterContext.RequiresLoggingHelper || endpoint.EmitterContext.HasJsonBodyOrService || endpoint.Response?.IsSerializableJsonResponse(out var _) is true)
82-
{
83-
codeWriter.WriteLine("var serviceProvider = options.ServiceProvider ?? options.EndpointBuilder.ApplicationServices;");
84-
}
81+
codeWriter.WriteLine("var serviceProvider = options.ServiceProvider ?? options.EndpointBuilder.ApplicationServices;");
8582
endpoint.EmitLoggingPreamble(codeWriter);
8683
endpoint.EmitJsonPreparation(codeWriter);
8784
endpoint.EmitRouteOrQueryResolver(codeWriter);
@@ -183,7 +180,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
183180
var hasRouteOrQuery = endpoints.Any(endpoint => endpoint.EmitterContext.HasRouteOrQuery);
184181
var hasBindAsync = endpoints.Any(endpoint => endpoint.EmitterContext.HasBindAsync);
185182
var hasParsable = endpoints.Any(endpoint => endpoint.EmitterContext.HasParsable);
186-
var hasJsonResponse = endpoints.Any(endpoint => endpoint.EmitterContext.HasJsonResponse);
187183
var hasEndpointMetadataProvider = endpoints.Any(endpoint => endpoint.EmitterContext.HasEndpointMetadataProvider);
188184
var hasEndpointParameterMetadataProvider = endpoints.Any(endpoint => endpoint.EmitterContext.HasEndpointParameterMetadataProvider);
189185
var hasIResult = endpoints.Any(endpoint => endpoint.Response?.IsIResult == true);
@@ -196,11 +192,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
196192
codeWriter.WriteLine(RequestDelegateGeneratorSources.ResolveFromRouteOrQueryMethod);
197193
}
198194

199-
if (hasJsonResponse)
200-
{
201-
codeWriter.WriteLine(RequestDelegateGeneratorSources.WriteToResponseAsyncMethod);
202-
}
203-
204195
if (hasJsonBody || hasJsonBodyOrService || hasJsonBodyOrQuery)
205196
{
206197
codeWriter.WriteLine(RequestDelegateGeneratorSources.TryResolveBodyAsyncMethod);

src/Http/Http.Extensions/gen/RequestDelegateGeneratorSources.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -229,22 +229,6 @@ private static Func<HttpContext, StringValues> ResolveFromRouteOrQuery(string pa
229229
}
230230
""";
231231

232-
public static string WriteToResponseAsyncMethod => """
233-
[UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode",
234-
Justification = "The 'JsonSerializer.IsReflectionEnabledByDefault' feature switch, which is set to false by default for trimmed ASP.NET apps, ensures the JsonSerializer doesn't use Reflection.")]
235-
[UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = "See above.")]
236-
private static Task WriteToResponseAsync<T>(T? value, HttpContext httpContext, JsonTypeInfo<T> jsonTypeInfo)
237-
{
238-
var runtimeType = value?.GetType();
239-
if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null)
240-
{
241-
return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo);
242-
}
243-
244-
return httpContext.Response.WriteAsJsonAsync<object?>(value, jsonTypeInfo.Options);
245-
}
246-
""";
247-
248232
public static string ResolveJsonBodyOrServiceMethod => """
249233
private static Func<HttpContext, bool, ValueTask<(bool, T?)>> ResolveJsonBodyOrService<T>(LogOrThrowExceptionHelper logOrThrowExceptionHelper, string parameterTypeName, string parameterName, JsonTypeInfo<T> jsonTypeInfo, IServiceProviderIsService? serviceProviderIsService = null)
250234
{
@@ -577,7 +561,7 @@ private static EndpointFilterDelegate BuildFilterDelegate(EndpointFilterDelegate
577561
[UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode",
578562
Justification = "The 'JsonSerializer.IsReflectionEnabledByDefault' feature switch, which is set to false by default for trimmed ASP.NET apps, ensures the JsonSerializer doesn't use Reflection.")]
579563
[UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = "See above.")]
580-
private static Task ExecuteObjectResult(object? obj, HttpContext httpContext)
564+
private static Task ExecuteReturnAsync(object? obj, HttpContext httpContext, JsonTypeInfo<object?> jsonTypeInfo)
581565
{
582566
if (obj is IResult r)
583567
{
@@ -589,10 +573,24 @@ private static Task ExecuteObjectResult(object? obj, HttpContext httpContext)
589573
}
590574
else
591575
{
592-
return httpContext.Response.WriteAsJsonAsync(obj);
576+
return WriteJsonResponseAsync(obj, httpContext, jsonTypeInfo);
593577
}
594578
}
595579
580+
[UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode",
581+
Justification = "The 'JsonSerializer.IsReflectionEnabledByDefault' feature switch, which is set to false by default for trimmed ASP.NET apps, ensures the JsonSerializer doesn't use Reflection.")]
582+
[UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = "See above.")]
583+
private static Task WriteJsonResponseAsync<T>(T? value, HttpContext httpContext, JsonTypeInfo<T> jsonTypeInfo)
584+
{
585+
var runtimeType = value?.GetType();
586+
if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null)
587+
{
588+
return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo);
589+
}
590+
591+
return httpContext.Response.WriteAsJsonAsync<object?>(value, jsonTypeInfo.Options);
592+
}
593+
596594
{{helperMethods}}
597595
}
598596

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EmitterContext.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ internal sealed class EmitterContext
1111
public bool HasRouteOrQuery { get; set; }
1212
public bool HasBindAsync { get; set; }
1313
public bool HasParsable { get; set; }
14-
public bool HasJsonResponse { get; set; }
1514
public bool RequiresPropertyAsParameterInfo { get; set; }
1615
public bool RequiresLoggingHelper { get; set; }
1716
public bool HasEndpointMetadataProvider { get; set; }

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointJsonPreparationEmitter.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,34 @@ internal static class EndpointJsonPreparationEmitter
77
{
88
internal static void EmitJsonPreparation(this Endpoint endpoint, CodeWriter codeWriter)
99
{
10-
var serializerOptionsEmitted = false;
10+
codeWriter.WriteLine("var serializerOptions = serviceProvider?.GetService<IOptions<JsonOptions>>()?.Value.SerializerOptions ?? new JsonOptions().SerializerOptions;");
11+
codeWriter.WriteLine($"var objectJsonTypeInfo = (JsonTypeInfo<object?>)serializerOptions.GetTypeInfo(typeof(object));");
12+
1113
if (endpoint.Response?.IsSerializableJsonResponse(out var responseType) == true)
1214
{
1315
var typeName = responseType.ToDisplayString(EmitterConstants.DisplayFormat);
14-
codeWriter.WriteLine("var serializerOptions = serviceProvider?.GetService<IOptions<JsonOptions>>()?.Value.SerializerOptions ?? new JsonOptions().SerializerOptions;");
15-
serializerOptionsEmitted = true;
1616
codeWriter.WriteLine($"var responseJsonTypeInfo = (JsonTypeInfo<{typeName}>)serializerOptions.GetTypeInfo(typeof({typeName}));");
1717
}
1818

1919
foreach (var parameter in endpoint.Parameters)
2020
{
21-
ProcessParameter(parameter, codeWriter, ref serializerOptionsEmitted);
21+
ProcessParameter(parameter, codeWriter);
2222
if (parameter is { Source: EndpointParameterSource.AsParameters, EndpointParameters: {} innerParameters })
2323
{
2424
foreach (var innerParameter in innerParameters)
2525
{
26-
ProcessParameter(innerParameter, codeWriter, ref serializerOptionsEmitted);
26+
ProcessParameter(innerParameter, codeWriter);
2727
}
2828
}
2929
}
3030

31-
static void ProcessParameter(EndpointParameter parameter, CodeWriter codeWriter, ref bool serializerOptionsEmitted)
31+
static void ProcessParameter(EndpointParameter parameter, CodeWriter codeWriter)
3232
{
3333
if (parameter.Source != EndpointParameterSource.JsonBody && parameter.Source != EndpointParameterSource.JsonBodyOrService && parameter.Source != EndpointParameterSource.JsonBodyOrQuery)
3434
{
3535
return;
3636
}
3737
var typeName = parameter.Type.ToDisplayString(EmitterConstants.DisplayFormat);
38-
if (!serializerOptionsEmitted)
39-
{
40-
serializerOptionsEmitted = true;
41-
codeWriter.WriteLine("var serializerOptions = serviceProvider?.GetService<IOptions<JsonOptions>>()?.Value.SerializerOptions ?? new JsonOptions().SerializerOptions;");
42-
}
4338
codeWriter.WriteLine($"var {parameter.SymbolName}_JsonTypeInfo = (JsonTypeInfo<{typeName}>)serializerOptions.GetTypeInfo(typeof({parameter.Type.ToDisplayString(EmitterConstants.DisplayFormatWithoutNullability)}));");
4439
}
4540

@@ -52,6 +47,6 @@ internal static string EmitJsonResponse(this EndpointResponse endpointResponse)
5247
{
5348
return "httpContext.Response.WriteAsJsonAsync(result, responseJsonTypeInfo);";
5449
}
55-
return "GeneratedRouteBuilderExtensionsCore.WriteToResponseAsync(result, httpContext, responseJsonTypeInfo);";
50+
return "GeneratedRouteBuilderExtensionsCore.WriteJsonResponseAsync(result, httpContext, responseJsonTypeInfo);";
5651
}
5752
}

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Endpoint.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public Endpoint(IInvocationOperation operation, WellKnownTypes wellKnownTypes, S
3535
return;
3636
}
3737

38-
EmitterContext.HasJsonResponse = Response is not { ResponseType: { IsSealed: true } or { IsValueType: true } };
3938
IsAwaitable = Response?.IsAwaitable == true;
4039

4140
EmitterContext.HasResponseMetadata = Response is { } response && !(response.IsIResult || response.HasNoResponse);

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private static string EmitResponseWritingCall(this EndpointResponse endpointResp
114114
}
115115
else if (endpointResponse.ResponseType?.SpecialType == SpecialType.System_Object)
116116
{
117-
return $"{returnOrAwait} GeneratedRouteBuilderExtensionsCore.ExecuteObjectResult(result, httpContext);";
117+
return $"{returnOrAwait} GeneratedRouteBuilderExtensionsCore.ExecuteReturnAsync(result, httpContext, objectJsonTypeInfo);";
118118
}
119119
else if (!endpointResponse.HasNoResponse)
120120
{
@@ -154,7 +154,10 @@ public static void EmitFilteredRequestHandler(this Endpoint endpoint, CodeWriter
154154
codeWriter.WriteLine("httpContext.Response.StatusCode = 400;");
155155
codeWriter.EndBlock(); // End if-statement block
156156
codeWriter.WriteLine($"var result = await filteredInvocation({invocationCreator}{invocationGenericArgs}(httpContext{argumentList}));");
157-
codeWriter.WriteLine("await GeneratedRouteBuilderExtensionsCore.ExecuteObjectResult(result, httpContext);");
157+
codeWriter.WriteLine("if (result is not null)");
158+
codeWriter.StartBlock();
159+
codeWriter.WriteLine("await GeneratedRouteBuilderExtensionsCore.ExecuteReturnAsync(result, httpContext, objectJsonTypeInfo);");
160+
codeWriter.EndBlock();
158161
codeWriter.EndBlock(); // End handler method block
159162
}
160163

0 commit comments

Comments
 (0)