Removed enum reflection method in favor of factory approach (#507)

Co-authored-by: Alex <clodanSPT@hotmail.com>
This commit is contained in:
Chomp
2025-07-23 10:51:23 +01:00
committed by GitHub
4 changed files with 104 additions and 33 deletions
@@ -4,6 +4,27 @@ using System.Text.Json.Serialization;
namespace SPTarkov.Server.Core.Utils.Json.Converters;
public class EftEnumConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsEnum && (typeToConvert.Namespace?.Contains("SPTarkov") ?? false);
}
public override JsonConverter? CreateConverter(
Type typeToConvert,
JsonSerializerOptions options
)
{
return (JsonConverter)
Activator.CreateInstance(
typeof(EftEnumConverter<>).MakeGenericType(typeToConvert)
);
}
}
public class EftEnumConverter<T> : JsonConverter<T>
{
private static readonly JsonSerializerOptions _options = new()
@@ -3,6 +3,27 @@ using System.Text.Json.Serialization;
namespace SPTarkov.Server.Core.Utils.Json.Converters;
public class EftListEnumConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(List<>) &&
typeToConvert.GenericTypeArguments[0].IsEnum &&
(typeToConvert.GenericTypeArguments[0].Namespace?.Contains("SPTarkov") ?? false);
}
public override JsonConverter? CreateConverter(
Type typeToConvert,
JsonSerializerOptions options
)
{
return (JsonConverter)
Activator.CreateInstance(
typeof(EftListEnumConverter<>).MakeGenericType(typeToConvert.GenericTypeArguments[0])
);
}
}
public class EftListEnumConverter<T> : JsonConverter<List<T>>
{
private static readonly JsonSerializerOptions _options = new()
@@ -0,0 +1,59 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace SPTarkov.Server.Core.Utils.Json.Converters;
public class EnumerableConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType
&& typeToConvert.GetGenericTypeDefinition() == typeof(IEnumerable<>);
}
public override JsonConverter? CreateConverter(
Type typeToConvert,
JsonSerializerOptions options
)
{
return (JsonConverter)
Activator.CreateInstance(
typeof(EnumerableConverter<>).MakeGenericType(typeToConvert.GenericTypeArguments[0])
);
}
}
public class EnumerableConverter<T> : JsonConverter<IEnumerable<T>?>
{
public override IEnumerable<T>? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options
)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
case JsonTokenType.Number:
case JsonTokenType.StartObject:
throw new Exception($"Error attempting to deserialize object, its not a valid array. Type {reader.TokenType}");
case JsonTokenType.StartArray:
var list = JsonSerializer.Deserialize<List<T>>(ref reader, options);
return list;
default:
throw new Exception(
$"Unable to translate object type {reader.TokenType} to ListOrT<T>."
);
}
}
public override void Write(
Utf8JsonWriter writer,
IEnumerable<T>? value,
JsonSerializerOptions options
)
{
JsonSerializer.Serialize(writer, value?.ToList(), options);
}
}
@@ -18,39 +18,9 @@ public class SptJsonConverterRegistrator : IJsonConverterRegistrator
new EftEnumConverter<LogLevel>(), // Special case, this belongs to a lib.
new BaseInteractionRequestDataConverter(),
new StringToMongoIdConverter(),
.. GetGenericJsonConverters(),
new EftEnumConverterFactory(),
new EftListEnumConverterFactory(),
new EnumerableConverterFactory()
];
}
private static List<JsonConverter> GetGenericJsonConverters()
{
var enums = AppDomain
.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type =>
type.IsEnum && type.GetCustomAttribute<EftEnumConverterAttribute>() != null
);
var listEnums = AppDomain
.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type =>
type.IsEnum && type.GetCustomAttribute<EftListEnumConverterAttribute>() != null
);
var result = enums
.Select(e =>
(JsonConverter)
Activator.CreateInstance(typeof(EftEnumConverter<>).MakeGenericType(e))!
)
.ToList();
result.AddRange(
listEnums.Select(e =>
(JsonConverter)
Activator.CreateInstance(typeof(EftListEnumConverter<>).MakeGenericType(e))!
)
);
return result;
}
}