elsa-core/src/modules/Elsa.Common/Serialization/ConfigurableSerializer.cs
Marko Lahma 492d6fcd35
Fixing some analyzer warnings (#5617)
* Fixing some analyzer warnings

* review feedback

---------

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2024-07-05 15:14:28 +02:00

124 lines
3.8 KiB
C#

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Text.Unicode;
using Elsa.Common.Contracts;
using Elsa.Common.Converters;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Common.Serialization;
/// <summary>
/// A base class for configurable JSON serializers.
/// </summary>
public abstract class ConfigurableSerializer
{
private JsonSerializerOptions? _options;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurableSerializer"/> class.
/// </summary>
protected ConfigurableSerializer(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
/// <summary>
/// Gets the service provider.
/// </summary>
protected IServiceProvider ServiceProvider { get; }
/// <summary>
/// Creates a new instance of <see cref="JsonSerializerOptions"/> with the configured options.
/// </summary>
public virtual JsonSerializerOptions GetOptions()
{
if (_options != null)
return _options;
var options = CreateOptionsInternal();
ApplyOptions(options);
_options = options;
return options;
}
/// <summary>
/// Creates a new instance of <see cref="JsonSerializerOptions"/> with the configured options.
/// </summary>
public virtual void ApplyOptions(JsonSerializerOptions options)
{
Configure(options);
AddConverters(options);
RunConfigurators(options);
}
/// <summary>
/// Creates a new instance of <see cref="JsonSerializerOptions"/>.
/// </summary>
protected JsonSerializerOptions GetOptionsInternal()
{
var options = CreateOptionsInternal();
ApplyOptions(options);
_options = options;
return options;
}
/// <summary>
/// Creates a new instance of <see cref="JsonSerializerOptions"/>.
/// </summary>
private static JsonSerializerOptions CreateOptionsInternal()
{
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};
options.Converters.Add(new JsonStringEnumConverter());
options.Converters.Add(JsonMetadataServices.TimeSpanConverter);
options.Converters.Add(new IntegerJsonConverter());
options.Converters.Add(new DecimalJsonConverter());
return options;
}
/// <summary>
/// Configures the <see cref="JsonSerializerOptions"/> object.
/// </summary>
protected virtual void Configure(JsonSerializerOptions options)
{
}
/// <summary>
/// Adds additional <see cref="JsonConverter"/> objects.
/// </summary>
protected virtual void AddConverters(JsonSerializerOptions options)
{
}
/// <summary>
/// Give external packages a chance to further configure the serializer options.
/// </summary>
protected virtual void RunConfigurators(JsonSerializerOptions options)
{
var configurators = ServiceProvider.GetServices<ISerializationOptionsConfigurator>();
var modifiers = new List<Action<JsonTypeInfo>>();
foreach (var configurator in configurators)
{
configurator.Configure(options);
var modifiersToAdd = configurator.GetModifiers();
modifiers.AddRange(modifiersToAdd);
}
options.TypeInfoResolver = new ModifiableJsonTypeInfoResolver(modifiers);
}
/// <summary>
/// Creates an instance of the specified type using the service provider.
/// </summary>
protected T CreateInstance<T>() => ActivatorUtilities.CreateInstance<T>(ServiceProvider);
}