Skip to content

Commit

Permalink
Refactor JsonSerializerOptions resolution
Browse files Browse the repository at this point in the history
- Move resolution to own private class.
- Only resolve the value once.
- Add comments about resolution.
- Make `ISerializerDataContractResolver` a singleton by default.
  • Loading branch information
martincostello committed May 1, 2024
1 parent 023c396 commit 850b3a7
Showing 1 changed file with 44 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,10 @@ public static class SwaggerGenServiceCollectionExtensions
services.TryAddTransient(s => s.GetRequiredService<IOptions<SwaggerGeneratorOptions>>().Value);
services.TryAddTransient<ISchemaGenerator, SchemaGenerator>();
services.TryAddTransient(s => s.GetRequiredService<IOptions<SchemaGeneratorOptions>>().Value);
services.TryAddTransient<ISerializerDataContractResolver>(s =>
services.AddSingleton<JsonSerializerOptionsProvider>();
services.TryAddSingleton<ISerializerDataContractResolver>(s =>
{
#if (!NETSTANDARD2_0)
var serializerOptions =
s.GetService<IOptions<AspNetCore.Mvc.JsonOptions>>()?.Value?.JsonSerializerOptions
#if NET8_0_OR_GREATER
?? s.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions
#endif
#if NET7_0_OR_GREATER
?? JsonSerializerOptions.Default;
#else
?? new JsonSerializerOptions();
#endif
#else
var serializerOptions = new JsonSerializerOptions();
#endif
var serializerOptions = s.GetRequiredService<JsonSerializerOptionsProvider>().Options;
return new JsonSerializerDataContractResolver(serializerOptions);
});

Expand All @@ -63,5 +50,46 @@ public static class SwaggerGenServiceCollectionExtensions
{
services.Configure(setupAction);
}

private sealed class JsonSerializerOptionsProvider
{
private readonly IServiceProvider _serviceProvider;
private JsonSerializerOptions _options;

public JsonSerializerOptionsProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public JsonSerializerOptions Options => _options ??= ResolveOptions();

private JsonSerializerOptions ResolveOptions()
{
JsonSerializerOptions serializerOptions;

/*
* First try to get the options configured for MVC,
* then try to get the options configured for Minimal APIs if available,
* then try the default JsonSerializerOptions if available,
* otherwise create a new instance as a last resort as this is an expensive operation.
*/
#if !NETSTANDARD2_0
serializerOptions =
_serviceProvider.GetService<IOptions<AspNetCore.Mvc.JsonOptions>>()?.Value?.JsonSerializerOptions
#if NET8_0_OR_GREATER
?? _serviceProvider.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions
#endif
#if NET7_0_OR_GREATER
?? JsonSerializerOptions.Default;
#else
?? new JsonSerializerOptions();
#endif
#else
serializerOptions = new JsonSerializerOptions();
#endif

return serializerOptions;
}
}
}
}

0 comments on commit 850b3a7

Please sign in to comment.