Skip to content

Commit 37ffaf8

Browse files
committed
Add bounded per-type enum lookup cache for GetEnumStringValue
Caches attribute resolution per enum Type (not per value), so growth is bounded by the number of distinct enum types in the app. Flags combinations and undefined values fall through to ToString() without polluting the cache.
1 parent 0b5299e commit 37ffaf8

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

src/Foundatio.Repositories.Elasticsearch/Utility/FieldValueHelper.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
24
using System.Reflection;
35
using System.Runtime.Serialization;
46
using System.Text.Json.Serialization;
@@ -8,6 +10,8 @@ namespace Foundatio.Repositories.Elasticsearch.Utility;
810

911
public static class FieldValueHelper
1012
{
13+
private static readonly ConcurrentDictionary<Type, Dictionary<string, string>> _enumTypeLookup = new();
14+
1115
public static FieldValue ToFieldValue(object? value)
1216
{
1317
return value switch
@@ -35,18 +39,27 @@ public static FieldValue ToFieldValue(object? value)
3539

3640
private static string GetEnumStringValue(Enum value)
3741
{
38-
var field = value.GetType().GetField(value.ToString());
39-
if (field is not null)
42+
var lookup = _enumTypeLookup.GetOrAdd(value.GetType(), static type =>
4043
{
41-
var jsonAttr = field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>();
42-
if (jsonAttr is not null)
43-
return jsonAttr.Name;
44+
var map = new Dictionary<string, string>();
45+
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
46+
{
47+
var jsonAttr = field.GetCustomAttribute<JsonStringEnumMemberNameAttribute>();
48+
if (jsonAttr is not null)
49+
{
50+
map[field.Name] = jsonAttr.Name;
51+
continue;
52+
}
53+
54+
var enumMemberAttr = field.GetCustomAttribute<EnumMemberAttribute>();
55+
if (enumMemberAttr?.Value is not null)
56+
map[field.Name] = enumMemberAttr.Value;
57+
}
4458

45-
var enumMemberAttr = field.GetCustomAttribute<EnumMemberAttribute>();
46-
if (enumMemberAttr?.Value is not null)
47-
return enumMemberAttr.Value;
48-
}
59+
return map;
60+
});
4961

50-
return value.ToString();
62+
var name = value.ToString();
63+
return lookup.TryGetValue(name, out var resolved) ? resolved : name;
5164
}
5265
}

0 commit comments

Comments
 (0)